sea_query/backend/mysql/
table.rs

1use super::*;
2
3impl TableBuilder for MysqlQueryBuilder {
4    fn prepare_table_opt(&self, create: &TableCreateStatement, sql: &mut dyn SqlWriter) {
5        // comment
6        if let Some(comment) = &create.comment {
7            sql.write_str(" COMMENT '").unwrap();
8            self.write_escaped(sql.as_writer(), comment);
9            sql.write_str("'").unwrap();
10        }
11        self.prepare_table_opt_def(create, sql)
12    }
13
14    fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut dyn SqlWriter) {
15        self.prepare_iden(&column_def.name, sql);
16
17        if let Some(column_type) = &column_def.types {
18            sql.write_str(" ").unwrap();
19            self.prepare_column_type(column_type, sql);
20        }
21
22        for column_spec in column_def.spec.iter() {
23            sql.write_str(" ").unwrap();
24            self.prepare_column_spec(column_spec, sql);
25        }
26    }
27
28    fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter) {
29        match column_type {
30            ColumnType::Char(length) => match length {
31                Some(length) => {
32                    sql.write_str("char(").unwrap();
33                    write!(sql, "{length}").unwrap();
34                    sql.write_str(")")
35                }
36                None => sql.write_str("char"),
37            },
38            ColumnType::String(length) => match length {
39                StringLen::N(length) => {
40                    sql.write_str("varchar(").unwrap();
41                    write!(sql, "{length}").unwrap();
42                    sql.write_char(')')
43                }
44                StringLen::None => sql.write_str("varchar(255)"),
45                StringLen::Max => sql.write_str("varchar(65535)"),
46            },
47            ColumnType::Text => sql.write_str("text"),
48            ColumnType::TinyInteger | ColumnType::TinyUnsigned => sql.write_str("tinyint"),
49            ColumnType::SmallInteger | ColumnType::SmallUnsigned => sql.write_str("smallint"),
50            ColumnType::Integer | ColumnType::Unsigned => sql.write_str("int"),
51            ColumnType::BigInteger | ColumnType::BigUnsigned => sql.write_str("bigint"),
52            ColumnType::Float => sql.write_str("float"),
53            ColumnType::Double => sql.write_str("double"),
54            ColumnType::Decimal(precision) => match precision {
55                Some((precision, scale)) => {
56                    sql.write_str("decimal(").unwrap();
57                    write!(sql, "{precision}").unwrap();
58                    sql.write_str(", ").unwrap();
59                    write!(sql, "{scale}").unwrap();
60                    sql.write_char(')')
61                }
62                None => sql.write_str("decimal"),
63            },
64            ColumnType::DateTime => sql.write_str("datetime"),
65            ColumnType::Timestamp => sql.write_str("timestamp"),
66            ColumnType::TimestampWithTimeZone => sql.write_str("timestamp"),
67            ColumnType::Time => sql.write_str("time"),
68            ColumnType::Date => sql.write_str("date"),
69            ColumnType::Year => sql.write_str("year"),
70            ColumnType::Interval(_, _) => sql.write_str("unsupported"),
71            ColumnType::Binary(length) => {
72                sql.write_str("binary(").unwrap();
73                write!(sql, "{length}").unwrap();
74                sql.write_char(')')
75            }
76            ColumnType::VarBinary(length) => match length {
77                StringLen::N(length) => {
78                    sql.write_str("varbinary(").unwrap();
79                    write!(sql, "{length}").unwrap();
80                    sql.write_char(')')
81                }
82                StringLen::None => sql.write_str("varbinary(255)"),
83                StringLen::Max => sql.write_str("varbinary(65535)"),
84            },
85            ColumnType::Blob => sql.write_str("blob"),
86            ColumnType::Bit(length) => match length {
87                Some(length) => {
88                    sql.write_str("bit(").unwrap();
89                    write!(sql, "{length}").unwrap();
90                    sql.write_char(')')
91                }
92                None => sql.write_str("bit"),
93            },
94            ColumnType::VarBit(length) => {
95                sql.write_str("bit(").unwrap();
96                write!(sql, "{length}").unwrap();
97                sql.write_char(')')
98            }
99            ColumnType::Boolean => sql.write_str("bool"),
100            ColumnType::Money(precision) => match precision {
101                Some((precision, scale)) => {
102                    sql.write_str("decimal(").unwrap();
103                    write!(sql, "{precision}").unwrap();
104                    sql.write_str(", ").unwrap();
105                    write!(sql, "{scale}").unwrap();
106                    sql.write_char(')')
107                }
108                None => sql.write_str("decimal"),
109            },
110            ColumnType::Json => sql.write_str("json"),
111            ColumnType::JsonBinary => sql.write_str("json"),
112            ColumnType::Uuid => sql.write_str("binary(16)"),
113            ColumnType::Custom(iden) => sql.write_str(&format!("{iden}")),
114            ColumnType::Enum { variants, .. } => {
115                sql.write_str("ENUM('").unwrap();
116
117                let mut viter = variants.iter();
118                join_io!(
119                    viter,
120                    variant,
121                    join {
122                        sql.write_str("', '").unwrap();
123                    },
124                    do {
125                        sql.write_str(&variant.0).unwrap();
126                    }
127                );
128
129                sql.write_str("')")
130            }
131            ColumnType::Array(_) => unimplemented!("Array is not available in MySQL."),
132            ColumnType::Vector(_) => unimplemented!("Vector is not available in MySQL."),
133            ColumnType::Cidr => unimplemented!("Cidr is not available in MySQL."),
134            ColumnType::Inet => unimplemented!("Inet is not available in MySQL."),
135            ColumnType::MacAddr => unimplemented!("MacAddr is not available in MySQL."),
136            ColumnType::LTree => unimplemented!("LTree is not available in MySQL."),
137        }
138        .unwrap();
139
140        if matches!(
141            column_type,
142            ColumnType::TinyUnsigned
143                | ColumnType::SmallUnsigned
144                | ColumnType::Unsigned
145                | ColumnType::BigUnsigned
146        ) {
147            sql.write_str(" UNSIGNED").unwrap();
148        }
149    }
150
151    fn column_spec_auto_increment_keyword(&self) -> &str {
152        "AUTO_INCREMENT"
153    }
154
155    fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter) {
156        if alter.options.is_empty() {
157            panic!("No alter option found")
158        };
159        sql.write_str("ALTER TABLE ").unwrap();
160        if let Some(table) = &alter.table {
161            self.prepare_table_ref_table_stmt(table, sql);
162            sql.write_str(" ").unwrap();
163        }
164
165        let mut opts = alter.options.iter();
166
167        join_io!(
168            opts,
169            opt,
170            join {
171                sql.write_str(", ").unwrap();
172            },
173            do {
174                match opt {
175                    TableAlterOption::AddColumn(AddColumnOption {
176                        column,
177                        if_not_exists,
178                    }) => {
179                        sql.write_str("ADD COLUMN ").unwrap();
180                        if *if_not_exists {
181                            sql.write_str("IF NOT EXISTS ").unwrap();
182                        }
183                        self.prepare_column_def(column, sql);
184                    }
185                    TableAlterOption::ModifyColumn(column_def) => {
186                        sql.write_str("MODIFY COLUMN ").unwrap();
187                        self.prepare_column_def(column_def, sql);
188                    }
189                    TableAlterOption::RenameColumn(from_name, to_name) => {
190                        sql.write_str("RENAME COLUMN ").unwrap();
191                        self.prepare_iden(from_name, sql);
192                        sql.write_str(" TO ").unwrap();
193                        self.prepare_iden(to_name, sql);
194                    }
195                    TableAlterOption::DropColumn(column_name) => {
196                        sql.write_str("DROP COLUMN ").unwrap();
197                        self.prepare_iden(column_name, sql);
198                    }
199                    TableAlterOption::DropForeignKey(name) => {
200                        let mut foreign_key = TableForeignKey::new();
201                        foreign_key.name(name.to_string());
202                        let drop = ForeignKeyDropStatement {
203                            foreign_key,
204                            table: None,
205                        };
206                        self.prepare_foreign_key_drop_statement_internal(
207                            &drop,
208                            sql,
209                            Mode::TableAlter,
210                        );
211                    }
212                    TableAlterOption::AddForeignKey(foreign_key) => {
213                        let create = ForeignKeyCreateStatement {
214                            foreign_key: foreign_key.to_owned(),
215                        };
216                        self.prepare_foreign_key_create_statement_internal(
217                            &create,
218                            sql,
219                            Mode::TableAlter,
220                        );
221                    }
222                };
223            }
224        );
225    }
226
227    fn prepare_table_rename_statement(
228        &self,
229        rename: &TableRenameStatement,
230        sql: &mut dyn SqlWriter,
231    ) {
232        sql.write_str("RENAME TABLE ").unwrap();
233        if let Some(from_name) = &rename.from_name {
234            self.prepare_table_ref_table_stmt(from_name, sql);
235        }
236        sql.write_str(" TO ").unwrap();
237        if let Some(to_name) = &rename.to_name {
238            self.prepare_table_ref_table_stmt(to_name, sql);
239        }
240    }
241
242    /// column comment
243    fn column_comment(&self, comment: &str, sql: &mut dyn SqlWriter) {
244        sql.write_str("COMMENT '").unwrap();
245        self.write_escaped(sql.as_writer(), comment);
246        sql.write_str("'").unwrap();
247    }
248}