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(col_name) => {
66                sql.write_str("DROP COLUMN ").unwrap();
67                self.prepare_iden(col_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        }
80    }
81
82    fn prepare_table_rename_statement(
83        &self,
84        rename: &TableRenameStatement,
85        sql: &mut impl SqlWriter,
86    ) {
87        sql.write_str("ALTER TABLE ").unwrap();
88        if let Some(from_name) = &rename.from_name {
89            self.prepare_table_ref_table_stmt(from_name, sql);
90        }
91        sql.write_str(" RENAME TO ").unwrap();
92        if let Some(to_name) = &rename.to_name {
93            self.prepare_table_ref_table_stmt(to_name, sql);
94        }
95    }
96}
97
98impl SqliteQueryBuilder {
99    fn prepare_column_type(
100        &self,
101        _column_specs: &ColumnSpec,
102        column_type: &ColumnType,
103        sql: &mut impl SqlWriter,
104    ) {
105        match column_type {
106            ColumnType::Char(length) => match length {
107                Some(length) => {
108                    sql.write_str("char(").unwrap();
109                    write_int(sql, *length);
110                    sql.write_char(')')
111                }
112                None => sql.write_str("char"),
113            },
114            ColumnType::String(length) => match length {
115                StringLen::N(length) => {
116                    sql.write_str("varchar(").unwrap();
117                    write_int(sql, *length);
118                    sql.write_char(')')
119                }
120                _ => sql.write_str("varchar"),
121            },
122            ColumnType::Text => sql.write_str("text"),
123            ColumnType::TinyInteger | ColumnType::TinyUnsigned => sql.write_str(integer("tinyint")),
124            ColumnType::SmallInteger | ColumnType::SmallUnsigned => {
125                sql.write_str(integer("smallint"))
126            }
127            ColumnType::Integer | ColumnType::Unsigned => sql.write_str("integer"),
128            ColumnType::BigInteger | ColumnType::BigUnsigned => sql.write_str("integer"),
129            ColumnType::Float => sql.write_str("float"),
130            ColumnType::Double => sql.write_str("double"),
131            ColumnType::Decimal(precision) => match precision {
132                Some((precision, scale)) => {
133                    if precision > &16 {
134                        panic!("precision cannot be larger than 16");
135                    }
136                    sql.write_str("real(").unwrap();
137                    write_int(sql, *precision);
138                    sql.write_str(", ").unwrap();
139                    write_int(sql, *scale);
140                    sql.write_char(')')
141                }
142                None => sql.write_str("real"),
143            },
144            ColumnType::DateTime => sql.write_str("datetime_text"),
145            ColumnType::Timestamp => sql.write_str("timestamp_text"),
146            ColumnType::TimestampWithTimeZone => sql.write_str("timestamp_with_timezone_text"),
147            ColumnType::Time => sql.write_str("time_text"),
148            ColumnType::Date => sql.write_str("date_text"),
149            ColumnType::Interval(_, _) => unimplemented!("Interval is not available in Sqlite."),
150            ColumnType::Binary(length) => {
151                sql.write_str("blob(").unwrap();
152                write_int(sql, *length);
153                sql.write_char(')')
154            }
155            ColumnType::VarBinary(length) => match length {
156                StringLen::N(length) => {
157                    sql.write_str("varbinary_blob(").unwrap();
158                    write_int(sql, *length);
159                    sql.write_char(')')
160                }
161                _ => sql.write_str("varbinary_blob"),
162            },
163            ColumnType::Blob => sql.write_str("blob"),
164            ColumnType::Boolean => sql.write_str("boolean"),
165            ColumnType::Money(precision) => match precision {
166                Some((precision, scale)) => {
167                    sql.write_str("real_money(").unwrap();
168                    write_int(sql, *precision);
169                    sql.write_str(", ").unwrap();
170                    write_int(sql, *scale);
171                    sql.write_char(')')
172                }
173                None => sql.write_str("real_money"),
174            },
175            ColumnType::Json => sql.write_str("json_text"),
176            ColumnType::JsonBinary => sql.write_str("jsonb_text"),
177            ColumnType::Uuid => sql.write_str("uuid_text"),
178            ColumnType::Custom(iden) => sql.write_str(&iden.0),
179            ColumnType::Enum { .. } => sql.write_str("enum_text"),
180            ColumnType::Array(_) => unimplemented!("Array is not available in Sqlite."),
181            ColumnType::Vector(_) => unimplemented!("Vector is not available in Sqlite."),
182            ColumnType::Cidr => unimplemented!("Cidr is not available in Sqlite."),
183            ColumnType::Inet => unimplemented!("Inet is not available in Sqlite."),
184            ColumnType::MacAddr => unimplemented!("MacAddr is not available in Sqlite."),
185            ColumnType::Year => unimplemented!("Year is not available in Sqlite."),
186            ColumnType::Bit(_) => unimplemented!("Bit is not available in Sqlite."),
187            ColumnType::VarBit(_) => unimplemented!("VarBit is not available in Sqlite."),
188            ColumnType::LTree => unimplemented!("LTree is not available in Sqlite."),
189        }
190        .unwrap()
191    }
192}
193
194fn integer(ty: &str) -> &str {
195    if cfg!(feature = "option-sqlite-exact-column-type") {
196        "integer"
197    } else {
198        ty
199    }
200}