summaryrefslogtreecommitdiff
path: root/db/post_migrate/20220512190659_remove_web_hooks_web_hook_logs_web_hook_id_fk.rb
blob: b73d3a7f1024344b9fb783f0a86bcfe83a87869b (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
# frozen_string_literal: true

class RemoveWebHooksWebHookLogsWebHookIdFk < Gitlab::Database::Migration[2.0]
  disable_ddl_transaction!

  PARENT_TABLE_NAME = :web_hook_logs
  FK_NAME = "fk_rails_bb3355782d"

  def up
    with_lock_retries do
      execute('LOCK web_hooks, web_hook_logs IN ACCESS EXCLUSIVE MODE') if transaction_open?

      remove_foreign_key_if_exists(:web_hook_logs, :web_hooks, name: FK_NAME)
    end
  end

  def down
    fk_attrs = {
      name: FK_NAME, # Note we need the same name for every partition
      column: :web_hook_id,
      target_column: :id,
      on_delete: :cascade
    }

    # Must add child FK's first, then to the partitioned table.
    child_tables.each do |tbl|
      add_concurrent_foreign_key(
        tbl, :web_hooks,
        # This embeds the lock table statement in the with_lock_retries inside add_concurrent_foreign_key
        reverse_lock_order: true,
        **fk_attrs)
    end

    with_lock_retries do
      execute("LOCK web_hooks, #{PARENT_TABLE_NAME} IN ACCESS EXCLUSIVE MODE") if transaction_open?
      add_foreign_key(:web_hook_logs, :web_hooks, **fk_attrs)
    end
  end

  # This table is partitioned: we need to apply the index changes to each
  # partition separately.
  def child_tables
    @child_tables ||= execute(<<~SQL.squish).pluck("child")
      SELECT inhrelid::regclass AS child
      FROM   pg_catalog.pg_inherits
      WHERE  inhparent = '#{PARENT_TABLE_NAME}'::regclass
      ORDER BY inhrelid ASC
    SQL
  end
end