summaryrefslogtreecommitdiff
path: root/db/post_migrate/20170301205640_migrate_build_events_to_pipeline_events.rb
blob: 2dd14ee5a787eebe2f393dc0b047c84772f45e64 (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class MigrateBuildEventsToPipelineEvents < ActiveRecord::Migration
  include Gitlab::Database::MigrationHelpers
  include Gitlab::Database

  DOWNTIME = false

  def up
    Gitlab::Database.with_connection_pool(2) do |pool|
      threads = []

      threads << Thread.new do
        pool.with_connection do |connection|
          Thread.current[:foreign_key_connection] = connection

          execute(<<-SQL.strip_heredoc)
            UPDATE services
              SET properties = replace(properties,
                                       'notify_only_broken_builds',
                                       'notify_only_broken_pipelines')
                , pipeline_events = #{true_value}
                , build_events = #{false_value}
            WHERE type IN
              ('SlackService', 'MattermostService', 'HipchatService')
              AND build_events = #{true_value};
          SQL
        end
      end

      threads << Thread.new do
        pool.with_connection do |connection|
          Thread.current[:foreign_key_connection] = connection

          execute(update_pipeline_services_sql)
        end
      end

      threads.each(&:join)
    end
  end

  def down
    # Don't bother to migrate the data back
  end

  def connection
    # Rails memoizes connection objects, but this causes them to be shared
    # amongst threads; we don't want that.
    Thread.current[:foreign_key_connection] || ActiveRecord::Base.connection
  end

  private

  def update_pipeline_services_sql
    if Gitlab::Database.postgresql?
      <<-SQL
        UPDATE services
          SET type = 'PipelinesEmailService'
            , properties = replace(properties,
                                   'notify_only_broken_builds',
                                   'notify_only_broken_pipelines')
            , pipeline_events = #{true_value}
            , build_events = #{false_value}
        WHERE type = 'BuildsEmailService'
        AND
          (SELECT 1 FROM services pipeline_services
             WHERE pipeline_services.project_id = services.project_id
               AND pipeline_services.type = 'PipelinesEmailService' LIMIT 1)
          IS NULL;
      SQL
    else
      <<-SQL
        UPDATE services build_services
         LEFT OUTER JOIN services pipeline_services
           ON build_services.project_id = pipeline_services.project_id
          AND pipeline_services.type = 'PipelinesEmailService'
          SET build_services.type = 'PipelinesEmailService'
            , build_services.properties = replace(build_services.properties,
                                         'notify_only_broken_builds',
                                         'notify_only_broken_pipelines')
            , build_services.pipeline_events = #{true_value}
            , build_services.build_events = #{false_value}
        WHERE build_services.type = 'BuildsEmailService'
          AND pipeline_services.id IS NULL;
      SQL
    end.strip_heredoc
  end
end