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 write!(sql, "CREATE ").unwrap();
13
14 self.prepare_create_temporary_table(create, sql);
15
16 write!(sql, "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 write!(sql, " ( ").unwrap();
25 let mut first = true;
26
27 create.columns.iter().for_each(|column_def| {
28 if !first {
29 write!(sql, ", ").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 write!(sql, ", ").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 write!(sql, ", ").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 write!(sql, ", ").unwrap();
54 }
55 self.prepare_check_constraint(check, sql);
56 first = false;
57 });
58
59 write!(sql, " )").unwrap();
60
61 self.prepare_table_opt(create, sql);
62
63 if let Some(extra) = &create.extra {
64 write!(sql, " {extra}").unwrap();
65 }
66 }
67
68 fn prepare_table_ref_table_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
70 match table_ref {
71 TableRef::Table(_)
72 | TableRef::SchemaTable(_, _)
73 | TableRef::DatabaseSchemaTable(_, _, _) => 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 => write!(sql, "NULL").unwrap(),
98 ColumnSpec::NotNull => write!(sql, "NOT NULL").unwrap(),
99 ColumnSpec::Default(value) => {
100 write!(sql, "DEFAULT ").unwrap();
101 QueryBuilder::prepare_simple_expr(self, value, sql);
102 }
103 ColumnSpec::AutoIncrement => {
104 write!(sql, "{}", self.column_spec_auto_increment_keyword()).unwrap()
105 }
106 ColumnSpec::UniqueKey => write!(sql, "UNIQUE").unwrap(),
107 ColumnSpec::PrimaryKey => write!(sql, "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) => write!(sql, "{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 write!(sql, " ").unwrap();
133 write!(
134 sql,
135 "{}",
136 match table_opt {
137 TableOpt::Engine(s) => format!("ENGINE={s}"),
138 TableOpt::Collate(s) => format!("COLLATE={s}"),
139 TableOpt::CharacterSet(s) => format!("DEFAULT CHARSET={s}"),
140 }
141 )
142 .unwrap()
143 }
144 }
145
146 fn prepare_table_partition(&self, _table_partition: &TablePartition, _sql: &mut dyn SqlWriter) {
148 }
149
150 fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut dyn SqlWriter) {
152 write!(sql, "DROP TABLE ").unwrap();
153
154 if drop.if_exists {
155 write!(sql, "IF EXISTS ").unwrap();
156 }
157
158 drop.tables.iter().fold(true, |first, table| {
159 if !first {
160 write!(sql, ", ").unwrap();
161 }
162 self.prepare_table_ref_table_stmt(table, sql);
163 false
164 });
165
166 for drop_opt in drop.options.iter() {
167 self.prepare_table_drop_opt(drop_opt, sql);
168 }
169 }
170
171 fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut dyn SqlWriter) {
173 write!(
174 sql,
175 " {}",
176 match drop_opt {
177 TableDropOpt::Restrict => "RESTRICT",
178 TableDropOpt::Cascade => "CASCADE",
179 }
180 )
181 .unwrap();
182 }
183
184 fn prepare_table_truncate_statement(
186 &self,
187 truncate: &TableTruncateStatement,
188 sql: &mut dyn SqlWriter,
189 ) {
190 write!(sql, "TRUNCATE TABLE ").unwrap();
191
192 if let Some(table) = &truncate.table {
193 self.prepare_table_ref_table_stmt(table, sql);
194 }
195 }
196
197 fn prepare_check_constraint(&self, check: &SimpleExpr, sql: &mut dyn SqlWriter) {
199 write!(sql, "CHECK (").unwrap();
200 QueryBuilder::prepare_simple_expr(self, check, sql);
201 write!(sql, ")").unwrap();
202 }
203
204 fn prepare_generated_column(&self, gen: &SimpleExpr, stored: bool, sql: &mut dyn SqlWriter) {
206 write!(sql, "GENERATED ALWAYS AS (").unwrap();
207 QueryBuilder::prepare_simple_expr(self, gen, sql);
208 write!(sql, ")").unwrap();
209 if stored {
210 write!(sql, " STORED").unwrap();
211 } else {
212 write!(sql, " VIRTUAL").unwrap();
213 }
214 }
215
216 fn prepare_create_table_if_not_exists(
218 &self,
219 create: &TableCreateStatement,
220 sql: &mut dyn SqlWriter,
221 ) {
222 if create.if_not_exists {
223 write!(sql, "IF NOT EXISTS ").unwrap();
224 }
225 }
226
227 fn prepare_create_temporary_table(
229 &self,
230 create: &TableCreateStatement,
231 sql: &mut dyn SqlWriter,
232 ) {
233 if create.temporary {
234 write!(sql, "TEMPORARY ").unwrap();
235 }
236 }
237
238 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter);
240
241 fn prepare_table_rename_statement(
243 &self,
244 rename: &TableRenameStatement,
245 sql: &mut dyn SqlWriter,
246 );
247}