1use crate::mysql::def::TableDef;
2use sea_query::{Alias, Iden, Table, TableCreateStatement};
3
4impl TableDef {
5 pub fn write(&self) -> TableCreateStatement {
6 let mut table = Table::create();
7 table.table(Alias::new(&self.info.name));
8 for col in self.columns.iter() {
9 table.col(col.write());
10 }
11 table.engine(self.info.engine.to_string().as_str());
12 table.character_set(self.info.char_set.to_string().as_str());
13 table.collate(self.info.collation.to_string().as_str());
14 for idx in self.indexes.iter() {
15 table.index(&mut idx.write());
16 }
17 for key in self.foreign_keys.iter() {
18 table.foreign_key(&mut key.write());
19 }
20 table
21 }
22}
23
24#[cfg(test)]
25mod tests {
26 use crate::mysql::def::*;
27 use sea_query::MysqlQueryBuilder;
28
29 #[test]
30 fn test_1() {
31 assert_eq!(
32 TableDef {
33 info: TableInfo {
34 name: "actor".to_owned(),
35 engine: StorageEngine::InnoDb,
36 auto_increment: None,
37 char_set: CharSet::Utf8Mb4,
38 collation: Collation::Utf8Mb40900AiCi,
39 comment: "".to_owned(),
40 },
41 columns: vec![
42 ColumnInfo {
43 name: "actor_id".to_owned(),
44 col_type: ColumnType::SmallInt(
45 NumericAttr {
46 maximum: None,
47 decimal: None,
48 unsigned: Some(
49 true,
50 ),
51 zero_fill: None,
52 },
53 ),
54 null: false,
55 key: ColumnKey::Primary,
56 default: None,
57 extra: ColumnExtra {
58 auto_increment: true,
59 on_update_current_timestamp: false,
60 generated: false,
61 default_generated: false,
62 },
63 expression: None,
64 comment: "Actor ID".to_owned(),
65 },
66 ColumnInfo {
67 name: "first_name".to_owned(),
68 col_type: ColumnType::Varchar(
69 StringAttr {
70 length: Some(
71 45,
72 ),
73 charset: None,
74 collation: None,
75 },
76 ),
77 null: false,
78 key: ColumnKey::NotKey,
79 default: None,
80 extra: ColumnExtra {
81 auto_increment: false,
82 on_update_current_timestamp: false,
83 generated: false,
84 default_generated: false,
85 },
86 expression: None,
87 comment: "".to_owned(),
88 },
89 ColumnInfo {
90 name: "last_name".to_owned(),
91 col_type: ColumnType::Varchar(
92 StringAttr {
93 length: Some(
94 45,
95 ),
96 charset: None,
97 collation: None,
98 },
99 ),
100 null: false,
101 key: ColumnKey::Multiple,
102 default: None,
103 extra: ColumnExtra {
104 auto_increment: false,
105 on_update_current_timestamp: false,
106 generated: false,
107 default_generated: false,
108 },
109 expression: None,
110 comment: "".to_owned(),
111 },
112 ColumnInfo {
113 name: "last_update".to_owned(),
114 col_type: ColumnType::Timestamp(
115 TimeAttr {
116 fractional: None,
117 },
118 ),
119 null: false,
120 key: ColumnKey::NotKey,
121 default: Some(
122 ColumnDefault::CurrentTimestamp,
123 ),
124 extra: ColumnExtra {
125 auto_increment: false,
126 on_update_current_timestamp: true,
127 generated: false,
128 default_generated: true,
129 },
130 expression: None,
131 comment: "".to_owned(),
132 },
133 ],
134 indexes: vec![],
135 foreign_keys: vec![],
136 }.write().to_string(MysqlQueryBuilder),
137 [
138 "CREATE TABLE `actor` (",
139 "`actor_id` smallint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Actor ID',",
140 "`first_name` varchar(45) NOT NULL,",
141 "`last_name` varchar(45) NOT NULL,",
142 "`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",
143 ")",
144 "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci",
145 ].join(" ")
146 );
147 }
148
149 #[test]
150 fn test_2() {
151 assert_eq!(
152 TableDef {
153 info: TableInfo {
154 name: "film_actor".to_owned(),
155 engine: StorageEngine::InnoDb,
156 auto_increment: None,
157 char_set: CharSet::Utf8Mb4,
158 collation: Collation::Utf8Mb40900AiCi,
159 comment: "".to_owned(),
160 },
161 columns: vec![
162 ColumnInfo {
163 name: "actor_id".to_owned(),
164 col_type: ColumnType::SmallInt(
165 NumericAttr {
166 maximum: None,
167 decimal: None,
168 unsigned: Some(
169 true,
170 ),
171 zero_fill: None,
172 },
173 ),
174 null: false,
175 key: ColumnKey::Primary,
176 default: None,
177 extra: ColumnExtra {
178 auto_increment: false,
179 on_update_current_timestamp: false,
180 generated: false,
181 default_generated: false,
182 },
183 expression: None,
184 comment: "".to_owned(),
185 },
186 ColumnInfo {
187 name: "film_id".to_owned(),
188 col_type: ColumnType::SmallInt(
189 NumericAttr {
190 maximum: None,
191 decimal: None,
192 unsigned: Some(
193 true,
194 ),
195 zero_fill: None,
196 },
197 ),
198 null: false,
199 key: ColumnKey::Primary,
200 default: None,
201 extra: ColumnExtra {
202 auto_increment: false,
203 on_update_current_timestamp: false,
204 generated: false,
205 default_generated: false,
206 },
207 expression: None,
208 comment: "".to_owned(),
209 },
210 ColumnInfo {
211 name: "last_update".to_owned(),
212 col_type: ColumnType::Timestamp(
213 TimeAttr {
214 fractional: None,
215 },
216 ),
217 null: false,
218 key: ColumnKey::NotKey,
219 default: Some(
220 ColumnDefault::CurrentTimestamp,
221 ),
222 extra: ColumnExtra {
223 auto_increment: false,
224 on_update_current_timestamp: true,
225 generated: false,
226 default_generated: true,
227 },
228 expression: None,
229 comment: "".to_owned(),
230 },
231 ],
232 indexes: vec![
233 IndexInfo {
234 unique: true,
235 name: "PRIMARY".to_owned(),
236 parts: vec![
237 IndexPart {
238 column: "actor_id".to_owned(),
239 order: IndexOrder::Ascending,
240 sub_part: None,
241 },
242 IndexPart {
243 column: "film_id".to_owned(),
244 order: IndexOrder::Ascending,
245 sub_part: None,
246 },
247 ],
248 nullable: false,
249 idx_type: IndexType::BTree,
250 comment: "".to_owned(),
251 functional: false,
252 },
253 IndexInfo {
254 unique: false,
255 name: "idx_fk_film_id".to_owned(),
256 parts: vec![
257 IndexPart {
258 column: "film_id".to_owned(),
259 order: IndexOrder::Ascending,
260 sub_part: None,
261 },
262 ],
263 nullable: false,
264 idx_type: IndexType::BTree,
265 comment: "".to_owned(),
266 functional: false,
267 },
268 ],
269 foreign_keys: vec![
270 ForeignKeyInfo {
271 name: "fk_film_actor_actor".to_owned(),
272 columns: vec![
273 "actor_id".to_owned(),
274 ],
275 referenced_table: "actor".to_owned(),
276 referenced_columns: vec![
277 "actor_id".to_owned(),
278 ],
279 on_delete: ForeignKeyAction::Restrict,
280 on_update: ForeignKeyAction::Cascade,
281 },
282 ForeignKeyInfo {
283 name: "fk_film_actor_film".to_owned(),
284 columns: vec![
285 "film_id".to_owned(),
286 ],
287 referenced_table: "film".to_owned(),
288 referenced_columns: vec![
289 "film_id".to_owned(),
290 ],
291 on_delete: ForeignKeyAction::Restrict,
292 on_update: ForeignKeyAction::Cascade,
293 },
294 ],
295 }.write().to_string(MysqlQueryBuilder),
296 vec![
297 "CREATE TABLE `film_actor` (",
298 "`actor_id` smallint UNSIGNED NOT NULL,",
299 "`film_id` smallint UNSIGNED NOT NULL,",
300 "`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,",
301 "PRIMARY KEY (`actor_id`, `film_id`),",
302 "KEY `idx_fk_film_id` (`film_id`),",
303 "CONSTRAINT `fk_film_actor_actor`",
304 "FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`)",
305 "ON DELETE RESTRICT ON UPDATE CASCADE,",
306 "CONSTRAINT `fk_film_actor_film`",
307 "FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`)",
308 "ON DELETE RESTRICT ON UPDATE CASCADE",
309 ")",
310 "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci",
311 ].join(" ")
312 );
313 }
314
315 #[test]
316 fn test_3() {
317 assert_eq!(
318 TableDef {
319 info: TableInfo {
320 name: "film_actor".to_owned(),
321 engine: StorageEngine::InnoDb,
322 auto_increment: None,
323 char_set: CharSet::Utf8Mb4,
324 collation: Collation::Utf8Mb40900AiCi,
325 comment: "".to_owned(),
326 },
327 columns: vec![],
328 indexes: vec![IndexInfo {
329 unique: false,
330 name: "idx_fk_film_id".to_owned(),
331 parts: vec![IndexPart {
332 column: "film_id".to_owned(),
333 order: IndexOrder::Ascending,
334 sub_part: Some(32),
335 },],
336 nullable: false,
337 idx_type: IndexType::BTree,
338 comment: "".to_owned(),
339 functional: false,
340 },],
341 foreign_keys: vec![],
342 }
343 .write()
344 .to_string(MysqlQueryBuilder),
345 [
346 "CREATE TABLE `film_actor` (",
347 "KEY `idx_fk_film_id` (`film_id` (32))",
348 ")",
349 "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci",
350 ]
351 .join(" ")
352 );
353 }
354
355 #[test]
356 fn test_4() {
357 assert_eq!(
358 TableDef {
359 info: TableInfo {
360 name: "film_actor".to_owned(),
361 engine: StorageEngine::InnoDb,
362 auto_increment: None,
363 char_set: CharSet::Utf8Mb4,
364 collation: Collation::Utf8Mb40900AiCi,
365 comment: "".to_owned(),
366 },
367 columns: vec![],
368 indexes: vec![IndexInfo {
369 unique: false,
370 name: "idx_fk_film_id".to_owned(),
371 parts: vec![IndexPart {
372 column: "film_id".to_owned(),
373 order: IndexOrder::Descending,
374 sub_part: None,
375 },],
376 nullable: false,
377 idx_type: IndexType::BTree,
378 comment: "".to_owned(),
379 functional: false,
380 },],
381 foreign_keys: vec![],
382 }
383 .write()
384 .to_string(MysqlQueryBuilder),
385 [
386 "CREATE TABLE `film_actor` (",
387 "KEY `idx_fk_film_id` (`film_id` DESC)",
388 ")",
389 "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci",
390 ]
391 .join(" ")
392 );
393 }
394}