Class: Potluck::Postgres
- Inherits:
-
Service
- Object
- Service
- Potluck::Postgres
- Defined in:
- lib/potluck/postgres.rb
Overview
A Ruby interface for controlling and connecting to Postgres. Uses [Sequel](github.com/jeremyevans/sequel) to connect and perform automatic role and database creation, as well as for utility methods such as database schema migration.
Constant Summary collapse
- ROLE_NOT_FOUND_REGEX =
/role .* does not exist/.freeze
- DATABASE_NOT_FOUND_REGEX =
/database .* does not exist/.freeze
- STARTING_UP_STRING =
'the database system is starting up'- STARTING_UP_TIMEOUT =
30- CONNECTION_REFUSED_STRING =
'connection refused'- CONNECTION_REFUSED_TIMEOUT =
3
Instance Attribute Summary collapse
-
#database ⇒ Object
readonly
Returns the value of attribute database.
Class Method Summary collapse
-
.plist ⇒ Object
Content of the launchctl plist file.
Instance Method Summary collapse
-
#connect ⇒ Object
Connects to the configured Postgres database.
-
#disconnect ⇒ Object
Disconnects from the database if a connection was made.
-
#initialize(config, **args) ⇒ Postgres
constructor
Creates a new instance.
-
#migrate(dir, steps = nil) ⇒ Object
Runs database migrations by way of Sequel’s migration extension.
-
#stop ⇒ Object
Disconnects and stops the Postgres process.
Constructor Details
#initialize(config, **args) ⇒ Postgres
Creates a new instance.
-
config- Configuration hash to pass toSequel.connect. -
args- Arguments to pass to Potluck::Service.new (optional).
49 50 51 52 53 |
# File 'lib/potluck/postgres.rb', line 49 def initialize(config, **args) super(**args) @config = config end |
Instance Attribute Details
#database ⇒ Object (readonly)
Returns the value of attribute database.
41 42 43 |
# File 'lib/potluck/postgres.rb', line 41 def database @database end |
Class Method Details
.plist ⇒ Object
Content of the launchctl plist file.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/potluck/postgres.rb', line 191 def self.plist super( <<~EOS <key>ProgramArguments</key> <array> <string>/usr/local/opt/postgresql/bin/postgres</string> <string>-D</string> <string>/usr/local/var/postgres</string> </array> <key>WorkingDirectory</key> <string>/usr/local</string> <key>StandardOutPath</key> <string>/usr/local/var/log/postgres.log</string> <key>StandardErrorPath</key> <string>/usr/local/var/log/postgres.log</string> EOS ) end |
Instance Method Details
#connect ⇒ Object
Connects to the configured Postgres database.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/potluck/postgres.rb', line 66 def connect (tries ||= 0) && (tries += 1) @database = Sequel.connect(@config, logger: @logger) rescue Sequel::DatabaseConnectionError => e if (dud = Sequel::DATABASES.last) dud.disconnect Sequel.synchronize { Sequel::DATABASES.delete(dud) } end = e..downcase if =~ ROLE_NOT_FOUND_REGEX && tries == 1 create_database_role create_database retry elsif =~ DATABASE_NOT_FOUND_REGEX && tries == 1 create_database retry elsif .include?(STARTING_UP_STRING) && tries < STARTING_UP_TIMEOUT sleep(1) retry elsif .include?(CONNECTION_REFUSED_STRING) && tries < CONNECTION_REFUSED_TIMEOUT && manage? sleep(1) retry elsif .include?(CONNECTION_REFUSED_STRING) raise(PostgresError.new(e..strip, e)) else raise end end |
#disconnect ⇒ Object
Disconnects from the database if a connection was made.
100 101 102 |
# File 'lib/potluck/postgres.rb', line 100 def disconnect @database&.disconnect end |
#migrate(dir, steps = nil) ⇒ Object
Runs database migrations by way of Sequel’s migration extension. Migration files must use the timestamp naming strategy as opposed to integers.
-
dir- Directory where migration files are located. -
steps- Number of steps forward or backward to migrate from the current migration, otherwise will migrate to latest (optional).
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/potluck/postgres.rb', line 112 def migrate(dir, steps = nil) return unless File.directory?(dir) Sequel.extension(:migration) # Suppress Sequel schema migration table queries. original_level = @logger.level @logger.level = Logger::WARN if @logger.level == Logger::INFO args = [Sequel::Model.db, dir, {allow_missing_migration_files: true}] migrator = Sequel::TimestampMigrator.new(*args) return if migrator.files.empty? if steps all = migrator.files.map { |f| File.basename(f) } applied = migrator.applied_migrations current = applied.last return if applied.empty? && steps <= 0 index = [[0, (all.index(current) || -1) + steps].max, all.size].min file = all[index] args.last[:target] = migrator.send(:migration_version_from_file, file) end migrator = Sequel::TimestampMigrator.new(*args) @logger.level = original_level migrator.run ensure @logger.level = original_level if original_level end |
#stop ⇒ Object
Disconnects and stops the Postgres process.
58 59 60 61 |
# File 'lib/potluck/postgres.rb', line 58 def stop disconnect super end |