sea_schema/mysql/writer/
table.rs

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}