Make the index on environment name and project id unique, fixing up any duplicates
This commit is contained in:
parent
2d1dfae9b6
commit
35a3e91830
3 changed files with 74 additions and 3 deletions
|
@ -0,0 +1,53 @@
|
||||||
|
class FixupEnvironmentNameUniqueness < ActiveRecord::Migration
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = true
|
||||||
|
DOWNTIME_REASON = 'Renaming non-unique environments'
|
||||||
|
|
||||||
|
def up
|
||||||
|
environments = Arel::Table.new(:environments)
|
||||||
|
|
||||||
|
# Get all [project_id, name] pairs that occur more than once
|
||||||
|
finder_sql = environments.
|
||||||
|
group(environments[:project_id], environments[:name]).
|
||||||
|
having(Arel.sql("COUNT(1)").gt(1)).
|
||||||
|
project(environments[:project_id], environments[:name]).
|
||||||
|
to_sql
|
||||||
|
|
||||||
|
conflicting = connection.exec_query(finder_sql)
|
||||||
|
|
||||||
|
conflicting.rows.each do |project_id, name|
|
||||||
|
fix_duplicates(project_id, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
# Nothing to do
|
||||||
|
end
|
||||||
|
|
||||||
|
# Rename conflicting environments by appending "-#{id}" to all but the first
|
||||||
|
def fix_duplicates(project_id, name)
|
||||||
|
environments = Arel::Table.new(:environments)
|
||||||
|
finder_sql = environments.
|
||||||
|
where(environments[:project_id].eq(project_id)).
|
||||||
|
where(environments[:name].eq(name)).
|
||||||
|
order(environments[:id].asc).
|
||||||
|
project(environments[:id], environments[:name]).
|
||||||
|
to_sql
|
||||||
|
|
||||||
|
# Now we have the data for all the conflicting rows
|
||||||
|
conflicts = connection.exec_query(finder_sql).rows
|
||||||
|
conflicts.shift # Leave the first row alone
|
||||||
|
|
||||||
|
conflicts.each do |id, name|
|
||||||
|
update_sql =
|
||||||
|
Arel::UpdateManager.new(ActiveRecord::Base).
|
||||||
|
table(environments).
|
||||||
|
set(environments[:name] => name + "-" + id.to_s).
|
||||||
|
where(environments[:id].eq(id)).
|
||||||
|
to_sql
|
||||||
|
|
||||||
|
connection.exec_update(update_sql, self.class.name, [])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
class CreateEnvironmentNameUniqueIndex < ActiveRecord::Migration
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
DOWNTIME = true
|
||||||
|
DOWNTIME_REASON = 'Making a non-unique index into a unique index'
|
||||||
|
|
||||||
|
def up
|
||||||
|
remove_index :environments, [:project_id, :name]
|
||||||
|
add_concurrent_index :environments, [:project_id, :name], unique: true
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_index :environments, [:project_id, :name], unique: true
|
||||||
|
add_concurrent_index :environments, [:project_id, :name]
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20161212142807) do
|
ActiveRecord::Schema.define(version: 20161207231621) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -430,7 +430,7 @@ ActiveRecord::Schema.define(version: 20161212142807) do
|
||||||
t.string "state", default: "available", null: false
|
t.string "state", default: "available", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "environments", ["project_id", "name"], name: "index_environments_on_project_id_and_name", using: :btree
|
add_index "environments", ["project_id", "name"], name: "index_environments_on_project_id_and_name", unique: true, using: :btree
|
||||||
|
|
||||||
create_table "events", force: :cascade do |t|
|
create_table "events", force: :cascade do |t|
|
||||||
t.string "target_type"
|
t.string "target_type"
|
||||||
|
|
Loading…
Reference in a new issue