Class: Pgtk::Pool

Inherits:
Object
  • Object
show all
Defined in:
lib/pgtk/pool.rb

Overview

Pool.

Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2019-2025 Yegor Bugayenko

License

MIT

Defined Under Namespace

Classes: Txn

Instance Method Summary collapse

Constructor Details

#initialize(wire, log: Loog::NULL) ⇒ Pool

Constructor.

Parameters:

  • wire (Pgtk::Wire)

    The wire

  • log (Object) (defaults to: Loog::NULL)

    The log



37
38
39
40
41
# File 'lib/pgtk/pool.rb', line 37

def initialize(wire, log: Loog::NULL)
  @wire = wire
  @log = log
  @pool = Queue.new
end

Instance Method Details

#exec(query, args = [], result = 0) {|Hash| ... } ⇒ Object

Make a query and return the result as an array of hashes. For example, in order to fetch the list of all books belonging to the user:

books = pool.exec('SELECT * FROM book WHERE owner = $1', ['yegor256'])
books.each do |row|
  puts 'ID: ' + row['id'].to_i
  puts 'Created: ' + Time.parse(row['created'])
  puts 'Title: ' + row['title']
end

All values in the retrieved hash are strings. No matter what types of of data you have in the database, you get strings here. It’s your job to convert them to the type you need.

In order to insert a new row (pay attention to the RETURNING clause at the end of the SQL query):

id = pool.exec(
  'INSERT INTO book (owner, title) VALUES ($1, $2) RETURNING id',
  ['yegor256', 'Elegant Objects']
)[0]['id'].to_i

You can also pass a block to this method, if you want to get an instance of PG::Result instead of an array of hashes:

pool.exec('SELECT * FROM book WHERE owner = $1', ['yegor256']) do |res|
  res.each do |row|
    puts 'ID: ' + row['id'].to_i
    puts 'Title: ' + row['title']
  end
end

When the query is too long it’s convenient to use an array to specify it:

pool.exec(
  [
    'SELECT * FROM book',
    'LEFT JOIN user ON user.id = book.owner',
    'WHERE user.login = $1 AND book.title = $2'
  ],
  ['yegor256', 'Elegant Objects']
)

More details about exec_params, which is called here, you can find here: www.rubydoc.info/gems/pg/0.17.1/PG%2FConnection:exec_params

Parameters:

  • query (String)

    The SQL query with params inside (possibly)

  • args (Array) (defaults to: [])

    List of arguments

  • result (Integer) (defaults to: 0)

    Should be 0 for text results, 1 for binary

Yields:

  • (Hash)

    Rows



116
117
118
119
120
121
122
123
124
125
# File 'lib/pgtk/pool.rb', line 116

def exec(query, args = [], result = 0, &block)
  connect do |c|
    t = Txn.new(c, @log)
    if block_given?
      t.exec(query, args, result, &block)
    else
      t.exec(query, args, result)
    end
  end
end

#start(max = 8) ⇒ Object

Start it with a fixed number of connections. The amount of connections is specified in max argument and should be big enough to handle the amount of parallel connections you may have to the database. However, keep in mind that not all servers will allow you to have many connections open at the same time. For example, Heroku free PostgreSQL database allows only one connection open.

Parameters:

  • max (Integer) (defaults to: 8)

    Total amount of PostgreSQL connections in the pool



58
59
60
61
62
63
64
# File 'lib/pgtk/pool.rb', line 58

def start(max = 8)
  max.times do
    @pool << @wire.connection
  end
  @log.debug("PostgreSQL pool started with #{max} connections")
  self
end

#transactionObject

Run a transaction. The block has to be provided. It will receive a temporary object, which implements method exec, which works exactly like the method exec of class Pool, for example:

pgsql.transaction do |t|
  t.exec('DELETE FROM user WHERE id = $1', [id])
  t.exec('INSERT INTO user (name) VALUES ($1)', [name])
end


135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/pgtk/pool.rb', line 135

def transaction
  connect do |c|
    t = Txn.new(c, @log)
    t.exec('START TRANSACTION')
    begin
      r = yield t
      t.exec('COMMIT')
      r
    rescue StandardError => e
      t.exec('ROLLBACK')
      raise e
    end
  end
end

#versionString

Get the version of PostgreSQL server.

Returns:

  • (String)

    Version of PostgreSQL server



46
47
48
# File 'lib/pgtk/pool.rb', line 46

def version
  @version ||= exec('SHOW server_version')[0]['server_version'].split[0]
end