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}