potluck-postgres 0.0.5 → 0.0.7
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/LICENSE +1 -1
- data/VERSION +1 -0
- data/lib/potluck/postgres/version.rb +7 -0
- data/lib/potluck/postgres.rb +114 -58
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6484b446d1c719baef9d5aec6fc545d305107581c62335c33e9b30098f050ff7
|
4
|
+
data.tar.gz: a9b09e742ea51367296b898ca20c331830203eace33489e28e7820d3fe914cab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f1433d0ac8702cb655ce8e7dcdea53c1a196e27e6cce9619b7f79405028e6693565bcfda69d6ade2940950661fbc6b84fdb293aeb25a9462b8ae905550e122f
|
7
|
+
data.tar.gz: 4e7f3c780602ba4c62021b0611d9adf44b0dadb049c3ee448c20280141e78588ceff79b2876034af53c584a97349a902ab79df30f0b41fd1b1102c923b00d136
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2021 Nate Pickens
|
1
|
+
Copyright 2021-2022 Nate Pickens
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
4
|
documentation files (the "Software"), to deal in the Software without restriction, including without
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.7
|
data/lib/potluck/postgres.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require('potluck')
|
4
4
|
require('sequel')
|
5
|
+
require_relative('postgres/version')
|
5
6
|
|
6
7
|
module Potluck
|
7
8
|
##
|
@@ -64,34 +65,45 @@ module Potluck
|
|
64
65
|
# Connects to the configured Postgres database.
|
65
66
|
#
|
66
67
|
def connect
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
68
|
+
role_created = false
|
69
|
+
database_created = false
|
70
|
+
|
71
|
+
begin
|
72
|
+
(tries ||= 0) && (tries += 1)
|
73
|
+
@database = Sequel.connect(@config, logger: @logger)
|
74
|
+
rescue Sequel::DatabaseConnectionError => e
|
75
|
+
if (dud = Sequel::DATABASES.last)
|
76
|
+
dud.disconnect
|
77
|
+
Sequel.synchronize { Sequel::DATABASES.delete(dud) }
|
78
|
+
end
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
80
|
+
message = e.message.downcase
|
81
|
+
|
82
|
+
if message =~ ROLE_NOT_FOUND_REGEX && !role_created && manage?
|
83
|
+
role_created = true
|
84
|
+
create_role
|
85
|
+
retry
|
86
|
+
elsif message =~ DATABASE_NOT_FOUND_REGEX && !database_created && manage?
|
87
|
+
database_created = true
|
88
|
+
create_database
|
89
|
+
retry
|
90
|
+
elsif message.include?(STARTING_UP_STRING) && tries < STARTING_UP_TIMEOUT
|
91
|
+
sleep(1)
|
92
|
+
retry
|
93
|
+
elsif message.include?(CONNECTION_REFUSED_STRING) && tries < CONNECTION_REFUSED_TIMEOUT
|
94
|
+
sleep(1)
|
95
|
+
retry
|
96
|
+
elsif message.include?(CONNECTION_REFUSED_STRING)
|
97
|
+
raise(PostgresError.new(e.message.strip, e))
|
98
|
+
else
|
99
|
+
raise
|
100
|
+
end
|
94
101
|
end
|
102
|
+
|
103
|
+
# Only grant permissions if the database already existed but the role did not. Automatic database
|
104
|
+
# creation (via #create_database) is performed as the configured role, which means explicit permission
|
105
|
+
# granting is not necessary.
|
106
|
+
grant_permissions if role_created && !database_created
|
95
107
|
end
|
96
108
|
|
97
109
|
##
|
@@ -118,7 +130,7 @@ module Potluck
|
|
118
130
|
original_level = @logger.level
|
119
131
|
@logger.level = Logger::WARN if @logger.level == Logger::INFO
|
120
132
|
|
121
|
-
args = [
|
133
|
+
args = [@database, dir, {allow_missing_migration_files: true}]
|
122
134
|
migrator = Sequel::TimestampMigrator.new(*args)
|
123
135
|
|
124
136
|
return if migrator.files.empty?
|
@@ -130,7 +142,7 @@ module Potluck
|
|
130
142
|
|
131
143
|
return if applied.empty? && steps <= 0
|
132
144
|
|
133
|
-
index = [[0, (all.index(current) || -1) + steps].max, all.size].min
|
145
|
+
index = [[0, (all.index(current) || -1) + steps].max, all.size - 1].min
|
134
146
|
file = all[index]
|
135
147
|
|
136
148
|
args.last[:target] = migrator.send(:migration_version_from_file, file)
|
@@ -143,26 +155,60 @@ module Potluck
|
|
143
155
|
@logger.level = original_level if original_level
|
144
156
|
end
|
145
157
|
|
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
|
+
|
146
193
|
private
|
147
194
|
|
148
195
|
##
|
149
196
|
# Attempts to connect to the 'postgres' database as the system user with no password and create the
|
150
197
|
# configured role. Useful in development.
|
151
198
|
#
|
152
|
-
def
|
153
|
-
tmp_config =
|
199
|
+
def create_role
|
200
|
+
tmp_config = admin_database_config
|
154
201
|
tmp_config[:database] = 'postgres'
|
155
|
-
tmp_config[:username] = ENV['USER']
|
156
|
-
tmp_config[:password] = nil
|
157
202
|
|
158
203
|
begin
|
159
204
|
Sequel.connect(tmp_config, logger: @logger) do |database|
|
160
|
-
database.execute("CREATE ROLE #{@config[:username]} WITH LOGIN CREATEDB REPLICATION
|
161
|
-
"'#{@config[:password]}'")
|
205
|
+
database.execute("CREATE ROLE \"#{@config[:username]}\" WITH LOGIN CREATEDB REPLICATION"\
|
206
|
+
"#{" PASSWORD '#{@config[:password]}'" if @config[:password]}")
|
162
207
|
end
|
163
208
|
rescue => e
|
164
|
-
raise(PostgresError.new("
|
165
|
-
"
|
209
|
+
raise(PostgresError.new("Failed to create database role #{@config[:username].inspect} by "\
|
210
|
+
"connecting to database #{tmp_config[:database].inspect} as role "\
|
211
|
+
"#{tmp_config[:username].inspect}. Please create the role manually.", e))
|
166
212
|
end
|
167
213
|
end
|
168
214
|
|
@@ -176,35 +222,45 @@ module Potluck
|
|
176
222
|
|
177
223
|
begin
|
178
224
|
Sequel.connect(tmp_config, logger: @logger) do |database|
|
179
|
-
database.execute("CREATE DATABASE #{@config[:database]}")
|
225
|
+
database.execute("CREATE DATABASE \"#{@config[:database]}\"")
|
180
226
|
end
|
181
227
|
rescue => e
|
182
|
-
raise(PostgresError.new("
|
183
|
-
"
|
184
|
-
'manually.', e))
|
228
|
+
raise(PostgresError.new("Failed to create database #{@config[:database].inspect} by connecting to "\
|
229
|
+
"database #{tmp_config[:database].inspect} as role #{tmp_config[:username].inspect}. "\
|
230
|
+
'Please create the database manually.', e))
|
185
231
|
end
|
186
232
|
end
|
187
233
|
|
188
234
|
##
|
189
|
-
#
|
235
|
+
# Grants appropriate permissions for the configured database role.
|
190
236
|
#
|
191
|
-
def
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
237
|
+
def grant_permissions
|
238
|
+
tmp_config = admin_database_config
|
239
|
+
|
240
|
+
begin
|
241
|
+
Sequel.connect(tmp_config, logger: @logger) do |db|
|
242
|
+
db.execute("GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"#{@config[:username]}\"")
|
243
|
+
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 "\
|
245
|
+
"ALL PRIVILEGES ON TABLES TO \"#{@config[:username]}\"")
|
246
|
+
end
|
247
|
+
rescue => e
|
248
|
+
raise(PostgresError.new("Failed to grant database permissions for role "\
|
249
|
+
"#{@config[:username].inspect} by connecting as role #{tmp_config[:username].inspect}. Please "\
|
250
|
+
'grant appropriate permissions manually.', e))
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Returns a configuration hash for connecting to Postgres to perform administrative tasks (i.e. role and
|
256
|
+
# database creation). Uses the system user as the username and no password.
|
257
|
+
#
|
258
|
+
def admin_database_config
|
259
|
+
config = @config.dup
|
260
|
+
config[:username] = ENV['USER']
|
261
|
+
config[:password] = nil
|
262
|
+
|
263
|
+
config
|
208
264
|
end
|
209
265
|
end
|
210
266
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Pickens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: potluck
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.0.
|
19
|
+
version: 0.0.7
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.0.
|
26
|
+
version: 0.0.7
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,7 +96,9 @@ extra_rdoc_files: []
|
|
96
96
|
files:
|
97
97
|
- LICENSE
|
98
98
|
- README.md
|
99
|
+
- VERSION
|
99
100
|
- lib/potluck/postgres.rb
|
101
|
+
- lib/potluck/postgres/version.rb
|
100
102
|
homepage: https://github.com/npickens/potluck/tree/master/potluck-postgres
|
101
103
|
licenses:
|
102
104
|
- MIT
|
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
121
|
- !ruby/object:Gem::Version
|
120
122
|
version: '0'
|
121
123
|
requirements: []
|
122
|
-
rubygems_version: 3.
|
124
|
+
rubygems_version: 3.3.7
|
123
125
|
signing_key:
|
124
126
|
specification_version: 4
|
125
127
|
summary: A Ruby manager for Postgres.
|