module HairTrigger::Adapter
Public Instance Methods
create_trigger(name = nil, options = {})
click to toggle source
# File lib/hair_trigger/adapter.rb, line 3 def create_trigger(name = nil, options = {}) if name.is_a?(Hash) options = name name = nil end ::HairTrigger::Builder.new(name, options.merge(:execute => true, :adapter => self)) end
drop_trigger(name, table, options = {})
click to toggle source
# File lib/hair_trigger/adapter.rb, line 11 def drop_trigger(name, table, options = {}) ::HairTrigger::Builder.new(name, options.merge(:execute => true, :drop => true, :table => table, :adapter => self)).all{} end
implicit_mysql_definer()
click to toggle source
# File lib/hair_trigger/adapter.rb, line 21 def implicit_mysql_definer "'#{@config[:username] || 'root'}'@'#{@config[:host] || 'localhost'}'" end
normalize_mysql_definer(definer)
click to toggle source
# File lib/hair_trigger/adapter.rb, line 15 def normalize_mysql_definer(definer) user, host = definer.split('@') host = @config[:host] || 'localhost' if host == '%' "'#{user}'@'#{host}'" # SHOW TRIGGERS doesn't quote them, but we need quotes for creating a trigger end
quote_table_name_in_trigger(definition)
click to toggle source
a bit hacky, but we need to ensure the table name is always quoted on the way out, not just for reserved words. this is because we always quote on the way in, so we need them to match exactly when diffing
# File lib/hair_trigger/adapter.rb, line 83 def quote_table_name_in_trigger(definition) pattern = / ( CREATE\sTRIGGER\s+ \S+\s+ (BEFORE|AFTER|INSTEAD\s+OF)\s+ (INSERT|UPDATE|DELETE|TRUNCATE)\s+ (OR\s+(INSERT|UPDATE|DELETE|TRUNCATE)\s+)* (ON\s+) ) (\w+) # quote if not already quoted /ixm definition.sub(pattern, '\\1"\\7"') end
triggers(options = {})
click to toggle source
# File lib/hair_trigger/adapter.rb, line 25 def triggers(options = {}) triggers = {} name_clause = options[:only] ? "IN ('" + options[:only].join("', '") + "')" : nil adapter_name = HairTrigger.adapter_name_for(self) case adapter_name when *HairTrigger::SQLITE_ADAPTERS select_rows("SELECT name, sql FROM sqlite_master WHERE type = 'trigger' #{name_clause ? " AND name " + name_clause : ""}").each do |(name, definition)| triggers[name] = quote_table_name_in_trigger(definition) + ";\n" end when *HairTrigger::MYSQL_ADAPTERS select_rows("SHOW TRIGGERS").each do |(name, event, table, actions, timing, created, sql_mode, definer)| definer = normalize_mysql_definer(definer) next if options[:only] && !options[:only].include?(name) triggers[name.strip] = <<-SQL CREATE #{definer != implicit_mysql_definer ? "DEFINER = #{definer} " : ""}TRIGGER #{name} #{timing} #{event} ON `#{table}` FOR EACH ROW #{actions} SQL end when *POSTGRESQL_ADAPTERS function_conditions = "(SELECT typname FROM pg_type WHERE oid = prorettype) = 'trigger'" function_conditions << <<-SQL unless options[:simple_check] AND oid IN ( SELECT tgfoid FROM pg_trigger WHERE NOT tgisinternal AND tgconstrrelid = 0 AND tgrelid IN ( SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '#{HairTrigger.pg_schema}') ) ) SQL sql = <<-SQL SELECT tgname::varchar, pg_get_triggerdef(oid, true) FROM pg_trigger WHERE NOT tgisinternal AND tgconstrrelid = 0 AND tgrelid IN ( SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '#{HairTrigger.pg_schema}') ) #{name_clause ? " AND tgname::varchar " + name_clause : ""} UNION SELECT proname || '()', pg_get_functiondef(oid) FROM pg_proc WHERE #{function_conditions} #{name_clause ? " AND (proname || '()')::varchar " + name_clause : ""} SQL select_rows(sql).each do |(name, definition)| triggers[name] = quote_table_name_in_trigger(definition) end else raise "don't know how to retrieve #{adapter_name} triggers yet" end triggers end