Class: SQLRunner::Adapters::PostgreSQL

Inherits:
Object
  • Object
show all
Defined in:
lib/sql_runner/adapters/postgresql.rb

Direct Known Subclasses

ActiveRecord::PostgreSQL

Constant Summary collapse

InvalidPreparedStatement =
Class.new(StandardError)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection_string) ⇒ PostgreSQL

Returns a new instance of PostgreSQL.



20
21
22
23
# File 'lib/sql_runner/adapters/postgresql.rb', line 20

def initialize(connection_string)
  @connection_string = connection_string
  connect
end

Class Method Details

.create_connection_pool(timeout:, size:, connection_string:) ⇒ Object



14
15
16
17
18
# File 'lib/sql_runner/adapters/postgresql.rb', line 14

def self.create_connection_pool(timeout:, size:, connection_string:)
  ConnectionPool.new(timeout:, size:) do
    new(connection_string)
  end
end

.loadObject



8
9
10
11
12
# 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

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


54
55
56
57
58
# File 'lib/sql_runner/adapters/postgresql.rb', line 54

def active?
  @connection && @connection.status == PG::Connection::CONNECTION_OK
rescue PGError
  false
end

#connect(started = Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ Object



25
26
27
28
29
30
31
32
33
34
# File 'lib/sql_runner/adapters/postgresql.rb', line 25

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

#disconnectObject



36
37
38
# File 'lib/sql_runner/adapters/postgresql.rb', line 36

def disconnect
  @connection&.close && (@connection = nil)
end

#execute(query, **bind_vars) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/sql_runner/adapters/postgresql.rb', line 45

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

#inspectObject



64
65
66
# File 'lib/sql_runner/adapters/postgresql.rb', line 64

def inspect
  to_s
end

#parse(query) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sql_runner/adapters/postgresql.rb', line 68

def parse(query)
  bindings = {}
  count = 0

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

    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

#reconnectObject



40
41
42
43
# File 'lib/sql_runner/adapters/postgresql.rb', line 40

def reconnect
  disconnect
  connect
end

#to_sObject



60
61
62
# File 'lib/sql_runner/adapters/postgresql.rb', line 60

def to_s
  %[#<#{self.class.name} #{format('0x00%x', (object_id << 1))}>]
end