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