Module: Keycard::DB
- Defined in:
- lib/keycard/db.rb
Overview
Module for database interactions for Keycard.
Defined Under Namespace
Classes: DatabaseError
Constant Summary collapse
- CONNECTION_ERROR =
'The Keycard database is not initialized. Call initialize! first.'
- ALREADY_CONNECTED =
'Already connected; refusing to connect to another database.'
- MISSING_CONFIG =
<<~MSG KEYCARD_DATABASE_URL and DATABASE_URL are both missing and a connection has not been configured. Cannot connect to the Keycard database. See Keycard::DB.connect! for help. MSG
- LOAD_ERROR =
<<~MSG Error loading Keycard database models. Verify connection information and that the database is migrated. MSG
- SCHEMA_HEADER =
"# Keycard Database Version\n"
Class Method Summary collapse
-
.[](*args) ⇒ Object
Forward the Sequel::Database []-syntax down to db for convenience.
- .config ⇒ Object
- .conn_opts ⇒ Object
-
.connect!(config = {}) ⇒ Sequel::Database
Connect to the Keycard database.
- .connected? ⇒ Boolean
-
.db ⇒ Sequel::Database
The Keycard database.
- .dump_schema! ⇒ Object
-
.initialize! ⇒ Object
Initialize Keycard.
- .load_schema! ⇒ Object
-
.merge_config!(config = {}) ⇒ Object
Merge url, opts, or db settings from a hash into our config.
-
.migrate! ⇒ Object
Run any pending migrations.
- .model_files ⇒ Object
- .schema_file ⇒ Object
- .schema_table ⇒ Object
Class Method Details
.[](*args) ⇒ Object
Forward the Sequel::Database []-syntax down to db for convenience. Everything else must be called on db directly, but this is nice sugar.
156 157 158 |
# File 'lib/keycard/db.rb', line 156 def [](*args) db[*args] end |
.config ⇒ Object
136 137 138 139 140 141 |
# File 'lib/keycard/db.rb', line 136 def config @config ||= OpenStruct.new( url: ENV['KEYCARD_DATABASE_URL'] || ENV['DATABASE_URL'], readonly: false ) end |
.conn_opts ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 |
# 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!(config = {}) ⇒ Sequel::Database
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.
71 72 73 74 75 76 77 78 79 |
# 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 |
.connected? ⇒ Boolean
143 144 145 |
# File 'lib/keycard/db.rb', line 143 def connected? !@db.nil? end |
.db ⇒ Sequel::Database
The Keycard database
149 150 151 152 |
# File 'lib/keycard/db.rb', line 149 def db raise DatabaseError, CONNECTION_ERROR unless connected? @db end |
.dump_schema! ⇒ Object
99 100 101 102 103 |
# 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! ⇒ Object
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.
36 37 38 39 40 41 42 43 44 45 46 |
# 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. end db end |
.load_schema! ⇒ Object
105 106 107 108 109 110 |
# 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_config!(config = {}) ⇒ Object
Merge url, opts, or db settings from a hash into our config
117 118 119 120 121 |
# 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 |
.migrate! ⇒ Object
Run any pending migrations. This will connect with the current config if not already conencted.
83 84 85 86 87 88 89 |
# 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 |
.model_files ⇒ Object
112 113 114 |
# File 'lib/keycard/db.rb', line 112 def model_files [] end |
.schema_file ⇒ Object
95 96 97 |
# File 'lib/keycard/db.rb', line 95 def schema_file 'db/keycard.yml' end |
.schema_table ⇒ Object
91 92 93 |
# File 'lib/keycard/db.rb', line 91 def schema_table :keycard_schema end |