summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb140
1 files changed, 140 insertions, 0 deletions
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 727ad243349..4cf207bf9d8 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -699,6 +699,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect(model).to receive(:copy_indexes).with(:users, :old, :new)
expect(model).to receive(:copy_foreign_keys).with(:users, :old, :new)
+ expect(model).to receive(:copy_check_constraints).with(:users, :old, :new)
model.rename_column_concurrently(:users, :old, :new)
end
@@ -761,6 +762,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect(model).to receive(:change_column_default)
.with(:users, :new, old_column.default)
+ expect(model).to receive(:copy_check_constraints)
+ .with(:users, :old, :new)
+
model.rename_column_concurrently(:users, :old, :new)
end
end
@@ -856,6 +860,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect(model).to receive(:copy_indexes).with(:users, :new, :old)
expect(model).to receive(:copy_foreign_keys).with(:users, :new, :old)
+ expect(model).to receive(:copy_check_constraints).with(:users, :new, :old)
model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
end
@@ -894,6 +899,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect(model).to receive(:change_column_default)
.with(:users, :old, new_column.default)
+ expect(model).to receive(:copy_check_constraints)
+ .with(:users, :new, :old)
+
model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
end
end
@@ -2172,6 +2180,138 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
end
+ describe '#copy_check_constraints' do
+ context 'inside a transaction' do
+ it 'raises an error' do
+ expect(model).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ model.copy_check_constraints(:test_table, :old_column, :new_column)
+ end.to raise_error(RuntimeError)
+ end
+ end
+
+ context 'outside a transaction' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ allow(model).to receive(:column_exists?).and_return(true)
+ end
+
+ let(:old_column_constraints) do
+ [
+ {
+ 'schema_name' => 'public',
+ 'table_name' => 'test_table',
+ 'column_name' => 'old_column',
+ 'constraint_name' => 'check_d7d49d475d',
+ 'constraint_def' => 'CHECK ((old_column IS NOT NULL))'
+ },
+ {
+ 'schema_name' => 'public',
+ 'table_name' => 'test_table',
+ 'column_name' => 'old_column',
+ 'constraint_name' => 'check_48560e521e',
+ 'constraint_def' => 'CHECK ((char_length(old_column) <= 255))'
+ },
+ {
+ 'schema_name' => 'public',
+ 'table_name' => 'test_table',
+ 'column_name' => 'old_column',
+ 'constraint_name' => 'custom_check_constraint',
+ 'constraint_def' => 'CHECK (((old_column IS NOT NULL) AND (another_column IS NULL)))'
+ },
+ {
+ 'schema_name' => 'public',
+ 'table_name' => 'test_table',
+ 'column_name' => 'old_column',
+ 'constraint_name' => 'not_valid_check_constraint',
+ 'constraint_def' => 'CHECK ((old_column IS NOT NULL)) NOT VALID'
+ }
+ ]
+ end
+
+ it 'copies check constraints from one column to another' do
+ allow(model).to receive(:check_constraints_for)
+ .with(:test_table, :old_column, schema: nil)
+ .and_return(old_column_constraints)
+
+ allow(model).to receive(:not_null_constraint_name).with(:test_table, :new_column)
+ .and_return('check_1')
+
+ allow(model).to receive(:text_limit_name).with(:test_table, :new_column)
+ .and_return('check_2')
+
+ allow(model).to receive(:check_constraint_name)
+ .with(:test_table, :new_column, 'copy_check_constraint')
+ .and_return('check_3')
+
+ expect(model).to receive(:add_check_constraint)
+ .with(
+ :test_table,
+ '(new_column IS NOT NULL)',
+ 'check_1',
+ validate: true
+ ).once
+
+ expect(model).to receive(:add_check_constraint)
+ .with(
+ :test_table,
+ '(char_length(new_column) <= 255)',
+ 'check_2',
+ validate: true
+ ).once
+
+ expect(model).to receive(:add_check_constraint)
+ .with(
+ :test_table,
+ '((new_column IS NOT NULL) AND (another_column IS NULL))',
+ 'check_3',
+ validate: true
+ ).once
+
+ expect(model).to receive(:add_check_constraint)
+ .with(
+ :test_table,
+ '(new_column IS NOT NULL)',
+ 'check_1',
+ validate: false
+ ).once
+
+ model.copy_check_constraints(:test_table, :old_column, :new_column)
+ end
+
+ it 'does nothing if there are no constraints defined for the old column' do
+ allow(model).to receive(:check_constraints_for)
+ .with(:test_table, :old_column, schema: nil)
+ .and_return([])
+
+ expect(model).not_to receive(:add_check_constraint)
+
+ model.copy_check_constraints(:test_table, :old_column, :new_column)
+ end
+
+ it 'raises an error when the orginating column does not exist' do
+ allow(model).to receive(:column_exists?).with(:test_table, :old_column).and_return(false)
+
+ error_message = /Column old_column does not exist on test_table/
+
+ expect do
+ model.copy_check_constraints(:test_table, :old_column, :new_column)
+ end.to raise_error(RuntimeError, error_message)
+ end
+
+ it 'raises an error when the target column does not exist' do
+ allow(model).to receive(:column_exists?).with(:test_table, :new_column).and_return(false)
+
+ error_message = /Column new_column does not exist on test_table/
+
+ expect do
+ model.copy_check_constraints(:test_table, :old_column, :new_column)
+ end.to raise_error(RuntimeError, error_message)
+ end
+ end
+ end
+
describe '#add_text_limit' do
context 'when it is called with the default options' do
it 'calls add_check_constraint with an infered constraint name and validate: true' do