module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::TriggerMethods
Provides methods to extend {ActiveRecord::ConnectionAdapters::PostgreSQLAdapter} to support db triggers.
Public Instance Methods
create_trigger(table_name, proc_name, event, options = {})
click to toggle source
See lib/pg_saurus/connection_adapters/trigger_methods.rb
# 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 = {})
click to toggle source
See lib/pg_saurus/connection_adapters/trigger_methods.rb
# 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?()
click to toggle source
:nodoc
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 6 def supports_triggers? true end
triggers()
click to toggle source
Returns the listing of currently defined db triggers
@return [Array<::PgSaurus::ConnectionAdapters::TriggerDefinition>]
# 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
Private Instance Methods
is_constraint?(trigger_definition)
click to toggle source
Whether the trigger is a constraint.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 115 def is_constraint?(trigger_definition) !!(trigger_definition =~ /^CREATE CONSTRAINT TRIGGER/) end
parse_condition(trigger_definition)
click to toggle source
Parse the condition from the trigger definition.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 97 def parse_condition(trigger_definition) trigger_definition[/WHEN[\s](.*?)[\s]EXECUTE[\s](FUNCTION|PROCEDURE)/m, 1] end
parse_event(trigger_definition, trigger_name)
click to toggle source
Parse the event from the trigger definition.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 103 def parse_event(trigger_definition, trigger_name) trigger_definition[/^CREATE[\sA-Z]+TRIGGER[\s]#{Regexp.escape(trigger_name)}[\s](.*?)[\s]ON[\s]/m, 1] end
parse_proc_name(trigger_definition)
click to toggle source
Parse the procedure name from the trigger definition.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 109 def parse_proc_name(trigger_definition) trigger_definition[/EXECUTE[\s](FUNCTION|PROCEDURE)[\s](.*?)$/m, 2] end
quote_table_or_view(name, options)
click to toggle source
Properly quote the table name or view name.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 121 def quote_table_or_view(name, options) schema = options[:schema] if schema "\"#{schema}\".\"#{name}\"" else "\"#{name}\"" end end
trigger_name(proc_name, options)
click to toggle source
The name provided in the options, or constructed from the procedure name.
# File lib/pg_saurus/connection_adapters/postgresql_adapter/trigger_methods.rb, line 132 def trigger_name(proc_name, options) if name = options[:name] name else "trigger_#{proc_name.gsub('(', '').gsub(')', '')}" end end