potluck-postgres 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/potluck/postgres/version.rb +1 -1
- data/lib/potluck/postgres.rb +108 -94
- metadata +27 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3589dd2164df71a6b980010ec03dc41416932e611f9b4b4ec1af4eb6d242015
|
4
|
+
data.tar.gz: 77616c26926b0ef95615f775f06fae452e875c752fbe1f4d3acf26f46e059dd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69805ee76d46065bb43d7b9d986221616c5ea58448acebcfbdc239556d54a254ba02e5824563d4cf9114fed2e939b41117574c2d5eaf6cd4bb528d354d704adc
|
7
|
+
data.tar.gz: 9400d94168b212a455450a52a5b8160899b619cb8ad549b20f84b3446cbc72b23b25fed6699e2a13db2d5f31e16e68a4bf79b4748f1f709fef35f3027653b9d8
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/lib/potluck/postgres.rb
CHANGED
@@ -5,18 +5,14 @@ require('sequel')
|
|
5
5
|
require_relative('postgres/version')
|
6
6
|
|
7
7
|
module Potluck
|
8
|
-
|
9
|
-
# Error class used to wrap errors encountered while connecting to or setting up a database.
|
10
|
-
#
|
8
|
+
# Public: Error class used to wrap errors encountered while connecting to or setting up a database.
|
11
9
|
class PostgresError < ServiceError
|
12
10
|
attr_reader(:wrapped_error)
|
13
11
|
|
14
|
-
|
15
|
-
# Creates a new instance.
|
16
|
-
#
|
17
|
-
# * +message+ - Error message.
|
18
|
-
# * +wrapped_error+ - Original error that was rescued and is being wrapped by this one (optional).
|
12
|
+
# Public: Create a new instance.
|
19
13
|
#
|
14
|
+
# message - String error message.
|
15
|
+
# wrapped_error - Original Exception that was rescued and is being wrapped by this one.
|
20
16
|
def initialize(message, wrapped_error = nil)
|
21
17
|
super(message)
|
22
18
|
|
@@ -24,46 +20,91 @@ module Potluck
|
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
27
|
-
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# creation, as well as for utility methods such as database schema migration.
|
31
|
-
#
|
23
|
+
# Public: A Ruby interface for controlling and connecting to Postgres. Uses the Sequel gem to connect and
|
24
|
+
# perform automatic role and database creation, as well as for utility methods such as database schema
|
25
|
+
# migration.
|
32
26
|
class Postgres < Service
|
33
|
-
ROLE_NOT_FOUND_REGEX = /role .* does not exist
|
34
|
-
DATABASE_NOT_FOUND_REGEX = /database .* does not exist
|
27
|
+
ROLE_NOT_FOUND_REGEX = /role .* does not exist/
|
28
|
+
DATABASE_NOT_FOUND_REGEX = /database .* does not exist/
|
35
29
|
|
36
30
|
STARTING_UP_STRING = 'the database system is starting up'
|
37
|
-
|
31
|
+
STARTING_UP_TRIES = 30
|
38
32
|
|
39
33
|
CONNECTION_REFUSED_STRING = 'connection refused'
|
40
|
-
|
34
|
+
CONNECTION_REFUSED_TRIES = 3
|
41
35
|
|
42
36
|
attr_reader(:database)
|
43
37
|
|
44
|
-
|
45
|
-
# Creates a new instance.
|
38
|
+
# Public: Get the content of the launchctl plist file.
|
46
39
|
#
|
47
|
-
#
|
48
|
-
|
40
|
+
# Returns the String content.
|
41
|
+
def self.plist
|
42
|
+
dir = postgres_dir
|
43
|
+
|
44
|
+
super(
|
45
|
+
<<~XML
|
46
|
+
<key>EnvironmentVariables</key>
|
47
|
+
<dict>
|
48
|
+
<key>LC_ALL</key>
|
49
|
+
<string>C</string>
|
50
|
+
</dict>
|
51
|
+
<key>ProgramArguments</key>
|
52
|
+
<array>
|
53
|
+
<string>#{Potluck.config.homebrew_prefix}/opt/#{dir}/bin/postgres</string>
|
54
|
+
<string>-D</string>
|
55
|
+
<string>#{Potluck.config.homebrew_prefix}/var/#{dir}</string>
|
56
|
+
</array>
|
57
|
+
<key>WorkingDirectory</key>
|
58
|
+
<string>#{Potluck.config.homebrew_prefix}</string>
|
59
|
+
<key>StandardOutPath</key>
|
60
|
+
<string>#{Potluck.config.homebrew_prefix}/var/log/#{dir}.log</string>
|
61
|
+
<key>StandardErrorPath</key>
|
62
|
+
<string>#{Potluck.config.homebrew_prefix}/var/log/#{dir}.log</string>
|
63
|
+
XML
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Public: Get the directory of the latest Homebrew-installed Postgres version.
|
49
68
|
#
|
50
|
-
|
51
|
-
|
69
|
+
# Returns the String path.
|
70
|
+
# Raises PostgresError if no Homebrew Postgres installation is found.
|
71
|
+
def self.postgres_dir
|
72
|
+
versions = Dir[File.join(Potluck.config.homebrew_prefix, 'opt', 'postgresql@*')].sort_by do |path|
|
73
|
+
path.split('@').last.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
if versions.empty?
|
77
|
+
raise(PostgresError, 'No Postgres installation found (try running `brew install postgresql@X`)')
|
78
|
+
end
|
79
|
+
|
80
|
+
File.basename(versions.last)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Public: Create a new instance.
|
84
|
+
#
|
85
|
+
# config - Configuration Hash to pass to Sequel.connect.
|
86
|
+
# kwargs - Hash of keyword arguments to pass to Service.new.
|
87
|
+
def initialize(config, **kwargs)
|
88
|
+
super(**kwargs)
|
52
89
|
|
53
90
|
@config = config
|
54
91
|
end
|
55
92
|
|
56
|
-
|
57
|
-
# Disconnects and stops the Postgres process.
|
93
|
+
# Public: Disconnect and stop the Postgres process.
|
58
94
|
#
|
95
|
+
# Returns nothing.
|
59
96
|
def stop
|
60
97
|
disconnect
|
61
98
|
super
|
62
99
|
end
|
63
100
|
|
64
|
-
|
65
|
-
# Connects to the configured Postgres database.
|
101
|
+
# Public: Connect to the configured Postgres database.
|
66
102
|
#
|
103
|
+
# Returns nothing.
|
104
|
+
# Raises Sequel::DatabaseConnectionError if connecting fails.
|
105
|
+
# Raises PostgresError if role creation was attempted and failed.
|
106
|
+
# Raises PostgresError if database creation was attempted and failed.
|
107
|
+
# Raises PostgresError if permission grant was attempted and failed.
|
67
108
|
def connect
|
68
109
|
role_created = false
|
69
110
|
database_created = false
|
@@ -87,14 +128,12 @@ module Potluck
|
|
87
128
|
database_created = true
|
88
129
|
create_database
|
89
130
|
retry
|
90
|
-
elsif message.include?(STARTING_UP_STRING) && tries <
|
131
|
+
elsif message.include?(STARTING_UP_STRING) && tries < STARTING_UP_TRIES
|
91
132
|
sleep(1)
|
92
133
|
retry
|
93
|
-
elsif message.include?(CONNECTION_REFUSED_STRING) && tries <
|
134
|
+
elsif message.include?(CONNECTION_REFUSED_STRING) && tries < CONNECTION_REFUSED_TRIES
|
94
135
|
sleep(1)
|
95
136
|
retry
|
96
|
-
elsif message.include?(CONNECTION_REFUSED_STRING)
|
97
|
-
raise(PostgresError.new(e.message.strip, e))
|
98
137
|
else
|
99
138
|
raise
|
100
139
|
end
|
@@ -106,22 +145,27 @@ module Potluck
|
|
106
145
|
grant_permissions if role_created && !database_created
|
107
146
|
end
|
108
147
|
|
109
|
-
|
110
|
-
# Disconnects from the database if a connection was made.
|
148
|
+
# Public: Disconnect from the database if a connection was made.
|
111
149
|
#
|
150
|
+
# Returns nothing.
|
112
151
|
def disconnect
|
113
152
|
@database&.disconnect
|
114
153
|
end
|
115
154
|
|
116
|
-
|
117
|
-
#
|
118
|
-
# timestamp naming strategy as opposed to integers.
|
155
|
+
# Deprecated: Run database migrations by way of Sequel's migration extension. Migration files must use
|
156
|
+
# the timestamp naming strategy as opposed to integers.
|
119
157
|
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
158
|
+
# dir - String directory where migration files are located.
|
159
|
+
# steps - Integer number of steps forward or backward to migrate from the current migration (if omitted,
|
160
|
+
# will migrate forward to latest migration).
|
123
161
|
#
|
162
|
+
# Returns nothing.
|
124
163
|
def migrate(dir, steps = nil)
|
164
|
+
location = caller_locations(1, 1).first
|
165
|
+
|
166
|
+
warn("#{location.path}:#{location.lineno}: #{self.class.name}#migrate is deprecated and will be " \
|
167
|
+
"removed soon. Please use Sequel's migration extension directly instead.")
|
168
|
+
|
125
169
|
return unless File.directory?(dir)
|
126
170
|
|
127
171
|
Sequel.extension(:migration)
|
@@ -155,67 +199,34 @@ module Potluck
|
|
155
199
|
@logger.level = original_level if original_level
|
156
200
|
end
|
157
201
|
|
158
|
-
##
|
159
|
-
# Content of the launchctl plist file.
|
160
|
-
#
|
161
|
-
def self.plist
|
162
|
-
versions = Dir["#{HOMEBREW_PREFIX}/opt/postgresql@*"].sort_by { |path| path.split('@').last.to_f }
|
163
|
-
version =
|
164
|
-
if versions.empty?
|
165
|
-
raise(PostgresError, "No Postgres installation found (try running `brew install postgresql@X`)")
|
166
|
-
else
|
167
|
-
File.basename(versions.last)
|
168
|
-
end
|
169
|
-
|
170
|
-
super(
|
171
|
-
<<~EOS
|
172
|
-
<key>EnvironmentVariables</key>
|
173
|
-
<dict>
|
174
|
-
<key>LC_ALL</key>
|
175
|
-
<string>C</string>
|
176
|
-
</dict>
|
177
|
-
<key>ProgramArguments</key>
|
178
|
-
<array>
|
179
|
-
<string>#{HOMEBREW_PREFIX}/opt/#{version}/bin/postgres</string>
|
180
|
-
<string>-D</string>
|
181
|
-
<string>#{HOMEBREW_PREFIX}/var/#{version}</string>
|
182
|
-
</array>
|
183
|
-
<key>WorkingDirectory</key>
|
184
|
-
<string>#{HOMEBREW_PREFIX}</string>
|
185
|
-
<key>StandardOutPath</key>
|
186
|
-
<string>#{HOMEBREW_PREFIX}/var/log/#{version}.log</string>
|
187
|
-
<key>StandardErrorPath</key>
|
188
|
-
<string>#{HOMEBREW_PREFIX}/var/log/#{version}.log</string>
|
189
|
-
EOS
|
190
|
-
)
|
191
|
-
end
|
192
|
-
|
193
202
|
private
|
194
203
|
|
195
|
-
|
196
|
-
#
|
197
|
-
# configured role. Useful in development.
|
204
|
+
# Internal: Attempt to connect to the 'postgres' database as the system user with no password and create
|
205
|
+
# the configured role. Useful in development environments.
|
198
206
|
#
|
207
|
+
# Returns nothing.
|
208
|
+
# Raises PostgresError if the role could not be created.
|
199
209
|
def create_role
|
200
210
|
tmp_config = admin_database_config
|
201
211
|
tmp_config[:database] = 'postgres'
|
202
212
|
|
203
213
|
begin
|
204
214
|
Sequel.connect(tmp_config, logger: @logger) do |database|
|
205
|
-
database.execute("CREATE ROLE \"#{@config[:username]}\" WITH LOGIN CREATEDB REPLICATION"\
|
215
|
+
database.execute("CREATE ROLE \"#{@config[:username]}\" WITH LOGIN CREATEDB REPLICATION" \
|
206
216
|
"#{" PASSWORD '#{@config[:password]}'" if @config[:password]}")
|
207
217
|
end
|
208
218
|
rescue => e
|
209
|
-
raise(PostgresError.new("Failed to create database role #{@config[:username].inspect} by "\
|
210
|
-
"connecting to database #{tmp_config[:database].inspect} as role "\
|
219
|
+
raise(PostgresError.new("Failed to create database role #{@config[:username].inspect} by " \
|
220
|
+
"connecting to database #{tmp_config[:database].inspect} as role " \
|
211
221
|
"#{tmp_config[:username].inspect}. Please create the role manually.", e))
|
212
222
|
end
|
213
223
|
end
|
214
224
|
|
215
|
-
|
216
|
-
#
|
217
|
-
# configured database. Useful in development.
|
225
|
+
# Internal: Attempt to connect to the 'postgres' database with the configured user and password and
|
226
|
+
# create the configured database. Useful in development environments.
|
218
227
|
#
|
228
|
+
# Returns nothing.
|
229
|
+
# Raises PostgresError if the database could not be created.
|
219
230
|
def create_database
|
220
231
|
tmp_config = @config.dup
|
221
232
|
tmp_config[:database] = 'postgres'
|
@@ -225,15 +236,17 @@ module Potluck
|
|
225
236
|
database.execute("CREATE DATABASE \"#{@config[:database]}\"")
|
226
237
|
end
|
227
238
|
rescue => e
|
228
|
-
raise(PostgresError.new("Failed to create database #{@config[:database].inspect} by connecting
|
229
|
-
"database #{tmp_config[:database].inspect} as role #{tmp_config[:username].inspect}. "\
|
239
|
+
raise(PostgresError.new("Failed to create database #{@config[:database].inspect} by connecting " \
|
240
|
+
"to database #{tmp_config[:database].inspect} as role #{tmp_config[:username].inspect}. " \
|
230
241
|
'Please create the database manually.', e))
|
231
242
|
end
|
232
243
|
end
|
233
244
|
|
234
|
-
|
235
|
-
#
|
245
|
+
# Internal: Grant appropriate permissions for the configured database role. Useful in development
|
246
|
+
# environments.
|
236
247
|
#
|
248
|
+
# Returns nothing.
|
249
|
+
# Raises PostgresError if permissions could not be granted.
|
237
250
|
def grant_permissions
|
238
251
|
tmp_config = admin_database_config
|
239
252
|
|
@@ -241,23 +254,24 @@ module Potluck
|
|
241
254
|
Sequel.connect(tmp_config, logger: @logger) do |db|
|
242
255
|
db.execute("GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"#{@config[:username]}\"")
|
243
256
|
db.execute("GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \"#{@config[:username]}\"")
|
244
|
-
db.execute("ALTER DEFAULT PRIVILEGES FOR ROLE \"#{@config[:username]}\" IN SCHEMA public GRANT "\
|
257
|
+
db.execute("ALTER DEFAULT PRIVILEGES FOR ROLE \"#{@config[:username]}\" IN SCHEMA public GRANT " \
|
245
258
|
"ALL PRIVILEGES ON TABLES TO \"#{@config[:username]}\"")
|
246
259
|
end
|
247
260
|
rescue => e
|
248
|
-
raise(PostgresError.new(
|
249
|
-
"#{@config[:username].inspect} by connecting as role #{tmp_config[:username].inspect}. Please "\
|
261
|
+
raise(PostgresError.new('Failed to grant database permissions for role ' \
|
262
|
+
"#{@config[:username].inspect} by connecting as role #{tmp_config[:username].inspect}. Please " \
|
250
263
|
'grant appropriate permissions manually.', e))
|
251
264
|
end
|
252
265
|
end
|
253
266
|
|
254
|
-
|
255
|
-
#
|
256
|
-
#
|
267
|
+
# Internal: Return a configuration hash for connecting to Postgres to perform administrative tasks
|
268
|
+
# (role and database creation). Uses the system user as the username and no password. Useful in
|
269
|
+
# development environments
|
257
270
|
#
|
271
|
+
# Returns the configuration Hash.
|
258
272
|
def admin_database_config
|
259
273
|
config = @config.dup
|
260
|
-
config[:username] = ENV
|
274
|
+
config[:username] = ENV.fetch('USER')
|
261
275
|
config[:password] = nil
|
262
276
|
|
263
277
|
config
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: potluck-postgres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Pickens
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-19 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: potluck
|
@@ -16,14 +15,14 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - '='
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.0.
|
18
|
+
version: 0.0.8
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - '='
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.0.
|
25
|
+
version: 0.0.8
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: pg
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,26 +69,33 @@ dependencies:
|
|
70
69
|
name: minitest
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
72
71
|
requirements:
|
73
|
-
- - "
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 5.11.2
|
76
|
-
- - "<"
|
72
|
+
- - "~>"
|
77
73
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
74
|
+
version: '5.24'
|
79
75
|
type: :development
|
80
76
|
prerelease: false
|
81
77
|
version_requirements: !ruby/object:Gem::Requirement
|
82
78
|
requirements:
|
83
|
-
- - "
|
79
|
+
- - "~>"
|
84
80
|
- !ruby/object:Gem::Version
|
85
|
-
version: 5.
|
86
|
-
|
81
|
+
version: '5.24'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: minitest-reporters
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.7'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
87
94
|
- !ruby/object:Gem::Version
|
88
|
-
version:
|
95
|
+
version: '1.7'
|
89
96
|
description: An extension to the Potluck gem that provides some basic utilities for
|
90
97
|
setting up and connecting to Postgres databases, as well as control over the Postgres
|
91
98
|
process.
|
92
|
-
email:
|
93
99
|
executables: []
|
94
100
|
extensions: []
|
95
101
|
extra_rdoc_files: []
|
@@ -103,10 +109,9 @@ homepage: https://github.com/npickens/potluck/tree/master/potluck-postgres
|
|
103
109
|
licenses:
|
104
110
|
- MIT
|
105
111
|
metadata:
|
106
|
-
|
107
|
-
|
108
|
-
source_code_uri: https://github.com/npickens/potluck/tree/
|
109
|
-
post_install_message:
|
112
|
+
bug_tracker_uri: https://github.com/npickens/potluck/issues
|
113
|
+
documentation_uri: https://github.com/npickens/potluck/blob/0.0.8/potluck-postgres/README.md
|
114
|
+
source_code_uri: https://github.com/npickens/potluck/tree/0.0.8/potluck-postgres
|
110
115
|
rdoc_options: []
|
111
116
|
require_paths:
|
112
117
|
- lib
|
@@ -114,15 +119,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
119
|
requirements:
|
115
120
|
- - ">="
|
116
121
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
122
|
+
version: 3.0.0
|
118
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
124
|
requirements:
|
120
125
|
- - ">="
|
121
126
|
- !ruby/object:Gem::Version
|
122
|
-
version:
|
127
|
+
version: 2.0.0
|
123
128
|
requirements: []
|
124
|
-
rubygems_version: 3.
|
125
|
-
signing_key:
|
129
|
+
rubygems_version: 3.6.6
|
126
130
|
specification_version: 4
|
127
131
|
summary: A Ruby manager for Postgres.
|
128
132
|
test_files: []
|