summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-05 18:07:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-05 18:07:51 +0000
commit6a7cc8c14727f6fac64a5be6838764d8d5d41468 (patch)
tree97c8a3c2f180d26f0f8f0baaa3230352b8ef1efb /db
parent872319738757edc0483346c75a2407f7019b963f (diff)
downloadgitlab-ce-6a7cc8c14727f6fac64a5be6838764d8d5d41468.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'db')
-rw-r--r--db/post_migrate/20191108202723_add_unique_constraint_to_software_licenses.rb69
-rw-r--r--db/schema.rb2
2 files changed, 70 insertions, 1 deletions
diff --git a/db/post_migrate/20191108202723_add_unique_constraint_to_software_licenses.rb b/db/post_migrate/20191108202723_add_unique_constraint_to_software_licenses.rb
new file mode 100644
index 00000000000..580d3a189c8
--- /dev/null
+++ b/db/post_migrate/20191108202723_add_unique_constraint_to_software_licenses.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class AddUniqueConstraintToSoftwareLicenses < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+ DOWNTIME = false
+ NEW_INDEX = 'index_software_licenses_on_unique_name'
+ OLD_INDEX = 'index_software_licenses_on_name'
+
+ disable_ddl_transaction!
+
+ # 12 software licenses will be removed on GitLab.com
+ # 0 software license policies will be updated on GitLab.com
+ def up(attempts: 100)
+ remove_redundant_software_licenses!
+
+ add_concurrent_index :software_licenses, :name, unique: true, name: NEW_INDEX
+ remove_concurrent_index :software_licenses, :name, name: OLD_INDEX
+ rescue ActiveRecord::RecordNotUnique
+ retry if (attempts -= 1) > 0
+
+ raise StandardError, <<~EOS
+ Failed to add an unique index to software_licenses, despite retrying the
+ migration 100 times.
+
+ See https://gitlab.com/gitlab-org/gitlab/merge_requests/19840.
+ EOS
+ end
+
+ def down
+ remove_concurrent_index :software_licenses, :name, unique: true, name: NEW_INDEX
+ add_concurrent_index :software_licenses, :name, name: OLD_INDEX
+ end
+
+ private
+
+ def remove_redundant_software_licenses!
+ redundant_software_licenses = execute <<~SQL
+ SELECT min(id) id, name
+ FROM software_licenses
+ WHERE name IN (select name from software_licenses group by name having count(name) > 1)
+ GROUP BY name
+ SQL
+ say "Detected #{redundant_software_licenses.count} duplicates."
+
+ redundant_software_licenses.each_row do |id, name|
+ say_with_time("Reassigning policies that reference software license #{name}.") do
+ duplicates = software_licenses.where.not(id: id).where(name: name)
+
+ software_license_policies
+ .where(software_license_id: duplicates)
+ .update_all(software_license_id: id)
+
+ duplicates.delete_all
+ end
+ end
+ end
+
+ def table(name)
+ Class.new(ActiveRecord::Base) { self.table_name = name }
+ end
+
+ def software_licenses
+ @software_licenses ||= table(:software_licenses)
+ end
+
+ def software_license_policies
+ @software_license_policies ||= table(:software_license_policies)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index c6fa84e96b5..621ae7f380e 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -3698,7 +3698,7 @@ ActiveRecord::Schema.define(version: 2019_12_02_031812) do
create_table "software_licenses", id: :serial, force: :cascade do |t|
t.string "name", null: false
t.string "spdx_identifier", limit: 255
- t.index ["name"], name: "index_software_licenses_on_name"
+ t.index ["name"], name: "index_software_licenses_on_unique_name", unique: true
t.index ["spdx_identifier"], name: "index_software_licenses_on_spdx_identifier"
end