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 dyn 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 dyn 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 dyn SqlWriter);
80
81 fn prepare_column_def_internal(
83 &self,
84 _is_alter_column: bool,
85 column_def: &ColumnDef,
86 sql: &mut dyn SqlWriter,
87 ) {
88 self.prepare_column_def(column_def, sql);
89 }
90
91 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter);
93
94 fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut dyn SqlWriter) {
96 match column_spec {
97 ColumnSpec::Null => sql.write_str("NULL").unwrap(),
98 ColumnSpec::NotNull => sql.write_str("NOT NULL").unwrap(),
99 ColumnSpec::Default(value) => {
100 sql.write_str("DEFAULT ").unwrap();
101 QueryBuilder::prepare_simple_expr(self, value, sql);
102 }
103 ColumnSpec::AutoIncrement => sql
104 .write_str(self.column_spec_auto_increment_keyword())
105 .unwrap(),
106 ColumnSpec::UniqueKey => sql.write_str("UNIQUE").unwrap(),
107 ColumnSpec::PrimaryKey => sql.write_str("PRIMARY KEY").unwrap(),
108 ColumnSpec::Check(check) => self.prepare_check_constraint(check, sql),
109 ColumnSpec::Generated { expr, stored } => {
110 self.prepare_generated_column(expr, *stored, sql)
111 }
112 ColumnSpec::Extra(string) => sql.write_str(string).unwrap(),
113 ColumnSpec::Comment(comment) => self.column_comment(comment, sql),
114 ColumnSpec::Using(_) => {}
115 }
116 }
117
118 fn column_comment(&self, _comment: &str, _sql: &mut dyn SqlWriter) {}
120
121 fn column_spec_auto_increment_keyword(&self) -> &str;
123
124 fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) {
126 self.prepare_table_opt_def(create, sql)
127 }
128
129 fn prepare_table_opt_def(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) {
131 for table_opt in create.options.iter() {
132 sql.write_str(" ").unwrap();
133 match table_opt {
134 TableOpt::Engine(s) => {
135 sql.write_str("ENGINE=").unwrap();
136 sql.write_str(s).unwrap();
137 }
138 TableOpt::Collate(s) => {
139 sql.write_str("COLLATE=").unwrap();
140 sql.write_str(s).unwrap();
141 }
142 TableOpt::CharacterSet(s) => {
143 sql.write_str("DEFAULT CHARSET=").unwrap();
144 sql.write_str(s).unwrap();
145 }
146 }
147 }
148 }
149
150 fn prepare_table_partition(&self, _table_partition: &TablePartition, _sql: &mut dyn SqlWriter) {
152 }
153
154 fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut dyn SqlWriter) {
156 sql.write_str("DROP TABLE ").unwrap();
157
158 if drop.if_exists {
159 sql.write_str("IF EXISTS ").unwrap();
160 }
161
162 let mut tables = drop.tables.iter();
163 join_io!(
164 tables,
165 table,
166 join {
167 sql.write_str(", ").unwrap();
168 },
169 do {
170 self.prepare_table_ref_table_stmt(table, sql);
171 }
172 );
173
174 for drop_opt in drop.options.iter() {
175 self.prepare_table_drop_opt(drop_opt, sql);
176 }
177 }
178
179 fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut dyn SqlWriter) {
181 match drop_opt {
182 TableDropOpt::Restrict => sql.write_str(" RESTRICT").unwrap(),
183 TableDropOpt::Cascade => sql.write_str(" CASCADE").unwrap(),
184 }
185 }
186
187 fn prepare_table_truncate_statement(
189 &self,
190 truncate: &TableTruncateStatement,
191 sql: &mut dyn SqlWriter,
192 ) {
193 sql.write_str("TRUNCATE TABLE ").unwrap();
194
195 if let Some(table) = &truncate.table {
196 self.prepare_table_ref_table_stmt(table, sql);
197 }
198 }
199
200 fn prepare_check_constraint(&self, check: &Check, sql: &mut dyn SqlWriter) {
202 if let Some(name) = &check.name {
203 sql.write_str("CONSTRAINT ").unwrap();
204 self.prepare_iden(name, sql);
205 sql.write_str(" ").unwrap();
206 }
207
208 sql.write_str("CHECK (").unwrap();
209 QueryBuilder::prepare_simple_expr(self, &check.expr, sql);
210 sql.write_str(")").unwrap();
211 }
212
213 fn prepare_generated_column(&self, r#gen: &Expr, stored: bool, sql: &mut dyn SqlWriter) {
215 sql.write_str("GENERATED ALWAYS AS (").unwrap();
216 QueryBuilder::prepare_simple_expr(self, r#gen, sql);
217 sql.write_str(")").unwrap();
218 if stored {
219 sql.write_str(" STORED").unwrap();
220 } else {
221 sql.write_str(" VIRTUAL").unwrap();
222 }
223 }
224
225 fn prepare_create_table_if_not_exists(
227 &self,
228 create: &TableCreateStatement,
229 sql: &mut dyn SqlWriter,
230 ) {
231 if create.if_not_exists {
232 sql.write_str("IF NOT EXISTS ").unwrap();
233 }
234 }
235
236 fn prepare_create_temporary_table(
238 &self,
239 create: &TableCreateStatement,
240 sql: &mut dyn SqlWriter,
241 ) {
242 if create.temporary {
243 sql.write_str("TEMPORARY ").unwrap();
244 }
245 }
246
247 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter);
249
250 fn prepare_table_rename_statement(
252 &self,
253 rename: &TableRenameStatement,
254 sql: &mut dyn SqlWriter,
255 );
256}