class Rack::State::Store::Postgres

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

Constants

BINARY

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

Public Class Methods

new(connection, table = 'state') click to toggle source
connection

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

table

Table name where state is stored.

# File lib/rack/state.rb, line 333
def initialize(connection, table = 'state')
  @db = connection
  @table = table
end

Public Instance Methods

create(token, object) click to toggle source
# File lib/rack/state.rb, line 338
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) click to toggle source
# File lib/rack/state.rb, line 361
def delete(token)
  sql = "DELETE FROM #{@table} WHERE token = $1"
  @db.exec_params(sql, [token]).clear
end
read(token) click to toggle source
# File lib/rack/state.rb, line 346
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) click to toggle source
# File lib/rack/state.rb, line 353
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