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