class Piggly::Installer
Public Class Methods
new(config, connection)
click to toggle source
# File lib/piggly/installer.rb, line 4 def initialize(config, connection) @config, @connection = config, connection end
Public Instance Methods
install(procedures, profile)
click to toggle source
@return [void]
# File lib/piggly/installer.rb, line 9 def install(procedures, profile) @connection.exec("begin") install_support(profile) procedures.each do |p| begin trace(p, profile) rescue Parser::Failure $stdout.puts $! end end @connection.exec("commit") rescue @connection.exec("rollback") raise end
install_support(profile)
click to toggle source
Installs necessary instrumentation support
# File lib/piggly/installer.rb, line 65 def install_support(profile) @connection.set_notice_processor(&profile.notice_processor(@config)) # def connection.set_notice_processor # # do nothing: prevent the notice processor from being subverted # end # install tracing functions @connection.exec <<-SQL -- Signals that a conditional expression was executed CREATE OR REPLACE FUNCTION piggly_cond(message varchar, value boolean) RETURNS boolean AS $$ BEGIN IF value THEN RAISE WARNING '#{@config.trace_prefix} % t', message; ELSE RAISE WARNING '#{@config.trace_prefix} % f', message; END IF; RETURN value; END $$ LANGUAGE 'plpgsql' VOLATILE; SQL @connection.exec <<-SQL -- Generic signal CREATE OR REPLACE FUNCTION piggly_signal(message varchar, signal varchar) RETURNS void AS $$ BEGIN RAISE WARNING '#{@config.trace_prefix} % %', message, signal; END $$ LANGUAGE 'plpgsql' VOLATILE; SQL @connection.exec <<-SQL -- Signals that a (sub)expression was executed. handles '' and NULL value CREATE OR REPLACE FUNCTION piggly_expr(message varchar, value varchar) RETURNS varchar AS $$ BEGIN RAISE WARNING '#{@config.trace_prefix} %', message; RETURN value; END $$ LANGUAGE 'plpgsql' VOLATILE; SQL @connection.exec <<-SQL -- Signals that a (sub)expression was executed. handles all other types CREATE OR REPLACE FUNCTION piggly_expr(message varchar, value anyelement) RETURNS anyelement AS $$ BEGIN RAISE WARNING '#{@config.trace_prefix} %', message; RETURN value; END $$ LANGUAGE 'plpgsql' VOLATILE; SQL @connection.exec <<-SQL -- Signals that a branch was taken CREATE OR REPLACE FUNCTION piggly_branch(message varchar) RETURNS void AS $$ BEGIN RAISE WARNING '#{@config.trace_prefix} %', message; END $$ LANGUAGE 'plpgsql' VOLATILE; SQL end
trace(procedure, profile)
click to toggle source
@return [void]
# File lib/piggly/installer.rb, line 42 def trace(procedure, profile) # recompile with instrumentation compiler = Compiler::TraceCompiler.new(@config) result = compiler.compile(procedure) # result[:tree] - tagged and rewritten parse tree # result[:tags] - collection of Tag values in the tree # result[:code] - instrumented @connection.exec(procedure.definition(result[:code])) profile.add(procedure, result[:tags], result) rescue $!.message << "\nError installing traced procedure #{procedure.name} " $!.message << "from #{procedure.source_path(@config)}" raise end
uninstall(procedures)
click to toggle source
@return [void]
# File lib/piggly/installer.rb, line 29 def uninstall(procedures) @connection.exec("begin") procedures.each{|p| untrace(p) } uninstall_support @connection.exec("commit") rescue @connection.exec("rollback") raise end
uninstall_support()
click to toggle source
Uninstalls instrumentation support
# File lib/piggly/installer.rb, line 127 def uninstall_support @connection.set_notice_processor{|x| $stderr.puts x } @connection.exec "DROP FUNCTION IF EXISTS piggly_cond(varchar, boolean)" @connection.exec "DROP FUNCTION IF EXISTS piggly_expr(varchar, varchar)" @connection.exec "DROP FUNCTION IF EXISTS piggly_expr(varchar, anyelement)" @connection.exec "DROP FUNCTION IF EXISTS piggly_branch(varchar)" @connection.exec "DROP FUNCTION IF EXISTS piggly_signal(varchar, varchar)" end
untrace(procedure)
click to toggle source
@return [void]
# File lib/piggly/installer.rb, line 60 def untrace(procedure) @connection.exec(procedure.definition(procedure.source(@config))) end