Skip to main content

sea_query/backend/sqlite/
table.rs

1use super::*;
2use crate::write_int;
3
4impl TableBuilder for SqliteQueryBuilder {
5    fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut impl SqlWriter) {
6        self.prepare_iden(&column_def.name, sql);
7
8        if let Some(column_type) = &column_def.types {
9            sql.write_str(" ").unwrap();
10            self.prepare_column_type(&column_def.spec, column_type, sql);
11        }
12
13        self.prepare_column_spec(&column_def.spec, sql);
14    }
15
16    fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut impl SqlWriter) {
17        self.prepare_column_type(&ColumnSpec::default(), column_type, sql)
18    }
19
20    fn column_spec_auto_increment_keyword(&self) -> &str {
21        " AUTOINCREMENT"
22    }
23
24    fn prepare_table_drop_opt(&self, _drop_opt: &TableDropOpt, _sql: &mut impl SqlWriter) {
25        // Sqlite does not support table drop options
26    }
27
28    fn prepare_table_truncate_statement(
29        &self,
30        _truncate: &TableTruncateStatement,
31        _sql: &mut impl SqlWriter,
32    ) {
33        panic!("Sqlite doesn't support TRUNCATE statement")
34    }
35
36    fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut impl SqlWriter) {
37        if alter.options.is_empty() {
38            panic!("No alter option found")
39        }
40        if alter.options.len() > 1 {
41            panic!("Sqlite doesn't support multiple alter options")
42        }
43        sql.write_str("ALTER TABLE ").unwrap();
44        if let Some(table) = &alter.table {
45            self.prepare_table_ref_table_stmt(table, sql);
46            sql.write_str(" ").unwrap();
47        }
48        match &alter.options[0] {
49            TableAlterOption::AddColumn(AddColumnOption {
50                column,
51                if_not_exists: _,
52            }) => {
53                sql.write_str("ADD COLUMN ").unwrap();
54                self.prepare_column_def(column, sql);
55            }
56            TableAlterOption::ModifyColumn(_) => {
57                panic!("Sqlite not support modifying table column")
58            }
59            TableAlterOption::RenameColumn(from_name, to_name) => {
60                sql.write_str("RENAME COLUMN ").unwrap();
61                self.prepare_iden(from_name, sql);
62                sql.write_str(" TO ").unwrap();
63                self.prepare_iden(to_name, sql);
64            }
65            TableAlterOption::DropColumn(DropColumnOption { column_name, .. }) => {
66                sql.write_str("DROP COLUMN ").unwrap();
67                self.prepare_iden(column_name, sql);
68            }
69            TableAlterOption::DropForeignKey(_) => {
70                panic!(
71                    "Sqlite does not support modification of foreign key constraints to existing tables"
72                );
73            }
74            TableAlterOption::AddForeignKey(_) => {
75                panic!(
76                    "Sqlite does not support modification of foreign key constraints to existing tables"
77                );
78            }
79            TableAlterOption::DropConstraint(_) => {
80                panic!("Sqlite does not support dropping constraints from existing tables");
81            }
82        }
83    }
84
85    fn prepare_table_rename_statement(
86        &self,
87        rename: &TableRenameStatement,
88        sql: &mut impl SqlWriter,
89    ) {
90        sql.write_str("ALTER TABLE ").unwrap();
91        if let Some(from_name) = &rename.from_name {
92            self.prepare_table_ref_table_stmt(from_name, sql);
93        }
94        sql.write_str(" RENAME TO ").unwrap();
95        if let Some(to_name) = &rename.to_name {
96            self.prepare_table_ref_table_stmt(to_name, sql);
97        }
98    }
99}
100
101impl SqliteQueryBuilder {
102    fn prepare_column_type(
103        &self,
104        _column_specs: &ColumnSpec,
105        column_type: &ColumnType,
106        sql: &mut impl SqlWriter,
107    ) {
108        match column_type {
109            ColumnType::Char(length) => match length {
110                Some(length) => {
111                    sql.write_str("char(").unwrap();
112                    write_int(sql, *length);
113                    sql.write_char(')')
114                }
115                None => sql.write_str("char"),
116            },
117            ColumnType::String(length) => match length {
118                StringLen::N(length) => {
119                    sql.write_str("varchar(").unwrap();
120                    write_int(sql, *length);
121                    sql.write_char(')')
122                }
123                _ => sql.write_str("varchar"),
124            },
125            ColumnType::Text => sql.write_str("text"),
126            ColumnType::TinyInteger | ColumnType::TinyUnsigned => sql.write_str(integer("tinyint")),
127            ColumnType::SmallInteger | ColumnType::SmallUnsigned => {
128                sql.write_str(integer("smallint"))
129            }
130            ColumnType::Integer | ColumnType::Unsigned => sql.write_str("integer"),
131            ColumnType::BigInteger | ColumnType::BigUnsigned => sql.write_str("integer"),
132            ColumnType::Float => sql.write_str("float"),
133            ColumnType::Double => sql.write_str("double"),
134            ColumnType::Decimal(precision) => match precision {
135                Some((precision, scale)) => {
136                    // if precision > &16 {
137                    //     panic!("precision cannot be larger than 16");
138                    // }
139                    sql.write_str("real(").unwrap();
140                    write_int(sql, *precision);
141                    sql.write_str(", ").unwrap();
142                    write_int(sql, *scale);
143                    sql.write_char(')')
144                }
145                None => sql.write_str("real_decimal"),
146            },
147            ColumnType::DateTime => sql.write_str("datetime_text"),
148            ColumnType::Timestamp => sql.write_str("timestamp_text"),
149            ColumnType::TimestampWithTimeZone => sql.write_str("timestamp_with_timezone_text"),
150            ColumnType::Time => sql.write_str("time_text"),
151            ColumnType::Date => sql.write_str("date_text"),
152            ColumnType::Interval(_, _) => unimplemented!("Interval is not available in Sqlite."),
153            ColumnType::Binary(length) => {
154                sql.write_str("blob(").unwrap();
155                write_int(sql, *length);
156                sql.write_char(')')
157            }
158            ColumnType::VarBinary(length) => match length {
159                StringLen::N(length) => {
160                    sql.write_str("varbinary_blob(").unwrap();
161                    write_int(sql, *length);
162                    sql.write_char(')')
163                }
164                _ => sql.write_str("varbinary_blob"),
165            },
166            ColumnType::Blob => sql.write_str("blob"),
167            ColumnType::Boolean => sql.write_str("boolean"),
168            ColumnType::Money(precision) => match precision {
169                Some((precision, scale)) => {
170                    sql.write_str("real_money(").unwrap();
171                    write_int(sql, *precision);
172                    sql.write_str(", ").unwrap();
173                    write_int(sql, *scale);
174                    sql.write_char(')')
175                }
176                None => sql.write_str("real_money"),
177            },
178            ColumnType::Json => sql.write_str("json_text"),
179            ColumnType::JsonBinary => sql.write_str("jsonb_text"),
180            ColumnType::Uuid => sql.write_str("uuid_text"),
181            ColumnType::Custom(iden) => sql.write_str(&iden.0),
182            ColumnType::Enum { .. } => sql.write_str("enum_text"),
183            ColumnType::Array(_) => unimplemented!("Array is not available in Sqlite."),
184            ColumnType::Vector(_) => unimplemented!("Vector is not available in Sqlite."),
185            ColumnType::Cidr => unimplemented!("Cidr is not available in Sqlite."),
186            ColumnType::Inet => unimplemented!("Inet is not available in Sqlite."),
187            ColumnType::MacAddr => unimplemented!("MacAddr is not available in Sqlite."),
188            ColumnType::Year => unimplemented!("Year is not available in Sqlite."),
189            ColumnType::Bit(_) => unimplemented!("Bit is not available in Sqlite."),
190            ColumnType::VarBit(_) => unimplemented!("VarBit is not available in Sqlite."),
191            ColumnType::LTree => unimplemented!("LTree is not available in Sqlite."),
192        }
193        .unwrap()
194    }
195}
196
197fn integer(ty: &str) -> &str {
198    if cfg!(feature = "option-sqlite-exact-column-type") {
199        "integer"
200    } else {
201        ty
202    }
203}