diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-05 18:07:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-05 18:07:51 +0000 |
commit | 6a7cc8c14727f6fac64a5be6838764d8d5d41468 (patch) | |
tree | 97c8a3c2f180d26f0f8f0baaa3230352b8ef1efb /db | |
parent | 872319738757edc0483346c75a2407f7019b963f (diff) | |
download | gitlab-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.rb | 69 | ||||
-rw-r--r-- | db/schema.rb | 2 |
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 |