BigW Consortium Gitlab

20161207231620_fixup_environment_name_uniqueness.rb 1.57 KB
Newer Older
1 2 3 4
class FixupEnvironmentNameUniqueness < ActiveRecord::Migration
  include Gitlab::Database::MigrationHelpers

  DOWNTIME = true
5
  DOWNTIME_REASON = 'Renaming non-unique environments'
6 7 8 9 10

  def up
    environments = Arel::Table.new(:environments)

    # Get all [project_id, name] pairs that occur more than once
11 12 13 14 15
    finder_sql = environments.
      group(environments[:project_id], environments[:name]).
      having(Arel.sql("COUNT(1)").gt(1)).
      project(environments[:project_id], environments[:name]).
      to_sql
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    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)
31 32 33 34 35 36
    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
37 38 39 40 41 42 43

    # 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 =
44 45 46 47 48
        Arel::UpdateManager.new(ActiveRecord::Base).
          table(environments).
          set(environments[:name] => name + "-" + id.to_s).
          where(environments[:id].eq(id)).
          to_sql
49 50 51 52 53

      connection.exec_update(update_sql, self.class.name, [])
    end
  end
end