class SQLRunner::Adapters::PostgreSQL

Constants

InvalidPreparedStatement

Public Class Methods

load() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 8
def self.load
  require "pg"
rescue LoadError
  raise MissingDependency, "make sure the `pg` gem is available"
end
new(connection_string) click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 14
def initialize(connection_string)
  @connection_string = connection_string
  connect
end

Public Instance Methods

active?() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 48
def active?
  @connection && @connection.status == PG::Connection::CONNECTION_OK
rescue PGError
  false
end
connect(started = Process.clock_gettime(Process::CLOCK_MONOTONIC)) click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 19
def connect(started = Process.clock_gettime(Process::CLOCK_MONOTONIC))
  @connection = PG.connect(@connection_string)
rescue PG::ConnectionBad
  ended = Process.clock_gettime(Process::CLOCK_MONOTONIC)

  raise unless ended - started < SQLRunner.timeout

  sleep 0.1
  connect(started)
end
disconnect() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 30
def disconnect
  @connection&.close && (@connection = nil)
end
execute(query, **bind_vars) click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 39
def execute(query, **bind_vars)
  bound_query, bindings = parse(query)
  args = extract_args(query, bindings, bind_vars)
  @connection.exec_params(bound_query, args)
rescue PG::ConnectionBad
  reconnect
  execute(query, **bind_vars)
end
inspect() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 58
def inspect
  to_s
end
parse(query) click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 62
def parse(query) # rubocop:disable Metrics/MethodLength
  bindings = {}
  count = 0

  parsed_query = query.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
    next match if Regexp.last_match(1) == ":" # skip type casting

    name = match[1..-1]
    sym_name = name.to_sym

    unless (index = bindings[sym_name])
      index = (count += 1)
      bindings[sym_name] = index
    end

    "$#{index}"
  end

  [parsed_query, bindings]
end
reconnect() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 34
def reconnect
  disconnect
  connect
end
to_s() click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 54
def to_s
  %[#<#{self.class.name} #{format('0x00%x', (object_id << 1))}>]
end

Private Instance Methods

extract_args(query, bindings, bind_vars) click to toggle source
# File lib/sql_runner/adapters/postgresql.rb, line 83
        def extract_args(query, bindings, bind_vars)
  bindings.each_with_object([]) do |(name, position), buffer|
    buffer[position - 1] = bind_vars.fetch(name) do
      raise InvalidPreparedStatement,
            "missing value for :#{name} in #{query}"
    end
  end
end