diff --git a/src/migration/collation/m20241022_065427_case_insensitive_collation.rs b/src/migration/collation/m20241022_065427_case_insensitive_collation.rs new file mode 100644 index 00000000..a86a0bfe --- /dev/null +++ b/src/migration/collation/m20241022_065427_case_insensitive_collation.rs @@ -0,0 +1,25 @@ +//! Migration to create a case-insensitive collation. +//! +//! See: +//! +//! Note: Currently only supports Postgres. If another DB is used, will do nothing. + +use crate::migration::collation::{ + exec_create_case_insensitive_collation, exec_drop_case_insensitive_collation, +}; +use async_trait::async_trait; +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + exec_create_case_insensitive_collation(manager).await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + exec_drop_case_insensitive_collation(manager).await + } +} diff --git a/src/migration/collation/mod.rs b/src/migration/collation/mod.rs new file mode 100644 index 00000000..abf5257e --- /dev/null +++ b/src/migration/collation/mod.rs @@ -0,0 +1,173 @@ +//! Utilities and migrations related to collations. + +pub mod m20241022_065427_case_insensitive_collation; + +use sea_orm::{DbBackend, Statement}; +use sea_orm_migration::prelude::*; + +/// Collations available from Roadster. +#[derive(DeriveIden)] +#[non_exhaustive] +pub enum Collation { + /// The `default` collation. This comes included in Postgres. + /// + /// Note: This iden needs to be surrounded in quotes, at least in Postgres. + Default, + /// A case-insensitive collation. + CaseInsensitive, +} + +/// Wrapper around [`create_case_insensitive_collation`] to execute the returned [`Statement`], if +/// present. +/// +/// # Examples +/// ```rust +/// use roadster::migration::collation::exec_create_case_insensitive_collation; +/// use sea_orm_migration::prelude::*; +/// +/// #[derive(DeriveMigrationName)] +/// pub struct Migration; +/// +/// #[async_trait::async_trait] +/// impl MigrationTrait for Migration { +/// async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { +/// exec_create_case_insensitive_collation(manager).await +/// } +/// # +/// # async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { +/// # todo!() +/// # } +/// } +/// ``` +pub async fn exec_create_case_insensitive_collation( + manager: &SchemaManager<'_>, +) -> Result<(), DbErr> { + let statement = create_case_insensitive_collation(manager); + if let Some(statement) = statement { + manager.get_connection().execute(statement).await?; + } + + Ok(()) +} + +/// Create a case-insensitive collation. +/// +/// See: +/// +/// Note: Currently only supports Postgres. If another DB is used, will return [`None`]. +pub fn create_case_insensitive_collation(manager: &SchemaManager<'_>) -> Option { + let backend = manager.get_database_backend(); + create_case_insensitive_collation_for_db_backend(backend) +} + +fn create_case_insensitive_collation_for_db_backend(backend: DbBackend) -> Option { + if let DbBackend::Postgres = backend { + Some(Statement::from_string( + backend, + format!( + r#"CREATE COLLATION IF NOT EXISTS {} ( +provider = icu, +locale = 'und-u-ks-level2', +deterministic = false +); +"#, + Collation::CaseInsensitive.to_string() + ), + )) + } else { + None + } +} + +/// Wrapper around [`drop_case_insensitive_collation`] to execute the returned [`Statement`], if +/// present. +/// +/// # Examples +/// ```rust +/// use roadster::migration::collation::exec_drop_case_insensitive_collation; +/// use sea_orm_migration::prelude::*; +/// +/// #[derive(DeriveMigrationName)] +/// pub struct Migration; +/// +/// #[async_trait::async_trait] +/// impl MigrationTrait for Migration { +/// # async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { +/// # todo!() +/// # } +/// # +/// async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { +/// exec_drop_case_insensitive_collation(manager).await +/// } +/// } +/// ``` +pub async fn exec_drop_case_insensitive_collation( + manager: &SchemaManager<'_>, +) -> Result<(), DbErr> { + let statement = drop_case_insensitive_collation(manager); + if let Some(statement) = statement { + manager.get_connection().execute(statement).await?; + } + + Ok(()) +} + +/// Drop the case-insensitive collation that was previously created by [`create_case_insensitive_collation`]. +/// +/// Note: Currently only supports Postgres. If another DB is used, will return [None]. +pub fn drop_case_insensitive_collation(manager: &SchemaManager<'_>) -> Option { + let backend = manager.get_database_backend(); + drop_case_insensitive_collation_for_db_backend(backend) +} + +fn drop_case_insensitive_collation_for_db_backend(backend: DbBackend) -> Option { + if let DbBackend::Postgres = backend { + Some(Statement::from_string( + backend, + format!( + "DROP COLLATION IF EXISTS {};", + Collation::CaseInsensitive.to_string() + ), + )) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use crate::testing::snapshot::TestCase; + use insta::assert_debug_snapshot; + use rstest::{fixture, rstest}; + use sea_orm::DbBackend; + + #[fixture] + fn case() -> TestCase { + Default::default() + } + + #[rstest] + #[case(DbBackend::Postgres)] + #[case(DbBackend::MySql)] + #[case(DbBackend::Sqlite)] + #[cfg_attr(coverage_nightly, coverage(off))] + fn create_case_insensitive_collation_for_db_backend( + _case: TestCase, + #[case] backend: DbBackend, + ) { + let statement = super::create_case_insensitive_collation_for_db_backend(backend); + + assert_debug_snapshot!(statement); + } + + #[rstest] + #[case(DbBackend::Postgres)] + #[case(DbBackend::MySql)] + #[case(DbBackend::Sqlite)] + #[cfg_attr(coverage_nightly, coverage(off))] + fn drop_case_insensitive_collation_for_db_backend(_case: TestCase, #[case] backend: DbBackend) { + let statement = super::drop_case_insensitive_collation_for_db_backend(backend); + + assert_debug_snapshot!(statement); + } +} diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_1.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_1.snap new file mode 100644 index 00000000..a9cbc6e9 --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_1.snap @@ -0,0 +1,11 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +Some( + Statement { + sql: "CREATE COLLATION IF NOT EXISTS case_insensitive (\nprovider = icu,\nlocale = 'und-u-ks-level2',\ndeterministic = false\n);\n", + values: None, + db_backend: Postgres, + }, +) diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_2.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_2.snap new file mode 100644 index 00000000..61aca4be --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_2.snap @@ -0,0 +1,5 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +None diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_3.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_3.snap new file mode 100644 index 00000000..61aca4be --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__create_case_insensitive_collation_for_db_backend@case_3.snap @@ -0,0 +1,5 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +None diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_1.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_1.snap new file mode 100644 index 00000000..82ee278f --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_1.snap @@ -0,0 +1,11 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +Some( + Statement { + sql: "DROP COLLATION IF EXISTS case_insensitive;", + values: None, + db_backend: Postgres, + }, +) diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_2.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_2.snap new file mode 100644 index 00000000..61aca4be --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_2.snap @@ -0,0 +1,5 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +None diff --git a/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_3.snap b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_3.snap new file mode 100644 index 00000000..61aca4be --- /dev/null +++ b/src/migration/collation/snapshots/roadster__migration__collation__tests__drop_case_insensitive_collation_for_db_backend@case_3.snap @@ -0,0 +1,5 @@ +--- +source: src/migration/collation/mod.rs +expression: statement +--- +None diff --git a/src/migration/mod.rs b/src/migration/mod.rs index 02ae47aa..d507e919 100644 --- a/src/migration/mod.rs +++ b/src/migration/mod.rs @@ -4,6 +4,7 @@ //! Additionally, some utilities are provided to create some common column types. pub mod check; +pub mod collation; pub mod schema; pub mod timestamp; pub mod user; diff --git a/src/migration/timestamp/m20240723_201404_add_update_timestamp_function.rs b/src/migration/timestamp/m20240723_201404_add_update_timestamp_function.rs index 291df153..68996872 100644 --- a/src/migration/timestamp/m20240723_201404_add_update_timestamp_function.rs +++ b/src/migration/timestamp/m20240723_201404_add_update_timestamp_function.rs @@ -1,4 +1,4 @@ -//! Migration to create a SQL function to update the [Timestamps::UpdatedAt] column for a row +//! Migration to create a SQL function to update the [`Timestamps::UpdatedAt`] column for a row //! with the current timestamp. //! //! Note: Currently only supports Postgres. If another DB is used, will do nothing. diff --git a/src/migration/timestamp/mod.rs b/src/migration/timestamp/mod.rs index 4667222c..f96b30c8 100644 --- a/src/migration/timestamp/mod.rs +++ b/src/migration/timestamp/mod.rs @@ -9,19 +9,19 @@ pub mod m20240723_201404_add_update_timestamp_function; #[derive(DeriveIden)] #[non_exhaustive] pub enum Timestamps { - /// When the row was created. When used with the [crate::migration::schema::timestamps] method, will default to + /// When the row was created. When used with the [`crate::migration::schema::timestamps`] method, will default to /// the current timestamp (with timezone). CreatedAt, - /// When the row was updated. When used with the [crate::migration::schema::timestamps] method, will be initially set to + /// When the row was updated. When used with the [`crate::migration::schema::timestamps`] method, will be initially set to /// the current timestamp (with timezone). /// /// To automatically update the value for a row whenever the row is updated, include the - /// [m20240723_201404_add_update_timestamp_function::Migration] - /// in your [MigratorTrait] implementation, along with a [MigrationTrait] for your table + /// [`m20240723_201404_add_update_timestamp_function::Migration`] + /// in your [`MigratorTrait`] implementation, along with a [`MigrationTrait`] for your table /// that add a trigger to update the column. Helper methods are provided for this in - /// the [crate::migration::timestamp] module. Specifically, see: - /// - [exec_create_update_timestamp_trigger] - /// - [exec_drop_update_timestamp_trigger] + /// the [`crate::migration::timestamp`] module. Specifically, see: + /// - [`exec_create_update_timestamp_trigger`] + /// - [`exec_drop_update_timestamp_trigger`] /// /// Note that the auto-updates mentioned above are currently only supported on Postgres. If /// an app is using a different DB, it will need to manually update the timestamp when updating @@ -29,7 +29,7 @@ pub enum Timestamps { UpdatedAt, } -/// Wrapper around [create_update_timestamp_function] to execute the returned [Statement], if +/// Wrapper around [`create_update_timestamp_function`] to execute the returned [`Statement`], if /// present. /// /// # Examples @@ -66,8 +66,8 @@ pub async fn exec_create_update_timestamp_function( Ok(()) } -/// Wrapper around [create_update_timestamp_function_dep_column] to execute the returned -/// [Statement], if present. +/// Wrapper around [`create_update_timestamp_function_dep_column`] to execute the returned +/// [`Statement`], if present. /// /// # Examples /// ```rust @@ -119,9 +119,9 @@ pub async fn exec_create_update_timestamp_function_dep_column( manager: &SchemaManager<'_>, timestamp_column: C, @@ -131,10 +131,10 @@ pub fn create_update_timestamp_function( } /// Create a SQL function to update a timestamp column with the current timestamp, but only -/// if the provided dependent column is modified. Returns a [Statement] containing the SQL +/// if the provided dependent column is modified. Returns a [`Statement`] containing the SQL /// instructions to create the function. /// -/// Note: Currently only supports Postgres. If another DB is used, will return [None]. +/// Note: Currently only supports Postgres. If another DB is used, will return [`None`]. pub fn create_update_timestamp_function_dep_column( manager: &SchemaManager<'_>, timestamp_column: C, @@ -149,9 +149,9 @@ pub fn create_update_timestamp_function_dep_column( } /// Create a SQL function to update a timestamp column with the current timestamp. Returns -/// a [Statement] containing the SQL instructions to create the function. +/// a [`Statement`] containing the SQL instructions to create the function. /// -/// Note: Currently only supports Postgres. If another DB is used, will return [None]. +/// Note: Currently only supports Postgres. If another DB is used, will return [`None`]. fn create_update_timestamp_function_for_db_backend( backend: DbBackend, timestamp_column: C, @@ -183,10 +183,10 @@ $$ language 'plpgsql'; } /// Create a SQL function to update a timestamp column with the current timestamp, but only -/// if the provided dependent column is modified. Returns a [Statement] containing the SQL +/// if the provided dependent column is modified. Returns a [`Statement`] containing the SQL /// instructions to create the function. /// -/// Note: Currently only supports Postgres. If another DB is used, will return [None]. +/// Note: Currently only supports Postgres. If another DB is used, will return [`None`]. fn create_update_timestamp_function_dep_column_for_db_backend( backend: DbBackend, timestamp_column: C, @@ -223,7 +223,7 @@ $$ language 'plpgsql'; } } -/// Wrapper around [drop_update_timestamp_function] to execute the returned [Statement], if +/// Wrapper around [`drop_update_timestamp_function`] to execute the returned [`Statement`], if /// present. /// /// # Examples @@ -288,7 +288,7 @@ fn drop_update_timestamp_function_for_db_backend( } } -/// Wrapper around [create_update_timestamp_trigger] to execute the returned [Statement], if +/// Wrapper around [`create_update_timestamp_trigger`] to execute the returned [`Statement`], if /// present. /// /// # Examples @@ -334,10 +334,10 @@ pub async fn exec_create_update_timestamp_trigger( manager: &SchemaManager<'_>, table: T, @@ -378,7 +378,7 @@ EXECUTE PROCEDURE {fn_call}; } } -/// Wrapper around [drop_update_timestamp_trigger] to execute the returned [Statement], if +/// Wrapper around [`drop_update_timestamp_trigger`] to execute the returned [`Statement`], if /// present. /// /// # Examples @@ -423,10 +423,10 @@ pub async fn exec_drop_update_timestamp_trigger( manager: &SchemaManager<'_>, table: T, diff --git a/src/migration/user/m20241022_072216_case_insensitive_username_email.rs b/src/migration/user/m20241022_072216_case_insensitive_username_email.rs new file mode 100644 index 00000000..48ddb9de --- /dev/null +++ b/src/migration/user/m20241022_072216_case_insensitive_username_email.rs @@ -0,0 +1,113 @@ +use crate::migration::collation::Collation; +use crate::migration::user::User; +use sea_orm::{DbBackend, Statement, TransactionTrait}; +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + let transaction = db.begin().await?; + + for statement in up_statements(manager.get_database_backend()) { + transaction.execute(statement).await?; + } + + transaction.commit().await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + let transaction = db.begin().await?; + + for statement in down_statements(manager.get_database_backend()) { + transaction.execute(statement).await?; + } + + transaction.commit().await?; + + Ok(()) + } +} + +fn up_statements(db_backend: DbBackend) -> Vec { + vec![ + alter_table_set_case_insensitive_collation(db_backend, User::Username), + alter_table_set_case_insensitive_collation(db_backend, User::Email), + ] +} + +fn alter_table_set_case_insensitive_collation(db_backend: DbBackend, column: User) -> Statement { + Statement::from_string( + db_backend, + format!( + r#"ALTER table "{}" ALTER COLUMN "{}" type {} COLLATE {}"#, + User::Table.to_string(), + column.to_string(), + // Todo: Can we get this dynamically? + "varchar", + Collation::CaseInsensitive.to_string(), + ), + ) +} + +fn down_statements(db_backend: DbBackend) -> Vec { + vec![ + alter_table_reset_collation(db_backend, User::Username), + alter_table_reset_collation(db_backend, User::Email), + ] +} + +fn alter_table_reset_collation(db_backend: DbBackend, column: User) -> Statement { + Statement::from_string( + db_backend, + format!( + r#"ALTER table "{}" ALTER COLUMN "{}" type {} COLLATE "{}""#, + User::Table.to_string(), + column.to_string(), + // Todo: Can we get this dynamically? + "varchar", + Collation::Default.to_string(), + ), + ) +} + +#[cfg(test)] +mod tests { + use crate::testing::snapshot::TestCase; + use insta::assert_debug_snapshot; + use rstest::{fixture, rstest}; + use sea_orm::DbBackend; + + #[fixture] + fn case() -> TestCase { + Default::default() + } + + #[rstest] + #[case(DbBackend::Postgres)] + #[case(DbBackend::MySql)] + #[case(DbBackend::Sqlite)] + #[cfg_attr(coverage_nightly, coverage(off))] + fn up_statements(_case: TestCase, #[case] db_backend: DbBackend) { + let query = super::up_statements(db_backend); + + assert_debug_snapshot!(query); + } + + #[rstest] + #[case(DbBackend::Postgres)] + #[case(DbBackend::MySql)] + #[case(DbBackend::Sqlite)] + #[cfg_attr(coverage_nightly, coverage(off))] + fn down_statements(_case: TestCase, #[case] db_backend: DbBackend) { + let query = super::down_statements(db_backend); + + assert_debug_snapshot!(query); + } +} diff --git a/src/migration/user/mod.rs b/src/migration/user/mod.rs index 9db10865..2e89cb51 100644 --- a/src/migration/user/mod.rs +++ b/src/migration/user/mod.rs @@ -1,3 +1,4 @@ +use crate::migration::collation::m20241022_065427_case_insensitive_collation; use crate::migration::timestamp::m20240723_201404_add_update_timestamp_function; use sea_orm_migration::prelude::*; @@ -9,6 +10,7 @@ pub mod m20240724_005115_user_update_timestamp; pub mod m20240729_000812_password_updated_at; pub mod m20240729_002549_password_updated_at_function; pub mod m20240729_002615_password_updated_at_trigger; +pub mod m20241022_072216_case_insensitive_username_email; #[cfg(test)] mod tests; @@ -69,6 +71,8 @@ impl MigratorTrait for UserMigrator { Box::new(m20240729_000812_password_updated_at::Migration), Box::new(m20240729_002549_password_updated_at_function::Migration), Box::new(m20240729_002615_password_updated_at_trigger::Migration), + Box::new(m20241022_065427_case_insensitive_collation::Migration), + Box::new(m20241022_072216_case_insensitive_username_email::Migration), ] } } diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_1.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_1.snap new file mode 100644 index 00000000..51ac5223 --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_1.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE \"default\"", + values: None, + db_backend: Postgres, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE \"default\"", + values: None, + db_backend: Postgres, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_2.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_2.snap new file mode 100644 index 00000000..e86904dc --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_2.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE \"default\"", + values: None, + db_backend: MySql, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE \"default\"", + values: None, + db_backend: MySql, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_3.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_3.snap new file mode 100644 index 00000000..fec06228 --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__down_statements@case_3.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE \"default\"", + values: None, + db_backend: Sqlite, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE \"default\"", + values: None, + db_backend: Sqlite, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_1.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_1.snap new file mode 100644 index 00000000..d89a585b --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_1.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE case_insensitive", + values: None, + db_backend: Postgres, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE case_insensitive", + values: None, + db_backend: Postgres, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_2.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_2.snap new file mode 100644 index 00000000..78b8492c --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_2.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE case_insensitive", + values: None, + db_backend: MySql, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE case_insensitive", + values: None, + db_backend: MySql, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_3.snap b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_3.snap new file mode 100644 index 00000000..119afb35 --- /dev/null +++ b/src/migration/user/snapshots/roadster__migration__user__m20241022_072216_case_insensitive_username_email__tests__up_statements@case_3.snap @@ -0,0 +1,16 @@ +--- +source: src/migration/user/m20241022_072216_case_insensitive_username_email.rs +expression: query +--- +[ + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"username\" type varchar COLLATE case_insensitive", + values: None, + db_backend: Sqlite, + }, + Statement { + sql: "ALTER table \"user\" ALTER COLUMN \"email\" type varchar COLLATE case_insensitive", + values: None, + db_backend: Sqlite, + }, +] diff --git a/src/migration/user/snapshots/roadster__migration__user__tests__user_migrator_migrations.snap b/src/migration/user/snapshots/roadster__migration__user__tests__user_migrator_migrations.snap index b02828d3..36a960d5 100644 --- a/src/migration/user/snapshots/roadster__migration__user__tests__user_migrator_migrations.snap +++ b/src/migration/user/snapshots/roadster__migration__user__tests__user_migrator_migrations.snap @@ -10,4 +10,6 @@ expression: user_migrations "m20240729_000812_password_updated_at", "m20240729_002549_password_updated_at_function", "m20240729_002615_password_updated_at_trigger", + "m20241022_065427_case_insensitive_collation", + "m20241022_072216_case_insensitive_username_email", ] diff --git a/src/service/worker/sidekiq/builder.rs b/src/service/worker/sidekiq/builder.rs index 8ff48d0c..74229ebd 100644 --- a/src/service/worker/sidekiq/builder.rs +++ b/src/service/worker/sidekiq/builder.rs @@ -28,6 +28,7 @@ where state: BuilderState, } +#[allow(clippy::large_enum_variant)] enum BuilderState where S: Clone + Send + Sync + 'static,