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 TABLE ").unwrap();
13
14 self.prepare_create_table_if_not_exists(create, sql);
15
16 if let Some(table_ref) = &create.table {
17 self.prepare_table_ref_table_stmt(table_ref, sql);
18 }
19
20 write!(sql, " ( ").unwrap();
21 let mut first = true;
22
23 create.columns.iter().for_each(|column_def| {
24 if !first {
25 write!(sql, ", ").unwrap();
26 }
27 self.prepare_column_def(column_def, sql);
28 first = false;
29 });
30
31 create.indexes.iter().for_each(|index| {
32 if !first {
33 write!(sql, ", ").unwrap();
34 }
35 self.prepare_table_index_expression(index, sql);
36 first = false;
37 });
38
39 create.foreign_keys.iter().for_each(|foreign_key| {
40 if !first {
41 write!(sql, ", ").unwrap();
42 }
43 self.prepare_foreign_key_create_statement_internal(foreign_key, sql, Mode::Creation);
44 first = false;
45 });
46
47 create.check.iter().for_each(|check| {
48 if !first {
49 write!(sql, ", ").unwrap();
50 }
51 self.prepare_check_constraint(check, sql);
52 first = false;
53 });
54
55 write!(sql, " )").unwrap();
56
57 self.prepare_table_opt(create, sql);
58
59 if let Some(extra) = &create.extra {
60 write!(sql, " {extra}").unwrap();
61 }
62 }
63
64 fn prepare_table_ref_table_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
66 match table_ref {
67 TableRef::Table(_)
68 | TableRef::SchemaTable(_, _)
69 | TableRef::DatabaseSchemaTable(_, _, _) => self.prepare_table_ref_iden(table_ref, sql),
70 _ => panic!("Not supported"),
71 }
72 }
73
74 fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut dyn SqlWriter);
76
77 fn prepare_column_def_internal(
79 &self,
80 _is_alter_column: bool,
81 column_def: &ColumnDef,
82 sql: &mut dyn SqlWriter,
83 ) {
84 self.prepare_column_def(column_def, sql);
85 }
86
87 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter);
89
90 fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut dyn SqlWriter) {
92 match column_spec {
93 ColumnSpec::Null => write!(sql, "NULL").unwrap(),
94 ColumnSpec::NotNull => write!(sql, "NOT NULL").unwrap(),
95 ColumnSpec::Default(value) => {
96 write!(sql, "DEFAULT ").unwrap();
97 QueryBuilder::prepare_simple_expr(self, value, sql);
98 }
99 ColumnSpec::AutoIncrement => {
100 write!(sql, "{}", self.column_spec_auto_increment_keyword()).unwrap()
101 }
102 ColumnSpec::UniqueKey => write!(sql, "UNIQUE").unwrap(),
103 ColumnSpec::PrimaryKey => write!(sql, "PRIMARY KEY").unwrap(),
104 ColumnSpec::Check(check) => self.prepare_check_constraint(check, sql),
105 ColumnSpec::Generated { expr, stored } => {
106 self.prepare_generated_column(expr, *stored, sql)
107 }
108 ColumnSpec::Extra(string) => write!(sql, "{string}").unwrap(),
109 ColumnSpec::Comment(comment) => self.column_comment(comment, sql),
110 ColumnSpec::Using(_) => {}
111 }
112 }
113
114 fn column_comment(&self, _comment: &str, _sql: &mut dyn SqlWriter) {}
116
117 fn column_spec_auto_increment_keyword(&self) -> &str;
119
120 fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) {
122 self.prepare_table_opt_def(create, sql)
123 }
124
125 fn prepare_table_opt_def(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) {
127 for table_opt in create.options.iter() {
128 write!(sql, " ").unwrap();
129 write!(
130 sql,
131 "{}",
132 match table_opt {
133 TableOpt::Engine(s) => format!("ENGINE={s}"),
134 TableOpt::Collate(s) => format!("COLLATE={s}"),
135 TableOpt::CharacterSet(s) => format!("DEFAULT CHARSET={s}"),
136 }
137 )
138 .unwrap()
139 }
140 }
141
142 fn prepare_table_partition(&self, _table_partition: &TablePartition, _sql: &mut dyn SqlWriter) {
144 }
145
146 fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut dyn SqlWriter) {
148 write!(sql, "DROP TABLE ").unwrap();
149
150 if drop.if_exists {
151 write!(sql, "IF EXISTS ").unwrap();
152 }
153
154 drop.tables.iter().fold(true, |first, table| {
155 if !first {
156 write!(sql, ", ").unwrap();
157 }
158 self.prepare_table_ref_table_stmt(table, sql);
159 false
160 });
161
162 for drop_opt in drop.options.iter() {
163 self.prepare_table_drop_opt(drop_opt, sql);
164 }
165 }
166
167 fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut dyn SqlWriter) {
169 write!(
170 sql,
171 " {}",
172 match drop_opt {
173 TableDropOpt::Restrict => "RESTRICT",
174 TableDropOpt::Cascade => "CASCADE",
175 }
176 )
177 .unwrap();
178 }
179
180 fn prepare_table_truncate_statement(
182 &self,
183 truncate: &TableTruncateStatement,
184 sql: &mut dyn SqlWriter,
185 ) {
186 write!(sql, "TRUNCATE TABLE ").unwrap();
187
188 if let Some(table) = &truncate.table {
189 self.prepare_table_ref_table_stmt(table, sql);
190 }
191 }
192
193 fn prepare_check_constraint(&self, check: &SimpleExpr, sql: &mut dyn SqlWriter) {
195 write!(sql, "CHECK (").unwrap();
196 QueryBuilder::prepare_simple_expr(self, check, sql);
197 write!(sql, ")").unwrap();
198 }
199
200 fn prepare_generated_column(&self, gen: &SimpleExpr, stored: bool, sql: &mut dyn SqlWriter) {
202 write!(sql, "GENERATED ALWAYS AS (").unwrap();
203 QueryBuilder::prepare_simple_expr(self, gen, sql);
204 write!(sql, ")").unwrap();
205 if stored {
206 write!(sql, " STORED").unwrap();
207 } else {
208 write!(sql, " VIRTUAL").unwrap();
209 }
210 }
211
212 fn prepare_create_table_if_not_exists(
214 &self,
215 create: &TableCreateStatement,
216 sql: &mut dyn SqlWriter,
217 ) {
218 if create.if_not_exists {
219 write!(sql, "IF NOT EXISTS ").unwrap();
220 }
221 }
222
223 fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter);
225
226 fn prepare_table_rename_statement(
228 &self,
229 rename: &TableRenameStatement,
230 sql: &mut dyn SqlWriter,
231 );
232}