class Ruboty::Brains::Postgres

Attributes

thread[R]

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/ruboty/brains/postgres.rb, line 17
def initialize
  super
  @thread = Thread.new { sync }
  @thread.abort_on_exception = true
end

Public Instance Methods

data() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 23
def data
  @data ||= load || {}
end
validate!() click to toggle source

Override.

Calls superclass method
# File lib/ruboty/brains/postgres.rb, line 28
def validate!
  super
  Ruboty.die("#{self.class.usage}") unless host
end

Private Instance Methods

botname() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 103
def botname
  ENV['POSTGRES_BOTNAME'] || 'ruboty'
end
connection() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 64
def connection
  if @connection.nil?
    @connection = PG::connect(
      host:     host,
      user:     user,
      password: password,
      dbname:   dbname,
      port:     port
    )
    migrate(@connection)
    prepare_save_and_load_statement(@connection)
  end
  @connection
end
dbname() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 95
def dbname
  ENV['POSTGRES_DBNAME'] || raise('ENV["POSTGRES_DBNAME"] is required.')
end
host() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 79
def host
  ENV['POSTGRES_HOST'] || 'localhost'
end
interval() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 107
def interval
  ENV['POSTGRES_SAVE_INTERVAL'].to_i || 10
end
load() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 40
def load
  result = connection.exec_prepared('load_statement', [botname])
  if result.count > 0
    Marshal.load(connection.unescape_bytea(result.first['marshal']))
  else
    str = connection.escape_bytea(Marshal.dump({}))
    sql = "INSERT INTO #{namespace} (botname, marshal) VALUES ($1, $2);"
    connection.prepare('insert_statement', sql)
    connection.exec_prepared('insert_statement', [botname, str])
    {}
  end
end
migrate(conn) click to toggle source
# File lib/ruboty/brains/postgres.rb, line 111
def migrate(conn)
  unless relation_exists?(conn)
    sql = "CREATE TABLE #{namespace} (botname VARCHAR(240) PRIMARY KEY, marshal BYTEA);"
    conn.exec(sql)
    load
  end
end
namespace() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 99
def namespace
  ENV['POSTGRES_NAMESPACE'] || 'ruboty'
end
password() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 91
def password
  ENV['POSTGRES_PASSWORD'] || raise('ENV["POSTGRES_PASSWORD"] is required.')
end
port() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 83
def port
  ENV['POSTGRES_PORT'] || 5432
end
prepare_save_and_load_statement(conn) click to toggle source

only this statment is called repeatedly

# File lib/ruboty/brains/postgres.rb, line 128
def prepare_save_and_load_statement(conn)
  conn.prepare('save_statement', "UPDATE #{namespace} SET marshal = $1 WHERE botname = $2;")
  conn.prepare('load_statement', "SELECT marshal FROM #{namespace} WHERE botname = $1;")
end
relation_exists?(conn) click to toggle source
# File lib/ruboty/brains/postgres.rb, line 119
def relation_exists?(conn)
  sql = "SELECT relname FROM pg_class WHERE relkind = 'r' AND relname = $1;"
  conn.prepare('exist_statement', sql)
  result = conn.exec_prepared('exist_statement', [namespace])
  return false if result.count == 0
  result.first['relname'] == namespace
end
save() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 35
def save
  str = connection.escape_bytea(Marshal.dump(data))
  connection.exec_prepared('save_statement', [str, botname])
end
sync() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 53
def sync
  loop do
    wait
    save
  end
end
user() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 87
def user
  ENV['POSTGRES_USER'] || raise('ENV["POSTGRES_USER"] is required.')
end
wait() click to toggle source
# File lib/ruboty/brains/postgres.rb, line 60
def wait
  sleep(interval)
end