diff --git a/db/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key.rb b/db/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key.rb new file mode 100644 index 0000000000..4bd8074c64 --- /dev/null +++ b/db/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key.rb @@ -0,0 +1,31 @@ +Sequel.migration do + up do + if self.class.name.match?(/mysql/i) + alter_table :quota_definitions do + drop_constraint :name, if_exists: true + end + elsif self.class.name.match?(/postgres/i) + alter_table :quota_definitions do + drop_constraint :quota_definitions_name_key, if_exists: true + end + end + end + + down do + if self.class.name.match?(/mysql/i) + # mysql 5 is not so smart as mysql 8, prevent Mysql2::Error: Duplicate key name 'name' + alter_table :quota_definitions do + # rubocop:disable Sequel/ConcurrentIndex + drop_index :name, name: :name if @db.indexes(:quota_definitions).include?(:name) + # rubocop:enable Sequel/ConcurrentIndex + end + alter_table :quota_definitions do + add_unique_constraint :name, name: :name, if_not_exists: true + end + elsif self.class.name.match?(/postgres/i) + alter_table :quota_definitions do + add_unique_constraint :name, name: :quota_definitions_name_key, if_not_exists: true + end + end + end +end diff --git a/spec/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key_spec.rb b/spec/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key_spec.rb new file mode 100644 index 0000000000..4b762ca1c0 --- /dev/null +++ b/spec/migrations/20240808118000_drop_unique_constraint_quota_definitions_name_key_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' +require 'migrations/helpers/migration_shared_context' + +RSpec.describe 'migration to add or remove unique constraint on name column in quota_definitions table', isolation: :truncation, type: :migration do + include_context 'migration' do + let(:migration_filename) { '20240808118000_drop_unique_constraint_quota_definitions_name_key_spec.rb' } + end + describe 'up migration' do + context 'the unique constraint on name column exists' do + it 'removes the unique constraint' do + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).to include(:quota_definitions_name_key) + end + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).not_to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).not_to include(:quota_definitions_name_key) + end + end + + context 'the unique constraint on name column does not exist' do + it 'does not throw an error' do + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).not_to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).not_to include(:quota_definitions_name_key) + end + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).not_to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).not_to include(:quota_definitions_name_key) + end + end + end + end + end + + describe 'down migration' do + context 'unique constraint on name column does not exist' do + before do + Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) + end + + it 'adds the unique constraint' do + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).not_to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).not_to include(:quota_definitions_name_key) + end + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).to include(:quota_definitions_name_key) + end + end + end + + context 'unique constraint on name column does exist' do + it 'does not fail' do + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).to include(:quota_definitions_name_key) + end + expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }.not_to raise_error + if db.database_type == :mysql + expect(db.indexes(:quota_definitions)).to include(:name) + elsif db.database_type == :postgres + expect(db.indexes(:quota_definitions)).to include(:quota_definitions_name_key) + end + end + end + end +end