module Keycard::DB
Module for database interactions for Keycard
.
Constants
- ALREADY_CONNECTED
- CONNECTION_ERROR
- LOAD_ERROR
- MISSING_CONFIG
- SCHEMA_HEADER
Public Class Methods
Forward the Sequel::Database []-syntax down to db for convenience. Everything else must be called on db directly, but this is nice sugar.
# File lib/keycard/db.rb, line 156 def [](*args) db[*args] end
# File lib/keycard/db.rb, line 136 def config @config ||= OpenStruct.new( url: ENV['KEYCARD_DATABASE_URL'] || ENV['DATABASE_URL'], readonly: false ) end
# File lib/keycard/db.rb, line 123 def conn_opts log = { logger: Logger.new('db/keycard.log') } url = config.url opts = config.opts if url [url, log] elsif opts [log.merge(opts)] else [] end end
Connect to the Keycard
database.
The default is to use the settings under {.config}, but can be supplied here (and they will be merged into config as a side effect). The keys that will be used from either source are documented here as the options.
Only one “mode” will be used; the first of these supplied will take precedence:
-
An already-connected {Sequel::Database} object
-
A connection string
-
A connection options hash
While Keycard
serves as a singleton, this will raise a DatabaseError
if already connected. Check `connected?` if you are unsure.
@see {Sequel.connect} @param [Hash] config Optional connection config @option config [String] :url A Sequel database URL @option config [Hash] :opts A set of connection options @option config [Sequel::Database] :db An already-connected database; @return [Sequel::Database] The initialized database connection
# File lib/keycard/db.rb, line 71 def connect!(config = {}) raise DatabaseError, ALREADY_CONNECTED if connected? merge_config!(config) raise DatabaseError, MISSING_CONFIG if self.config.db.nil? && conn_opts.empty? # We splat here because we might give one or two arguments depending # on whether we have a string or not; to add our logger regardless. @db = self.config.db || Sequel.connect(*conn_opts) end
# File lib/keycard/db.rb, line 143 def connected? !@db.nil? end
The Keycard
database @return [Sequel::Database] The connected database; be sure to call initialize! first.
# File lib/keycard/db.rb, line 149 def db raise DatabaseError, CONNECTION_ERROR unless connected? @db end
# File lib/keycard/db.rb, line 99 def dump_schema! connect! unless connected? version = db[schema_table].first.to_yaml File.write(schema_file, SCHEMA_HEADER + version) end
Initialize Keycard
This connects to the database if it has not already happened and requires all of the Keycard
model classes. It is required to do the connection setup first because of the design decision in Sequel that the schema is examined at the time of extending Sequel::Model.
# File lib/keycard/db.rb, line 36 def initialize! connect! unless connected? begin model_files.each do |file| require_relative file end rescue Sequel::DatabaseError, NoMethodError => e raise DatabaseError, LOAD_ERROR + "\n" + e.message end db end
# File lib/keycard/db.rb, line 105 def load_schema! connect! unless connected? version = YAML.load_file(schema_file)[:version] db[schema_table].delete db[schema_table].insert(version: version) end
Merge url, opts, or db settings from a hash into our config
# File lib/keycard/db.rb, line 117 def merge_config!(config = {}) self.config.url = config[:url] if config.key?(:url) self.config.opts = config[:opts] if config.key?(:opts) self.config.db = config[:db] if config.key?(:db) end
Run any pending migrations. This will connect with the current config if not already conencted.
# File lib/keycard/db.rb, line 83 def migrate! connect! unless connected? return if config.readonly Sequel.extension :migration Sequel::Migrator.run(db, File.join(__dir__, '../../db/migrations'), table: schema_table) end
# File lib/keycard/db.rb, line 112 def model_files [] end
# File lib/keycard/db.rb, line 95 def schema_file 'db/keycard.yml' end
# File lib/keycard/db.rb, line 91 def schema_table :keycard_schema end