From bf87a3c367a6dc325406d0e8f52191f2105f5235 Mon Sep 17 00:00:00 2001 From: Nahua Kang Date: Tue, 9 Aug 2022 00:01:19 +0200 Subject: [PATCH 1/4] Include space in sqlite index prepare table index expression --- src/backend/sqlite/index.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/sqlite/index.rs b/src/backend/sqlite/index.rs index 238f9fb07..84624d653 100644 --- a/src/backend/sqlite/index.rs +++ b/src/backend/sqlite/index.rs @@ -6,6 +6,7 @@ impl IndexBuilder for SqliteQueryBuilder { write!(sql, "CONSTRAINT ").unwrap(); } self.prepare_index_name(&create.index.name, sql); + write!(sql, " ").unwrap(); self.prepare_index_prefix(create, sql); From 8435d4677c3d8f5938cccefb6bad80bb7f566705 Mon Sep 17 00:00:00 2001 From: Nahua Kang Date: Tue, 9 Aug 2022 18:35:16 +0200 Subject: [PATCH 2/4] Add unit test for fixing space before unique in sqlite table index expr --- tests/sqlite/table.rs | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/sqlite/table.rs b/tests/sqlite/table.rs index c5e4e8a5b..1f0f5a6a7 100644 --- a/tests/sqlite/table.rs +++ b/tests/sqlite/table.rs @@ -239,6 +239,59 @@ fn create_with_primary_unique_index() { ); } +#[test] +fn create_with_unique_index_constraint() { + assert_eq!( + Table::create() + .table(Char::Table) + .if_not_exists() + .col( + ColumnDef::new(Char::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Char::FontSize).integer().not_null()) + .col(ColumnDef::new(Char::Character).string().not_null()) + .col(ColumnDef::new(Char::SizeW).integer().not_null()) + .col(ColumnDef::new(Char::SizeH).integer().not_null()) + .col( + ColumnDef::new(Char::FontId) + .integer() + .default(Value::Int(None)), + ) + .foreign_key( + ForeignKey::create() + .from(Char::Table, Char::FontId) + .to(Font::Table, Font::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .index( + Index::create() + .name("idx-sizehw") + .table(Char::Table) + .col(Char::SizeH) + .col(Char::SizeW) + .unique(), + ) + .to_string(SqliteQueryBuilder), + vec![ + r#"CREATE TABLE IF NOT EXISTS "character" ("#, + r#""id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"#, + r#""font_size" integer NOT NULL,"#, + r#""character" text NOT NULL,"#, + r#""size_w" integer NOT NULL,"#, + r#""size_h" integer NOT NULL,"#, + r#""font_id" integer DEFAULT NULL,"#, + r#"CONSTRAINT "idx-sizehw" UNIQUE ("size_h", "size_w"),"#, + r#"FOREIGN KEY ("font_id") REFERENCES "font" ("id") ON DELETE CASCADE ON UPDATE CASCADE"#, + r#")"#, + ].join(" ") + ); +} + #[test] fn drop_1() { assert_eq!( From 294a1f3ffd69d294991b082d3118f3f2bca8e183 Mon Sep 17 00:00:00 2001 From: Nahua Kang Date: Fri, 19 Aug 2022 11:35:41 +0200 Subject: [PATCH 3/4] Add space only when the constraint is named --- src/backend/sqlite/index.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/sqlite/index.rs b/src/backend/sqlite/index.rs index 84624d653..a2003498e 100644 --- a/src/backend/sqlite/index.rs +++ b/src/backend/sqlite/index.rs @@ -4,9 +4,9 @@ impl IndexBuilder for SqliteQueryBuilder { fn prepare_table_index_expression(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { if create.index.name.is_some() { write!(sql, "CONSTRAINT ").unwrap(); + self.prepare_index_name(&create.index.name, sql); + write!(sql, " ").unwrap(); } - self.prepare_index_name(&create.index.name, sql); - write!(sql, " ").unwrap(); self.prepare_index_prefix(create, sql); From 679e83e4b406a5d6c237156555afb1b1ece36b93 Mon Sep 17 00:00:00 2001 From: Nahua Kang Date: Sun, 28 Aug 2022 22:24:02 +0200 Subject: [PATCH 4/4] Clean up IndexBuilder trait methods --- src/backend/index_builder.rs | 30 +++++++++--------------------- src/backend/postgres/index.rs | 12 ------------ src/backend/sqlite/index.rs | 12 ------------ 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/src/backend/index_builder.rs b/src/backend/index_builder.rs index ff1b73f2b..bd2034fbe 100644 --- a/src/backend/index_builder.rs +++ b/src/backend/index_builder.rs @@ -2,34 +2,22 @@ use crate::*; pub trait IndexBuilder: QuotedBuilder + TableRefBuilder { /// Translate [`IndexCreateStatement`] into SQL expression. + /// This is the default implementation for `PostgresQueryBuilder` and `SqliteQueryBuilder`. + /// `MysqlQueryBuilder` overrides this default implementation. fn prepare_table_index_expression(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { - self.prepare_index_prefix(create, sql); - write!(sql, "KEY ").unwrap(); - - self.prepare_index_name(&create.index.name, sql); + if create.index.name.is_some() { + write!(sql, "CONSTRAINT ").unwrap(); + self.prepare_index_name(&create.index.name, sql); + write!(sql, " ").unwrap(); + } - self.prepare_index_type(&create.index_type, sql); + self.prepare_index_prefix(create, sql); self.prepare_index_columns(&create.index.columns, sql); } /// Translate [`IndexCreateStatement`] into SQL statement. - fn prepare_index_create_statement(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { - write!(sql, "CREATE ").unwrap(); - self.prepare_index_prefix(create, sql); - write!(sql, "INDEX ").unwrap(); - - self.prepare_index_name(&create.index.name, sql); - - write!(sql, " ON ").unwrap(); - if let Some(table) = &create.table { - self.prepare_table_ref_index_stmt(table, sql); - } - - self.prepare_index_type(&create.index_type, sql); - - self.prepare_index_columns(&create.index.columns, sql); - } + fn prepare_index_create_statement(&self, create: &IndexCreateStatement, sql: &mut SqlWriter); /// Translate [`TableRef`] into SQL statement. fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut SqlWriter); diff --git a/src/backend/postgres/index.rs b/src/backend/postgres/index.rs index 943844fea..4b3d98f4e 100644 --- a/src/backend/postgres/index.rs +++ b/src/backend/postgres/index.rs @@ -1,18 +1,6 @@ use super::*; impl IndexBuilder for PostgresQueryBuilder { - fn prepare_table_index_expression(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { - if create.index.name.is_some() { - write!(sql, "CONSTRAINT ").unwrap(); - self.prepare_index_name(&create.index.name, sql); - write!(sql, " ").unwrap(); - } - - self.prepare_index_prefix(create, sql); - - self.prepare_index_columns(&create.index.columns, sql); - } - fn prepare_index_create_statement(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { write!(sql, "CREATE ").unwrap(); self.prepare_index_prefix(create, sql); diff --git a/src/backend/sqlite/index.rs b/src/backend/sqlite/index.rs index a2003498e..54069cff5 100644 --- a/src/backend/sqlite/index.rs +++ b/src/backend/sqlite/index.rs @@ -1,18 +1,6 @@ use super::*; impl IndexBuilder for SqliteQueryBuilder { - fn prepare_table_index_expression(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { - if create.index.name.is_some() { - write!(sql, "CONSTRAINT ").unwrap(); - self.prepare_index_name(&create.index.name, sql); - write!(sql, " ").unwrap(); - } - - self.prepare_index_prefix(create, sql); - - self.prepare_index_columns(&create.index.columns, sql); - } - fn prepare_index_create_statement(&self, create: &IndexCreateStatement, sql: &mut SqlWriter) { write!(sql, "CREATE ").unwrap(); self.prepare_index_prefix(create, sql);