1use crate::*;
2
3pub trait TableBuilder:
4 IndexBuilder + ForeignKeyBuilder + QuotedBuilder + TableRefBuilder + QueryBuilder
5{
6 fn prepare_table_create_statement(
8 &self,
9 create: &TableCreateStatement,
10 sql: &mut impl SqlWriter,
11 ) {
12 sql.write_str("CREATE ").unwrap();
13
14 self.prepare_create_temporary_table(create, sql);
15
16 sql.write_str("TABLE ").unwrap();
17
18 self.prepare_create_table_if_not_exists(create, sql);
19
20 if let Some(table_ref) = &create.table {
21 self.prepare_table_ref_table_stmt(table_ref, sql);
22 }
23
24 if let Some(partition_of) = &create.partition_of {
25 sql.write_str(" PARTITION OF ").unwrap();
26 self.prepare_table_ref_table_stmt(partition_of, sql);
27 }
28
29 if !create.columns.is_empty()
30 || !create.indexes.is_empty()
31 || !create.foreign_keys.is_empty()
32 || !create.check.is_empty()
33 {
34 sql.write_str(" ( ").unwrap();
35 let mut first = true;
36
37 create.columns.iter().for_each(|column_def| {
38 if !first {
39 sql.write_str(", ").unwrap();
40 }
41 self.prepare_column_def(column_def, sql);
42 first = false;
43 });
44
45 create.indexes.iter().for_each(|index| {
46 if !first {
47 sql.write_str(", ").unwrap();
48 }
49 self.prepare_table_index_expression(index, sql);
50 first = false;
51 });
52
53 create.foreign_keys.iter().for_each(|foreign_key| {
54 if !first {
55 sql.write_str(", ").unwrap();
56 }
57 self.prepare_foreign_key_create_statement_internal(
58 foreign_key,
59 sql,
60 Mode::Creation,
61 );
62 first = false;
63 });
64
65 create.check.iter().for_each(|check| {
66 if !first {
67 sql.write_str(", ").unwrap();
68 }
69 self.prepare_check_constraint(check, sql);
70 first = false;
71 });
72
73 sql.write_str(" )").unwrap();
74 }
75
76 if let Some(partition_values) = &create.partition_values {
77 sql.write_str(" ").unwrap();
78 self.prepare_partition_values(partition_values, sql);
79 }
80
81 if let Some(partition_by) = &create.partition_by {
82 sql.write_str(" PARTITION BY ").unwrap();
83 self.prepare_partition_by(partition_by, sql);
84 }
85
86 if !create.partitions.is_empty() {
87 sql.write_str(" ( ").unwrap();
88 let mut first = true;
89 for partition in create.partitions.iter() {
90 if !first {
91 sql.write_str(", ").unwrap();
92 }
93 self.prepare_partition_definition(&partition.name, partition.values.as_ref(), sql);
94 first = false;
95 }
96 sql.write_str(" )").unwrap();
97 }
98
99 self.prepare_table_opt(create, sql);
100
101 if let Some(extra) = &create.extra {
102 sql.write_str(" ").unwrap();
103 sql.write_str(extra).unwrap();
104 }
105 }
106
107 fn prepare_table_ref_table_stmt(&self, table_ref: &TableRef, sql: &mut impl SqlWriter) {
109 match table_ref {
110 TableRef::Table(.., None) => self.prepare_table_ref_iden(table_ref, sql),
112 _ => panic!("Not supported"),
113 }
114 }
115
116 fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut impl SqlWriter);
118
119 fn prepare_column_def_internal(
121 &self,
122 _is_alter_column: bool,
123 column_def: &ColumnDef,
124 sql: &mut impl SqlWriter,
125 ) {
126 self.prepare_column_def(column_def, sql);
127 }
128
129 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut impl SqlWriter);
131
132 fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut impl SqlWriter) {
134 let ColumnSpec {
135 nullable,
136 default,
137 auto_increment,
138 unique,
139 primary_key,
140 check,
141 generated,
142 extra,
143 comment,
144 using: _,
145 } = column_spec;
146
147 if let Some(nullable) = nullable {
148 sql.write_str(if *nullable { " NULL" } else { " NOT NULL" })
149 .unwrap();
150 }
151
152 if let Some(default) = default {
153 sql.write_str(" DEFAULT ").unwrap();
154 match default {
163 Expr::Value(_) | Expr::Constant(_) | Expr::Keyword(_) => {
164 self.prepare_expr(default, sql)
165 }
166 _ => {
167 sql.write_str("(").unwrap();
168 self.prepare_expr(default, sql);
169 sql.write_str(")").unwrap()
170 }
171 }
172 }
173
174 if let Some(generated) = generated {
175 self.prepare_generated_column(&generated.expr, generated.stored, sql);
176 }
177
178 if *primary_key {
179 sql.write_str(" PRIMARY KEY").unwrap();
180 }
181
182 if *auto_increment {
183 sql.write_str(self.column_spec_auto_increment_keyword())
184 .unwrap();
185 }
186
187 if *unique {
188 sql.write_str(" UNIQUE").unwrap();
189 }
190
191 if let Some(check) = check {
192 sql.write_str(" ").unwrap();
193 self.prepare_check_constraint(check, sql);
194 }
195
196 if let Some(extra) = extra {
197 sql.write_str(" ").unwrap();
198 sql.write_str(extra).unwrap();
199 }
200
201 if let Some(comment) = comment {
202 self.column_comment(comment, sql);
203 }
204 }
205
206 fn column_comment(&self, _comment: &str, _sql: &mut impl SqlWriter) {}
208
209 fn column_spec_auto_increment_keyword(&self) -> &str;
211
212 fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut impl SqlWriter) {
214 self.prepare_table_opt_def(create, sql)
215 }
216
217 fn prepare_table_opt_def(&self, create: &TableCreateStatement, sql: &mut impl SqlWriter) {
219 for table_opt in create.options.iter() {
220 sql.write_str(" ").unwrap();
221 match table_opt {
222 TableOpt::Engine(s) => {
223 sql.write_str("ENGINE=").unwrap();
224 sql.write_str(s).unwrap();
225 }
226 TableOpt::Collate(s) => {
227 sql.write_str("COLLATE=").unwrap();
228 sql.write_str(s).unwrap();
229 }
230 TableOpt::CharacterSet(s) => {
231 sql.write_str("DEFAULT CHARSET=").unwrap();
232 sql.write_str(s).unwrap();
233 }
234 }
235 }
236 }
237
238 fn prepare_partition_by(&self, _partition_by: &PartitionBy, _sql: &mut impl SqlWriter) {}
240
241 fn prepare_partition_values(
243 &self,
244 _partition_values: &PartitionValues,
245 _sql: &mut impl SqlWriter,
246 ) {
247 }
248
249 fn prepare_partition_definition(
251 &self,
252 _name: &DynIden,
253 _values: Option<&PartitionValues>,
254 _sql: &mut impl SqlWriter,
255 ) {
256 }
257
258 fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut impl SqlWriter) {
260 sql.write_str("DROP TABLE ").unwrap();
261
262 if drop.if_exists {
263 sql.write_str("IF EXISTS ").unwrap();
264 }
265
266 let mut tables = drop.tables.iter();
267 join_io!(
268 tables,
269 table,
270 join {
271 sql.write_str(", ").unwrap();
272 },
273 do {
274 self.prepare_table_ref_table_stmt(table, sql);
275 }
276 );
277
278 for drop_opt in drop.options.iter() {
279 self.prepare_table_drop_opt(drop_opt, sql);
280 }
281 }
282
283 fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut impl SqlWriter) {
285 match drop_opt {
286 TableDropOpt::Restrict => sql.write_str(" RESTRICT").unwrap(),
287 TableDropOpt::Cascade => sql.write_str(" CASCADE").unwrap(),
288 }
289 }
290
291 fn prepare_table_truncate_statement(
293 &self,
294 truncate: &TableTruncateStatement,
295 sql: &mut impl SqlWriter,
296 ) {
297 sql.write_str("TRUNCATE TABLE ").unwrap();
298
299 if let Some(table) = &truncate.table {
300 self.prepare_table_ref_table_stmt(table, sql);
301 }
302 }
303
304 fn prepare_check_constraint(&self, check: &Check, sql: &mut impl SqlWriter) {
306 if let Some(name) = &check.name {
307 sql.write_str("CONSTRAINT ").unwrap();
308 self.prepare_iden(name, sql);
309 sql.write_str(" ").unwrap();
310 }
311
312 sql.write_str("CHECK (").unwrap();
313 QueryBuilder::prepare_expr(self, &check.expr, sql);
314 sql.write_str(")").unwrap();
315 }
316
317 fn prepare_generated_column(&self, r#gen: &Expr, stored: bool, sql: &mut impl SqlWriter) {
319 sql.write_str(" GENERATED ALWAYS AS (").unwrap();
320 QueryBuilder::prepare_expr(self, r#gen, sql);
321 sql.write_str(")").unwrap();
322 if stored {
323 sql.write_str(" STORED").unwrap();
324 } else {
325 sql.write_str(" VIRTUAL").unwrap();
326 }
327 }
328
329 fn prepare_create_table_if_not_exists(
331 &self,
332 create: &TableCreateStatement,
333 sql: &mut impl SqlWriter,
334 ) {
335 if create.if_not_exists {
336 sql.write_str("IF NOT EXISTS ").unwrap();
337 }
338 }
339
340 fn prepare_create_temporary_table(
342 &self,
343 create: &TableCreateStatement,
344 sql: &mut impl SqlWriter,
345 ) {
346 if create.temporary {
347 sql.write_str("TEMPORARY ").unwrap();
348 }
349 }
350
351 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut impl SqlWriter);
353
354 fn prepare_table_rename_statement(
356 &self,
357 rename: &TableRenameStatement,
358 sql: &mut impl SqlWriter,
359 );
360}