diff --git a/src/backend/sqlite/table.rs b/src/backend/sqlite/table.rs index 996630045..d0a10f99c 100644 --- a/src/backend/sqlite/table.rs +++ b/src/backend/sqlite/table.rs @@ -6,7 +6,7 @@ impl TableBuilder for SqliteQueryBuilder { if let Some(column_type) = &column_def.types { write!(sql, " ").unwrap(); - self.prepare_column_type(column_type, sql); + self.prepare_column_type(&column_def.spec, column_type, sql); } let mut is_primary_key = false; @@ -39,61 +39,7 @@ impl TableBuilder for SqliteQueryBuilder { } fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter) { - write!( - sql, - "{}", - match column_type { - ColumnType::Char(length) => match length { - Some(length) => format!("text({length})"), - None => "text".into(), - }, - ColumnType::String(length) => match length { - Some(length) => format!("text({length})"), - None => "text".into(), - }, - ColumnType::Text => "text".into(), - ColumnType::TinyInteger | ColumnType::TinyUnsigned => "integer".into(), - ColumnType::SmallInteger | ColumnType::SmallUnsigned => "integer".into(), - ColumnType::Integer | ColumnType::Unsigned => "integer".into(), - ColumnType::BigInteger | ColumnType::BigUnsigned => "bigint".into(), - ColumnType::Float => "real".into(), - ColumnType::Double => "real".into(), - ColumnType::Decimal(precision) => match precision { - Some((precision, scale)) => format!("real({precision}, {scale})"), - None => "real".into(), - }, - ColumnType::DateTime => "text".into(), - ColumnType::Timestamp => "text".into(), - ColumnType::TimestampWithTimeZone => "text".into(), - ColumnType::Time => "text".into(), - ColumnType::Date => "text".into(), - ColumnType::Interval(_, _) => "unsupported".into(), - ColumnType::Binary(blob_size) => match blob_size { - BlobSize::Blob(Some(length)) => format!("binary({length})"), - _ => "blob".into(), - }, - ColumnType::VarBinary(length) => format!("binary({length})"), - ColumnType::Boolean => "boolean".into(), - ColumnType::Money(precision) => match precision { - Some((precision, scale)) => format!("integer({precision}, {scale})"), - None => "integer".into(), - }, - ColumnType::Json => "text".into(), - ColumnType::JsonBinary => "text".into(), - ColumnType::Uuid => "text(36)".into(), - ColumnType::Custom(iden) => iden.to_string(), - ColumnType::Enum { .. } => "text".into(), - ColumnType::Array(_) => unimplemented!("Array is not available in Sqlite."), - ColumnType::Cidr => unimplemented!("Cidr is not available in Sqlite."), - ColumnType::Inet => unimplemented!("Inet is not available in Sqlite."), - ColumnType::MacAddr => unimplemented!("MacAddr is not available in Sqlite."), - ColumnType::Year(_) => unimplemented!("Year is not available in Sqlite."), - ColumnType::Bit(_) => unimplemented!("Bit is not available in Sqlite."), - ColumnType::VarBit(_) => unimplemented!("VarBit is not available in Sqlite."), - ColumnType::LTree => unimplemented!("LTree is not available in Sqlite."), - } - ) - .unwrap() + self.prepare_column_type(&[], column_type, sql) } fn column_spec_auto_increment_keyword(&self) -> &str { @@ -169,3 +115,76 @@ impl TableBuilder for SqliteQueryBuilder { } } } + +impl SqliteQueryBuilder { + fn prepare_column_type( + &self, + column_specs: &[ColumnSpec], + column_type: &ColumnType, + sql: &mut dyn SqlWriter, + ) { + let is_auto_increment = column_specs + .iter() + .any(|s| matches!(s, ColumnSpec::AutoIncrement)); + write!( + sql, + "{}", + match column_type { + ColumnType::Char(length) => match length { + Some(length) => format!("text({length})"), + None => "text".into(), + }, + ColumnType::String(length) => match length { + Some(length) => format!("text({length})"), + None => "text".into(), + }, + ColumnType::Text => "text".into(), + ColumnType::TinyInteger | ColumnType::TinyUnsigned => "integer".into(), + ColumnType::SmallInteger | ColumnType::SmallUnsigned => "integer".into(), + ColumnType::Integer | ColumnType::Unsigned => "integer".into(), + ColumnType::BigInteger | ColumnType::BigUnsigned => if is_auto_increment { + "integer" + } else { + "bigint" + } + .into(), + ColumnType::Float => "real".into(), + ColumnType::Double => "real".into(), + ColumnType::Decimal(precision) => match precision { + Some((precision, scale)) => format!("real({precision}, {scale})"), + None => "real".into(), + }, + ColumnType::DateTime => "text".into(), + ColumnType::Timestamp => "text".into(), + ColumnType::TimestampWithTimeZone => "text".into(), + ColumnType::Time => "text".into(), + ColumnType::Date => "text".into(), + ColumnType::Interval(_, _) => "unsupported".into(), + ColumnType::Binary(blob_size) => match blob_size { + BlobSize::Blob(Some(length)) => format!("binary({length})"), + _ => "blob".into(), + }, + ColumnType::VarBinary(length) => format!("binary({length})"), + ColumnType::Boolean => "boolean".into(), + ColumnType::Money(precision) => match precision { + Some((precision, scale)) => format!("integer({precision}, {scale})"), + None => "integer".into(), + }, + ColumnType::Json => "text".into(), + ColumnType::JsonBinary => "text".into(), + ColumnType::Uuid => "text(36)".into(), + ColumnType::Custom(iden) => iden.to_string(), + ColumnType::Enum { .. } => "text".into(), + ColumnType::Array(_) => unimplemented!("Array is not available in Sqlite."), + ColumnType::Cidr => unimplemented!("Cidr is not available in Sqlite."), + ColumnType::Inet => unimplemented!("Inet is not available in Sqlite."), + ColumnType::MacAddr => unimplemented!("MacAddr is not available in Sqlite."), + ColumnType::Year(_) => unimplemented!("Year is not available in Sqlite."), + ColumnType::Bit(_) => unimplemented!("Bit is not available in Sqlite."), + ColumnType::VarBit(_) => unimplemented!("VarBit is not available in Sqlite."), + ColumnType::LTree => unimplemented!("LTree is not available in Sqlite."), + } + ) + .unwrap() + } +} diff --git a/src/query/with.rs b/src/query/with.rs index 4b1e4d3fc..89ea69164 100644 --- a/src/query/with.rs +++ b/src/query/with.rs @@ -10,7 +10,6 @@ use crate::SqlWriter; use crate::SubQueryStatement; use crate::TableRef; use crate::{Alias, QueryBuilder}; -use std::ops::Deref; /// A table definition inside a WITH clause ([WithClause]). /// @@ -122,7 +121,7 @@ impl CommonTableExpression { let mut cte = Self::default(); cte.try_set_cols_from_selects(&select.selects); if let Some(from) = select.from.get(0) { - match from.deref() { + match from { TableRef::Table(iden) => cte.set_table_name_from_select(iden), TableRef::SchemaTable(_, iden) => cte.set_table_name_from_select(iden), TableRef::DatabaseSchemaTable(_, _, iden) => cte.set_table_name_from_select(iden), diff --git a/tests/sqlite/table.rs b/tests/sqlite/table.rs index a3b71d488..b79af8530 100644 --- a/tests/sqlite/table.rs +++ b/tests/sqlite/table.rs @@ -172,6 +172,28 @@ fn create_6() { ); } +#[test] +fn create_7() { + assert_eq!( + Table::create() + .table(Task::Table) + .col( + ColumnDef::new(Task::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key() + ) + .to_string(SqliteQueryBuilder), + [ + r#"CREATE TABLE "task" ("#, + r#""id" integer NOT NULL PRIMARY KEY AUTOINCREMENT"#, + r#")"#, + ] + .join(" ") + ); +} + #[test] fn create_with_unique_index() { assert_eq!(