sea_query/backend/mysql/
table.rs

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