1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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