summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2019-04-11 16:29:44 +0200
committerYorick Peterse <yorickpeterse@gmail.com>2019-06-17 17:06:20 +0200
commit0f777a8d49568d3f5ffdd4b75b594f07e9fbd2f0 (patch)
tree848ee08d3e8c7dde2a5308dfafc30df856196d34
parentcfcdfdd2de6009e7ce55e6a415825a0eca75f0c9 (diff)
downloadgitlab-ce-0f777a8d49568d3f5ffdd4b75b594f07e9fbd2f0.tar.gz
Allow custom names for concurrent foreign keys
This is necessary for backporting the EE schema to ensure backported foreign keys use the same key names.
-rw-r--r--lib/gitlab/database/migration_helpers.rb14
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb27
2 files changed, 36 insertions, 5 deletions
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index cc61bb7fa02..1b5cd0fbb07 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -149,7 +149,7 @@ module Gitlab
# column - The name of the column to create the foreign key on.
# on_delete - The action to perform when associated data is removed,
# defaults to "CASCADE".
- def add_concurrent_foreign_key(source, target, column:, on_delete: :cascade)
+ def add_concurrent_foreign_key(source, target, column:, on_delete: :cascade, name: nil)
# Transactions would result in ALTER TABLE locks being held for the
# duration of the transaction, defeating the purpose of this method.
if transaction_open?
@@ -167,14 +167,18 @@ module Gitlab
return
end
- return add_foreign_key(source, target,
- column: column,
- on_delete: on_delete)
+ key_options = { column: column, on_delete: on_delete }
+
+ # The MySQL adapter tries to create a foreign key without a name when
+ # `:name` is nil, instead of generating a name for us.
+ key_options[:name] = name if name
+
+ return add_foreign_key(source, target, key_options)
else
on_delete = 'SET NULL' if on_delete == :nullify
end
- key_name = concurrent_foreign_key_name(source, column)
+ key_name = name || concurrent_foreign_key_name(source, column)
unless foreign_key_exists?(source, target, column: column)
Rails.logger.warn "Foreign key not created because it exists already " \
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 4e83b27e4a5..1e4c4c38f74 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -214,6 +214,23 @@ describe Gitlab::Database::MigrationHelpers do
model.add_concurrent_foreign_key(:projects, :users, column: :user_id)
end
+ it 'allows the use of a custom key name' do
+ expect(model).to receive(:add_foreign_key).with(
+ :projects,
+ :users,
+ column: :user_id,
+ on_delete: :cascade,
+ name: :foo
+ )
+
+ model.add_concurrent_foreign_key(
+ :projects,
+ :users,
+ column: :user_id,
+ name: :foo
+ )
+ end
+
it 'does not create a foreign key if it exists already' do
expect(model).to receive(:foreign_key_exists?).with(:projects, :users, column: :user_id).and_return(true)
expect(model).not_to receive(:add_foreign_key)
@@ -257,6 +274,16 @@ describe Gitlab::Database::MigrationHelpers do
model.add_concurrent_foreign_key(:projects, :users, column: :user_id)
end
+
+ it 'allows the use of a custom key name' do
+ expect(model).to receive(:disable_statement_timeout).and_call_original
+ expect(model).to receive(:execute).with(/statement_timeout/)
+ expect(model).to receive(:execute).ordered.with(/NOT VALID/)
+ expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT.+foo/)
+ expect(model).to receive(:execute).with(/RESET ALL/)
+
+ model.add_concurrent_foreign_key(:projects, :users, column: :user_id, name: :foo)
+ end
end
end
end