summaryrefslogtreecommitdiff
path: root/db/post_migrate/20200810100921_add_target_type_to_audit_event.rb
blob: 8dde5945f0d081536b1ff0762f7f6c63eec6ee07 (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# frozen_string_literal: true

class AddTargetTypeToAuditEvent < ActiveRecord::Migration[6.0]
  include Gitlab::Database::SchemaHelpers
  include Gitlab::Database::MigrationHelpers

  DOWNTIME = false
  SOURCE_TABLE_NAME = 'audit_events'
  PARTITIONED_TABLE_NAME = 'audit_events_part_5fc467ac26'
  TRIGGER_FUNCTION_NAME = 'table_sync_function_2be879775d'

  def up
    with_lock_retries do
      # rubocop:disable Migration/AddLimitToTextColumns
      add_column('audit_events', :target_type, :text)
      add_column('audit_events_part_5fc467ac26', :target_type, :text)
      # rubocop:enable Migration/AddLimitToTextColumns

      create_trigger_function(TRIGGER_FUNCTION_NAME, replace: true) do
        <<~SQL
          IF (TG_OP = 'DELETE') THEN
            DELETE FROM #{PARTITIONED_TABLE_NAME} where id = OLD.id;
          ELSIF (TG_OP = 'UPDATE') THEN
            UPDATE #{PARTITIONED_TABLE_NAME}
            SET author_id = NEW.author_id,
              type = NEW.type,
              entity_id = NEW.entity_id,
              entity_type = NEW.entity_type,
              details = NEW.details,
              ip_address = NEW.ip_address,
              author_name = NEW.author_name,
              entity_path = NEW.entity_path,
              target_details = NEW.target_details,
              target_type = NEW.target_type,
              created_at = NEW.created_at
            WHERE #{PARTITIONED_TABLE_NAME}.id = NEW.id;
          ELSIF (TG_OP = 'INSERT') THEN
            INSERT INTO #{PARTITIONED_TABLE_NAME} (id,
              author_id,
              type,
              entity_id,
              entity_type,
              details,
              ip_address,
              author_name,
              entity_path,
              target_details,
              target_type,
              created_at)
            VALUES (NEW.id,
              NEW.author_id,
              NEW.type,
              NEW.entity_id,
              NEW.entity_type,
              NEW.details,
              NEW.ip_address,
              NEW.author_name,
              NEW.entity_path,
              NEW.target_details,
              NEW.target_type,
              NEW.created_at);
          END IF;
          RETURN NULL;
        SQL
      end
    end
  end

  def down
    with_lock_retries do
      remove_column SOURCE_TABLE_NAME, :target_type

      create_trigger_function(TRIGGER_FUNCTION_NAME, replace: true) do
        <<~SQL
          IF (TG_OP = 'DELETE') THEN
            DELETE FROM #{PARTITIONED_TABLE_NAME} where id = OLD.id;
          ELSIF (TG_OP = 'UPDATE') THEN
            UPDATE #{PARTITIONED_TABLE_NAME}
            SET author_id = NEW.author_id,
              type = NEW.type,
              entity_id = NEW.entity_id,
              entity_type = NEW.entity_type,
              details = NEW.details,
              ip_address = NEW.ip_address,
              author_name = NEW.author_name,
              entity_path = NEW.entity_path,
              target_details = NEW.target_details,
              created_at = NEW.created_at
            WHERE #{PARTITIONED_TABLE_NAME}.id = NEW.id;
          ELSIF (TG_OP = 'INSERT') THEN
            INSERT INTO #{PARTITIONED_TABLE_NAME} (id,
              author_id,
              type,
              entity_id,
              entity_type,
              details,
              ip_address,
              author_name,
              entity_path,
              target_details,
              created_at)
            VALUES (NEW.id,
              NEW.author_id,
              NEW.type,
              NEW.entity_id,
              NEW.entity_type,
              NEW.details,
              NEW.ip_address,
              NEW.author_name,
              NEW.entity_path,
              NEW.target_details,
              NEW.created_at);
          END IF;
          RETURN NULL;
        SQL
      end

      remove_column PARTITIONED_TABLE_NAME, :target_type
    end
  end
end