Class: Rack::State::Store::Postgres

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/state.rb

Overview

Postgres table-based state storage adapter.

The following statement will create the required database table:

CREATE UNLOGGED TABLE state (
  token   varchar PRIMARY KEY,
  object  bytea NOT NULL,
  mtime   timestamp DEFAULT current_timestamp
)

The mtime timestamp column may be used for implementing state expiry external to this class. For example, the following statement could be piped to psql(1) daily via cron(8):

DELETE FROM state WHERE (mtime + interval '30d') < current_timestamp

Constant Summary collapse

BINARY =

Indicate binary data; the object is stored in binary format.

1

Instance Method Summary collapse

Constructor Details

#initialize(connection, table = 'state') ⇒ Postgres

connection

Instance of the database connection, e.g., PG::Connection.new

table

Table name where state is stored.



303
304
305
306
# File 'lib/rack/state.rb', line 303

def initialize(connection, table = 'state')
  @db = connection
  @table = table
end

Instance Method Details

#create(token, object) ⇒ Object



308
309
310
311
312
313
314
# File 'lib/rack/state.rb', line 308

def create(token, object)
  sql = "INSERT INTO #{@table} (token,object) VALUES ($1,$2)"
  params = [token, {value: ::Marshal.dump(object), format: BINARY}]
  @db.exec_params(sql, params).clear
rescue PG::UniqueViolation
  raise KeyError
end

#delete(token) ⇒ Object



331
332
333
334
# File 'lib/rack/state.rb', line 331

def delete(token)
  sql = "DELETE FROM #{@table} WHERE token = $1"
  @db.exec_params(sql, [token]).clear
end

#read(token) ⇒ Object



316
317
318
319
320
321
# File 'lib/rack/state.rb', line 316

def read(token)
  sql = "SELECT object FROM #{@table} WHERE token = $1"
  @db.exec_params(sql, [token], BINARY) do |result|
    ::Marshal.load result.getvalue(0,0)
  end rescue nil
end

#update(token, object) ⇒ Object



323
324
325
326
327
328
329
# File 'lib/rack/state.rb', line 323

def update(token, object)
  sql = "UPDATE #{@table} SET object = $2 WHERE token = $1"
  params = [token, {value: ::Marshal.dump(object), format: BINARY}]
  @db.exec_params(sql, params) do |result|
    raise KeyError if result.cmd_tuples == 0
  end
end