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.



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

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

Instance Method Details

#create(token, object) ⇒ Object



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

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



337
338
339
340
# File 'lib/rack/state.rb', line 337

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

#read(token) ⇒ Object



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

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



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

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