Module: PgSaurus::ConnectionAdapters::PostgreSQLAdapter::TriggerMethods

Included in:
PgSaurus::ConnectionAdapters::PostgreSQLAdapter
Defined in:
lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb

Overview

Provides methods to extend ActiveRecord::ConnectionAdapters::PostgreSQLAdapter to support db triggers.

Instance Method Summary collapse

Instance Method Details

#create_trigger(table_name, proc_name, event, options = {}) ⇒ Object

See lib/pg_saurus/connection_adapters/trigger_methods.rb



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
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb', line 11

def create_trigger(table_name, proc_name, event, options = {})
  proc_name = "#{proc_name}"
  proc_name = "#{proc_name}()" unless proc_name.end_with?(')')

  for_each   = options[:for_each] || 'ROW'
  constraint = options[:constraint]

  sql = "CREATE #{!!constraint ? "CONSTRAINT " : ""}TRIGGER #{trigger_name(proc_name, options)}\n  #{event}\n"

  sql << "  ON #{quote_table_or_view(table_name, options)}\n"
  if constraint
    sql << if options[:deferrable]
             "  DEFERRABLE INITIALLY #{!!options[:initially_deferred] ? 'DEFERRED' : 'IMMEDIATE'}\n"
           else
             "  NOT DEFERRABLE\n"
           end
  end
  sql << "  FOR EACH #{for_each}\n"
  if condition = options[:condition]
    sql << "  WHEN (#{condition})\n"
  end
  sql << "  EXECUTE PROCEDURE #{proc_name}"

  execute sql
end

#remove_trigger(table_name, proc_name, options = {}) ⇒ Object

See lib/pg_saurus/connection_adapters/trigger_methods.rb



38
39
40
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb', line 38

def remove_trigger(table_name, proc_name, options = {})
  execute "DROP TRIGGER #{trigger_name(proc_name, options)} ON #{quote_table_or_view(table_name, options)}"
end

#supports_triggers?Boolean

:nodoc

Returns:

  • (Boolean)


6
7
8
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb', line 6

def supports_triggers?
  true
end

#triggersArray<::PgSaurus::ConnectionAdapters::TriggerDefinition>

Returns the listing of currently defined db triggers



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
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb', line 45

def triggers
  res = select_all <<-SQL
    SELECT n.nspname as schema,
           c.relname as table,
           t.tgname as trigger_name,
           t.tgenabled as enable_mode,
           t.tgdeferrable as is_deferrable,
           t.tginitdeferred as is_initially_deferrable,
           pg_catalog.pg_get_triggerdef(t.oid, true) as trigger_definition
    FROM pg_catalog.pg_trigger t
      INNER JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid
      INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind IN ('r', 'v')
      AND NOT t.tgisinternal
    ORDER BY 1, 2, 3;
  SQL

  res.inject([]) do |buffer, row|
    schema                = row['schema']
    table                 = row['table']
    trigger_name          = row['trigger_name']
    is_deferrable         = row['is_deferrable']
    is_initially_deferred = row['is_initially_deferred']

    trigger_definition = row['trigger_definition']

    is_constraint = is_constraint?(trigger_definition)
    proc_name     = parse_proc_name(trigger_definition)
    event         = parse_event(trigger_definition, trigger_name)
    condition     = parse_condition(trigger_definition)

    for_every = !!(trigger_definition =~ /FOR[\s]EACH[\s]ROW/) ? :row : :statement

    if proc_name && event
      buffer << ::PgSaurus::ConnectionAdapters::TriggerDefinition.new(
        trigger_name,
        proc_name,
        is_constraint,
        event,
        for_every,
        is_deferrable,
        is_initially_deferred,
        condition,
        table,
        schema
      )
    end
    buffer
  end
end