Class: OnlineMigrations::CopyTrigger

Inherits:
Object
  • Object
show all
Defined in:
lib/online_migrations/copy_trigger.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.on_table(table_name, connection:) ⇒ Object



8
9
10
# File 'lib/online_migrations/copy_trigger.rb', line 8

def self.on_table(table_name, connection:)
  new(table_name, connection)
end

Instance Method Details

#create(from_columns, to_columns, type_cast_functions: {}) ⇒ Object



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
# File 'lib/online_migrations/copy_trigger.rb', line 21

def create(from_columns, to_columns, type_cast_functions: {})
  from_columns, to_columns = normalize_column_names(from_columns, to_columns)
  trigger_name = name(from_columns, to_columns)
  assignment_clauses = assignment_clauses_for_columns(from_columns, to_columns, type_cast_functions)

  connection.execute(<<~SQL)
    CREATE OR REPLACE FUNCTION #{trigger_name}() RETURNS TRIGGER AS $$
    BEGIN
      #{assignment_clauses};
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
  SQL

  connection.execute(<<~SQL)
    DROP TRIGGER IF EXISTS #{trigger_name} ON #{quoted_table_name}
  SQL

  connection.execute(<<~SQL)
    CREATE TRIGGER #{trigger_name}
      BEFORE INSERT OR UPDATE
      ON #{quoted_table_name}
      FOR EACH ROW
      EXECUTE PROCEDURE #{trigger_name}();
  SQL
end

#name(from_columns, to_columns) ⇒ Object



12
13
14
15
16
17
18
19
# File 'lib/online_migrations/copy_trigger.rb', line 12

def name(from_columns, to_columns)
  from_columns, to_columns = normalize_column_names(from_columns, to_columns)

  joined_column_names = from_columns.zip(to_columns).flatten.join("_")
  identifier = "#{table_name}_#{joined_column_names}"
  hashed_identifier = OpenSSL::Digest::SHA256.hexdigest(identifier).first(10)
  "trigger_#{hashed_identifier}"
end

#remove(from_columns, to_columns) ⇒ Object



48
49
50
51
52
53
# File 'lib/online_migrations/copy_trigger.rb', line 48

def remove(from_columns, to_columns)
  trigger_name = name(from_columns, to_columns)

  connection.execute("DROP TRIGGER IF EXISTS #{trigger_name} ON #{quoted_table_name}")
  connection.execute("DROP FUNCTION IF EXISTS #{trigger_name}()")
end