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 sql.write_str(" ( ").unwrap();
25 let mut first = true;
26
27 create.columns.iter().for_each(|column_def| {
28 if !first {
29 sql.write_str(", ").unwrap();
30 }
31 self.prepare_column_def(column_def, sql);
32 first = false;
33 });
34
35 create.indexes.iter().for_each(|index| {
36 if !first {
37 sql.write_str(", ").unwrap();
38 }
39 self.prepare_table_index_expression(index, sql);
40 first = false;
41 });
42
43 create.foreign_keys.iter().for_each(|foreign_key| {
44 if !first {
45 sql.write_str(", ").unwrap();
46 }
47 self.prepare_foreign_key_create_statement_internal(foreign_key, sql, Mode::Creation);
48 first = false;
49 });
50
51 create.check.iter().for_each(|check| {
52 if !first {
53 sql.write_str(", ").unwrap();
54 }
55 self.prepare_check_constraint(check, sql);
56 first = false;
57 });
58
59 sql.write_str(" )").unwrap();
60
61 self.prepare_table_opt(create, sql);
62
63 if let Some(extra) = &create.extra {
64 sql.write_str(" ").unwrap();
65 sql.write_str(extra).unwrap();
66 }
67 }
68
69 fn prepare_table_ref_table_stmt(&self, table_ref: &TableRef, sql: &mut impl SqlWriter) {
71 match table_ref {
72 TableRef::Table(.., None) => self.prepare_table_ref_iden(table_ref, sql),
74 _ => panic!("Not supported"),
75 }
76 }
77
78 fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut impl SqlWriter);
80
81 fn prepare_column_def_internal(
83 &self,
84 _is_alter_column: bool,
85 column_def: &ColumnDef,
86 sql: &mut impl SqlWriter,
87 ) {
88 self.prepare_column_def(column_def, sql);
89 }
90
91 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut impl SqlWriter);
93
94 fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut impl SqlWriter) {
96 let ColumnSpec {
97 nullable,
98 default,
99 auto_increment,
100 unique,
101 primary_key,
102 check,
103 generated,
104 extra,
105 comment,
106 using: _,
107 } = column_spec;
108
109 if let Some(nullable) = nullable {
110 sql.write_str(if *nullable { " NULL" } else { " NOT NULL" })
111 .unwrap();
112 }
113
114 if let Some(default) = default {
115 write!(sql, " DEFAULT ").unwrap();
116 QueryBuilder::prepare_expr(self, default, sql);
117 }
118
119 if let Some(generated) = generated {
120 self.prepare_generated_column(&generated.expr, generated.stored, sql);
121 }
122
123 if *primary_key {
124 sql.write_str(" PRIMARY KEY").unwrap();
125 }
126
127 if *auto_increment {
128 sql.write_str(self.column_spec_auto_increment_keyword())
129 .unwrap();
130 }
131
132 if *unique {
133 sql.write_str(" UNIQUE").unwrap();
134 }
135
136 if let Some(check) = check {
137 sql.write_str(" ").unwrap();
138 self.prepare_check_constraint(check, sql);
139 }
140
141 if let Some(extra) = extra {
142 sql.write_str(" ").unwrap();
143 sql.write_str(extra).unwrap();
144 }
145
146 if let Some(comment) = comment {
147 self.column_comment(comment, sql);
148 }
149 }
150
151 fn column_comment(&self, _comment: &str, _sql: &mut impl SqlWriter) {}
153
154 fn column_spec_auto_increment_keyword(&self) -> &str;
156
157 fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut impl SqlWriter) {
159 self.prepare_table_opt_def(create, sql)
160 }
161
162 fn prepare_table_opt_def(&self, create: &TableCreateStatement, sql: &mut impl SqlWriter) {
164 for table_opt in create.options.iter() {
165 sql.write_str(" ").unwrap();
166 match table_opt {
167 TableOpt::Engine(s) => {
168 sql.write_str("ENGINE=").unwrap();
169 sql.write_str(s).unwrap();
170 }
171 TableOpt::Collate(s) => {
172 sql.write_str("COLLATE=").unwrap();
173 sql.write_str(s).unwrap();
174 }
175 TableOpt::CharacterSet(s) => {
176 sql.write_str("DEFAULT CHARSET=").unwrap();
177 sql.write_str(s).unwrap();
178 }
179 }
180 }
181 }
182
183 fn prepare_table_partition(
185 &self,
186 _table_partition: &TablePartition,
187 _sql: &mut impl SqlWriter,
188 ) {
189 }
190
191 fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut impl SqlWriter) {
193 sql.write_str("DROP TABLE ").unwrap();
194
195 if drop.if_exists {
196 sql.write_str("IF EXISTS ").unwrap();
197 }
198
199 let mut tables = drop.tables.iter();
200 join_io!(
201 tables,
202 table,
203 join {
204 sql.write_str(", ").unwrap();
205 },
206 do {
207 self.prepare_table_ref_table_stmt(table, sql);
208 }
209 );
210
211 for drop_opt in drop.options.iter() {
212 self.prepare_table_drop_opt(drop_opt, sql);
213 }
214 }
215
216 fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut impl SqlWriter) {
218 match drop_opt {
219 TableDropOpt::Restrict => sql.write_str(" RESTRICT").unwrap(),
220 TableDropOpt::Cascade => sql.write_str(" CASCADE").unwrap(),
221 }
222 }
223
224 fn prepare_table_truncate_statement(
226 &self,
227 truncate: &TableTruncateStatement,
228 sql: &mut impl SqlWriter,
229 ) {
230 sql.write_str("TRUNCATE TABLE ").unwrap();
231
232 if let Some(table) = &truncate.table {
233 self.prepare_table_ref_table_stmt(table, sql);
234 }
235 }
236
237 fn prepare_check_constraint(&self, check: &Check, sql: &mut impl SqlWriter) {
239 if let Some(name) = &check.name {
240 sql.write_str("CONSTRAINT ").unwrap();
241 self.prepare_iden(name, sql);
242 sql.write_str(" ").unwrap();
243 }
244
245 sql.write_str("CHECK (").unwrap();
246 QueryBuilder::prepare_expr(self, &check.expr, sql);
247 sql.write_str(")").unwrap();
248 }
249
250 fn prepare_generated_column(&self, r#gen: &Expr, stored: bool, sql: &mut impl SqlWriter) {
252 sql.write_str("GENERATED ALWAYS AS (").unwrap();
253 QueryBuilder::prepare_expr(self, r#gen, sql);
254 sql.write_str(")").unwrap();
255 if stored {
256 sql.write_str(" STORED").unwrap();
257 } else {
258 sql.write_str(" VIRTUAL").unwrap();
259 }
260 }
261
262 fn prepare_create_table_if_not_exists(
264 &self,
265 create: &TableCreateStatement,
266 sql: &mut impl SqlWriter,
267 ) {
268 if create.if_not_exists {
269 sql.write_str("IF NOT EXISTS ").unwrap();
270 }
271 }
272
273 fn prepare_create_temporary_table(
275 &self,
276 create: &TableCreateStatement,
277 sql: &mut impl SqlWriter,
278 ) {
279 if create.temporary {
280 sql.write_str("TEMPORARY ").unwrap();
281 }
282 }
283
284 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut impl SqlWriter);
286
287 fn prepare_table_rename_statement(
289 &self,
290 rename: &TableRenameStatement,
291 sql: &mut impl SqlWriter,
292 );
293}