sea_query/foreign_key/
create.rs

1use inherent::inherent;
2
3use crate::{
4    backend::SchemaBuilder, types::*, ForeignKeyAction, SchemaStatementBuilder, TableForeignKey,
5};
6
7/// Create a foreign key constraint for an existing table. Unsupported by Sqlite
8///
9/// # Examples
10///
11/// ```
12/// use sea_query::{tests_cfg::*, *};
13///
14/// let foreign_key = ForeignKey::create()
15///     .name("FK_character_font")
16///     .from(Char::Table, Char::FontId)
17///     .to(Font::Table, Font::Id)
18///     .on_delete(ForeignKeyAction::Cascade)
19///     .on_update(ForeignKeyAction::Cascade)
20///     .to_owned();
21///
22/// assert_eq!(
23///     foreign_key.to_string(MysqlQueryBuilder),
24///     [
25///         r#"ALTER TABLE `character`"#,
26///         r#"ADD CONSTRAINT `FK_character_font`"#,
27///         r#"FOREIGN KEY (`font_id`) REFERENCES `font` (`id`)"#,
28///         r#"ON DELETE CASCADE ON UPDATE CASCADE"#,
29///     ]
30///     .join(" ")
31/// );
32/// assert_eq!(
33///     foreign_key.to_string(PostgresQueryBuilder),
34///     [
35///         r#"ALTER TABLE "character" ADD CONSTRAINT "FK_character_font""#,
36///         r#"FOREIGN KEY ("font_id") REFERENCES "font" ("id")"#,
37///         r#"ON DELETE CASCADE ON UPDATE CASCADE"#,
38///     ]
39///     .join(" ")
40/// );
41/// ```
42///
43/// Composite key
44/// ```
45/// use sea_query::{tests_cfg::*, *};
46///
47/// let foreign_key = ForeignKey::create()
48///     .name("FK_character_glyph")
49///     .from(Char::Table, (Char::FontId, Char::Id))
50///     .to(Glyph::Table, (Char::FontId, Glyph::Id))
51///     .on_delete(ForeignKeyAction::Cascade)
52///     .on_update(ForeignKeyAction::Cascade)
53///     .to_owned();
54///
55/// assert_eq!(
56///     foreign_key.to_string(MysqlQueryBuilder),
57///     [
58///         r#"ALTER TABLE `character`"#,
59///         r#"ADD CONSTRAINT `FK_character_glyph`"#,
60///         r#"FOREIGN KEY (`font_id`, `id`) REFERENCES `glyph` (`font_id`, `id`)"#,
61///         r#"ON DELETE CASCADE ON UPDATE CASCADE"#,
62///     ]
63///     .join(" ")
64/// );
65/// assert_eq!(
66///     foreign_key.to_string(PostgresQueryBuilder),
67///     [
68///         r#"ALTER TABLE "character" ADD CONSTRAINT "FK_character_glyph""#,
69///         r#"FOREIGN KEY ("font_id", "id") REFERENCES "glyph" ("font_id", "id")"#,
70///         r#"ON DELETE CASCADE ON UPDATE CASCADE"#,
71///     ]
72///     .join(" ")
73/// );
74/// ```
75#[derive(Default, Debug, Clone)]
76pub struct ForeignKeyCreateStatement {
77    pub(crate) foreign_key: TableForeignKey,
78}
79
80impl ForeignKeyCreateStatement {
81    /// Construct a new [`ForeignKeyCreateStatement`]
82    pub fn new() -> Self {
83        Self::default()
84    }
85
86    /// Set foreign key name
87    pub fn name<T>(&mut self, name: T) -> &mut Self
88    where
89        T: Into<String>,
90    {
91        self.foreign_key.name(name);
92        self
93    }
94
95    /// Set key table and columns
96    pub fn from<T, C>(&mut self, table: T, columns: C) -> &mut Self
97    where
98        T: IntoTableRef,
99        C: IdenList,
100    {
101        self.foreign_key.from_tbl(table);
102        for col in columns.into_iter() {
103            self.foreign_key.from_col(col);
104        }
105        self
106    }
107
108    /// Set referencing table and columns
109    pub fn to<T, C>(&mut self, table: T, columns: C) -> &mut Self
110    where
111        T: IntoTableRef,
112        C: IdenList,
113    {
114        self.foreign_key.to_tbl(table);
115        for col in columns.into_iter() {
116            self.foreign_key.to_col(col);
117        }
118        self
119    }
120
121    /// Set key table
122    pub fn from_tbl<T>(&mut self, table: T) -> &mut Self
123    where
124        T: IntoTableRef,
125    {
126        self.foreign_key.from_tbl(table);
127        self
128    }
129
130    /// Set referencing table
131    pub fn to_tbl<R>(&mut self, ref_table: R) -> &mut Self
132    where
133        R: IntoTableRef,
134    {
135        self.foreign_key.to_tbl(ref_table);
136        self
137    }
138
139    /// Add key column
140    pub fn from_col<T>(&mut self, column: T) -> &mut Self
141    where
142        T: IntoIden,
143    {
144        self.foreign_key.from_col(column);
145        self
146    }
147
148    /// Add referencing column
149    pub fn to_col<R>(&mut self, ref_column: R) -> &mut Self
150    where
151        R: IntoIden,
152    {
153        self.foreign_key.to_col(ref_column);
154        self
155    }
156
157    /// Set on delete action
158    pub fn on_delete(&mut self, action: ForeignKeyAction) -> &mut Self {
159        self.foreign_key.on_delete(action);
160        self
161    }
162
163    /// Set on update action
164    pub fn on_update(&mut self, action: ForeignKeyAction) -> &mut Self {
165        self.foreign_key.on_update(action);
166        self
167    }
168
169    pub fn get_foreign_key(&self) -> &TableForeignKey {
170        &self.foreign_key
171    }
172
173    pub fn take(&mut self) -> Self {
174        Self {
175            foreign_key: self.foreign_key.take(),
176        }
177    }
178}
179
180#[inherent]
181impl SchemaStatementBuilder for ForeignKeyCreateStatement {
182    pub fn build<T: SchemaBuilder>(&self, schema_builder: T) -> String {
183        let mut sql = String::with_capacity(256);
184        schema_builder.prepare_foreign_key_create_statement(self, &mut sql);
185        sql
186    }
187
188    pub fn build_any(&self, schema_builder: &dyn SchemaBuilder) -> String {
189        let mut sql = String::with_capacity(256);
190        schema_builder.prepare_foreign_key_create_statement(self, &mut sql);
191        sql
192    }
193
194    pub fn to_string<T: SchemaBuilder>(&self, schema_builder: T) -> String;
195}