pg_objects 1.4.8 → 1.5.0
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/.github/workflows/ci.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +13 -2
- data/CHANGELOG.md +78 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +71 -54
- data/README.md +174 -3
- data/Rakefile +2 -0
- data/bin/benchmark +42 -7
- data/bin/console +1 -0
- data/lib/generators/pg_objects/install/install_generator.rb +2 -0
- data/lib/pg_objects/config.rb +53 -2
- data/lib/pg_objects/db_object.rb +6 -1
- data/lib/pg_objects/db_object_factory.rb +11 -3
- data/lib/pg_objects/logger.rb +34 -3
- data/lib/pg_objects/manager.rb +66 -15
- data/lib/pg_objects/parsed_object/aggregate.rb +9 -1
- data/lib/pg_objects/parsed_object/base.rb +38 -0
- data/lib/pg_objects/parsed_object/base_type.rb +17 -0
- data/lib/pg_objects/parsed_object/conversion.rb +9 -1
- data/lib/pg_objects/parsed_object/domain.rb +16 -0
- data/lib/pg_objects/parsed_object/enum_type.rb +16 -0
- data/lib/pg_objects/parsed_object/event_trigger.rb +3 -1
- data/lib/pg_objects/parsed_object/extension.rb +10 -0
- data/lib/pg_objects/parsed_object/function.rb +9 -1
- data/lib/pg_objects/parsed_object/index.rb +17 -0
- data/lib/pg_objects/parsed_object/materialized_view.rb +9 -1
- data/lib/pg_objects/parsed_object/operator.rb +9 -1
- data/lib/pg_objects/parsed_object/operator_class.rb +9 -1
- data/lib/pg_objects/parsed_object/policy.rb +10 -0
- data/lib/pg_objects/parsed_object/range_type.rb +16 -0
- data/lib/pg_objects/parsed_object/rule.rb +10 -0
- data/lib/pg_objects/parsed_object/sequence.rb +16 -0
- data/lib/pg_objects/parsed_object/table.rb +9 -1
- data/lib/pg_objects/parsed_object/text_search_parser.rb +9 -1
- data/lib/pg_objects/parsed_object/text_search_template.rb +9 -1
- data/lib/pg_objects/parsed_object/trigger.rb +3 -1
- data/lib/pg_objects/parsed_object/type.rb +9 -1
- data/lib/pg_objects/parsed_object/view.rb +9 -1
- data/lib/pg_objects/parsed_object.rb +11 -0
- data/lib/pg_objects/parsed_object_factory.rb +52 -90
- data/lib/pg_objects/parser.rb +28 -12
- data/lib/pg_objects/railtie.rb +2 -0
- data/lib/pg_objects/version.rb +3 -1
- data/lib/pg_objects/yaml_configurable.rb +25 -7
- data/lib/pg_objects.rb +54 -4
- data/lib/tasks/pg_objects_tasks.rake +33 -8
- data/pg_objects.gemspec +5 -3
- metadata +16 -20
- data/.github/copilot-instructions.md +0 -131
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1807b3da6b645e40097e8bc76bba2681eba9550b4e0312d2b815e106760afa7d
|
|
4
|
+
data.tar.gz: 12782fe9f8582bf759646c86a2dbfa8fecffab4afc027aea744e11640db389e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 01b441d4ba5a5dcbb8d753a5550785a8a67de5a97dcf3f94acb58cbe1925885c32a942c6d28a631188d4654f57ec4324795761dca02d32f3385af374d3cca6eb
|
|
7
|
+
data.tar.gz: a20c356f384c0eed96665aa535d33e3521aec5cbdfd13fd486b027427629094d54de8c62b700e2b13513c744f174ae0041fda053224c00d5533a54a211418e97
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -8,7 +8,7 @@ inherit_from: .rubocop_todo.yml
|
|
|
8
8
|
|
|
9
9
|
AllCops:
|
|
10
10
|
# EnabledByDefault: true
|
|
11
|
-
TargetRubyVersion: 3.
|
|
11
|
+
TargetRubyVersion: 3.3
|
|
12
12
|
# Cop names are not displayed in offense messages by default. Change behavior
|
|
13
13
|
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
|
|
14
14
|
# option.
|
|
@@ -186,6 +186,11 @@ RSpec/SpecFilePathFormat:
|
|
|
186
186
|
RSpec/SpecFilePathSuffix:
|
|
187
187
|
Enabled: true
|
|
188
188
|
|
|
189
|
+
# Integration specs describe cross-class behaviour, not a single class
|
|
190
|
+
RSpec/DescribeClass:
|
|
191
|
+
Exclude:
|
|
192
|
+
- 'spec/integration/**/*'
|
|
193
|
+
|
|
189
194
|
# Style #######################################################################
|
|
190
195
|
|
|
191
196
|
Style/AccessorGrouping:
|
|
@@ -217,11 +222,17 @@ Style/ExponentialNotation:
|
|
|
217
222
|
|
|
218
223
|
# Checks if there is a magic comment to enforce string literals
|
|
219
224
|
Style/FrozenStringLiteralComment:
|
|
220
|
-
Enabled:
|
|
225
|
+
Enabled: true
|
|
226
|
+
EnforcedStyle: always
|
|
221
227
|
|
|
222
228
|
Style/HashAsLastArrayItem:
|
|
223
229
|
Enabled: true
|
|
224
230
|
|
|
231
|
+
# Use explicit named block arguments instead of numbered parameters (_1)
|
|
232
|
+
Style/NumberedParameters:
|
|
233
|
+
EnforcedStyle: disallow
|
|
234
|
+
Enabled: true
|
|
235
|
+
|
|
225
236
|
Style/HashEachMethods:
|
|
226
237
|
Enabled: true
|
|
227
238
|
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.5.0] - 2026-07-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Multi-database support: `Manager` accepts a `connection:` argument, and the
|
|
15
|
+
rake tasks resolve a connection class from the `PG_OBJECTS_CONNECTION_CLASS`
|
|
16
|
+
environment variable ([#296](https://github.com/marinazzio/pg_objects/issues/296))
|
|
17
|
+
- New parsed object types: enum, range, base and shell `TYPE` variants,
|
|
18
|
+
`DOMAIN` ([#299](https://github.com/marinazzio/pg_objects/issues/299)),
|
|
19
|
+
`EXTENSION`, `INDEX`, `POLICY`, `RULE`, `SEQUENCE`
|
|
20
|
+
([#300](https://github.com/marinazzio/pg_objects/issues/300))
|
|
21
|
+
- Schema-qualified object names (`schema.name`) recognized in `--!depends_on`
|
|
22
|
+
directives for unambiguous dependency resolution
|
|
23
|
+
- Manual `db:create_objects:before` / `db:create_objects:after` rake tasks and
|
|
24
|
+
the `auto_hook_migrations` / `hook_tasks` settings controlling migration hooks
|
|
25
|
+
- `transactional` setting wrapping each run in a single database transaction
|
|
26
|
+
- Logger severity levels (`info`, `warn`, `error`) with an injectable output
|
|
27
|
+
stream; `error` messages print even in silent mode
|
|
28
|
+
([#308](https://github.com/marinazzio/pg_objects/issues/308))
|
|
29
|
+
- `MalformedStatementError` for statements whose object name cannot be extracted
|
|
30
|
+
- README sections on supported object types, multiple databases, and re-run
|
|
31
|
+
idempotency patterns ([#307](https://github.com/marinazzio/pg_objects/issues/307))
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Dependency errors now carry context: `CyclicDependencyError#cycle_path`
|
|
36
|
+
(full A → B → A chain), `AmbiguousDependencyError#candidates`/`#referrer`,
|
|
37
|
+
`DependencyNotExistError#referrer`
|
|
38
|
+
([#301](https://github.com/marinazzio/pg_objects/issues/301),
|
|
39
|
+
[#302](https://github.com/marinazzio/pg_objects/issues/302),
|
|
40
|
+
[#303](https://github.com/marinazzio/pg_objects/issues/303))
|
|
41
|
+
- YAML configuration loading is deferred to first config access and resolved
|
|
42
|
+
against `Rails.root` when available, fixing preloader/CWD issues
|
|
43
|
+
([#304](https://github.com/marinazzio/pg_objects/issues/304))
|
|
44
|
+
- Object files are loaded in sorted path order, and the object list is reset on
|
|
45
|
+
each `load_files` call
|
|
46
|
+
- Statement type dispatch refactored from a Try chain to a hash lookup
|
|
47
|
+
|
|
48
|
+
## [1.4.8] - 2026-05-15
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- Mutation testing (Evilution) development configuration
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Dependency updates
|
|
57
|
+
|
|
58
|
+
## [1.4.7] - 2026-02-07
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- Dependency updates (notably pg_query 6.2.2 in the development lockfile)
|
|
63
|
+
|
|
64
|
+
## [1.4.6] - 2026-01-21
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- Ruby 4 support
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- Dependency updates
|
|
73
|
+
|
|
74
|
+
[Unreleased]: https://github.com/marinazzio/pg_objects/compare/v1.5.0...HEAD
|
|
75
|
+
[1.5.0]: https://github.com/marinazzio/pg_objects/compare/v1.4.8...v1.5.0
|
|
76
|
+
[1.4.8]: https://github.com/marinazzio/pg_objects/compare/v1.4.7...v1.4.8
|
|
77
|
+
[1.4.7]: https://github.com/marinazzio/pg_objects/compare/v1.4.6...v1.4.7
|
|
78
|
+
[1.4.6]: https://github.com/marinazzio/pg_objects/compare/v1.4.5...v1.4.6
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
pg_objects (1.
|
|
4
|
+
pg_objects (1.5.0)
|
|
5
5
|
activerecord (>= 6.1.7.0, < 9)
|
|
6
6
|
dry-auto_inject (~> 1)
|
|
7
7
|
dry-configurable (~> 1)
|
|
8
|
-
dry-container (
|
|
9
|
-
dry-monads (~> 1.6)
|
|
8
|
+
dry-container (~> 0.11)
|
|
10
9
|
memery (>= 1.5, < 1.9)
|
|
11
10
|
pg_query (>= 5, < 7)
|
|
12
11
|
railties (>= 4, < 9)
|
|
@@ -54,7 +53,7 @@ GEM
|
|
|
54
53
|
base64 (0.3.0)
|
|
55
54
|
benchmark (0.5.0)
|
|
56
55
|
bigdecimal (4.1.2)
|
|
57
|
-
binding_of_caller (
|
|
56
|
+
binding_of_caller (2.0.0)
|
|
58
57
|
debug_inspector (>= 1.2.0)
|
|
59
58
|
builder (3.3.0)
|
|
60
59
|
bundler-audit (0.9.3)
|
|
@@ -63,18 +62,17 @@ GEM
|
|
|
63
62
|
byebug (13.0.0)
|
|
64
63
|
reline (>= 0.6.0)
|
|
65
64
|
coderay (1.1.3)
|
|
66
|
-
concurrent-ruby (1.3.
|
|
65
|
+
concurrent-ruby (1.3.7)
|
|
67
66
|
connection_pool (3.0.2)
|
|
68
|
-
crass (1.0.
|
|
69
|
-
date (3.5.1)
|
|
67
|
+
crass (1.0.7)
|
|
70
68
|
debug_inspector (1.2.0)
|
|
71
69
|
diff-lcs (1.6.2)
|
|
72
70
|
drb (2.2.3)
|
|
73
|
-
dry-auto_inject (1.1
|
|
71
|
+
dry-auto_inject (1.2.1)
|
|
74
72
|
dry-core (~> 1.1)
|
|
75
73
|
zeitwerk (~> 2.6)
|
|
76
|
-
dry-configurable (1.
|
|
77
|
-
dry-core (~> 1.
|
|
74
|
+
dry-configurable (1.4.0)
|
|
75
|
+
dry-core (~> 1.0)
|
|
78
76
|
zeitwerk (~> 2.6)
|
|
79
77
|
dry-container (0.11.0)
|
|
80
78
|
concurrent-ruby (~> 1.0)
|
|
@@ -82,29 +80,44 @@ GEM
|
|
|
82
80
|
concurrent-ruby (~> 1.0)
|
|
83
81
|
logger
|
|
84
82
|
zeitwerk (~> 2.6)
|
|
85
|
-
|
|
86
|
-
concurrent-ruby (~> 1.0)
|
|
87
|
-
dry-core (~> 1.1)
|
|
88
|
-
zeitwerk (~> 2.6)
|
|
89
|
-
erb (6.0.1.1)
|
|
83
|
+
erb (6.0.4)
|
|
90
84
|
erubi (1.13.1)
|
|
91
85
|
faker (3.8.0)
|
|
92
86
|
i18n (>= 1.8.11, < 2)
|
|
93
|
-
google-protobuf (4.
|
|
87
|
+
google-protobuf (4.35.1)
|
|
88
|
+
bigdecimal
|
|
89
|
+
rake (~> 13.3)
|
|
90
|
+
google-protobuf (4.35.1-aarch64-linux-gnu)
|
|
91
|
+
bigdecimal
|
|
92
|
+
rake (~> 13.3)
|
|
93
|
+
google-protobuf (4.35.1-aarch64-linux-musl)
|
|
94
94
|
bigdecimal
|
|
95
|
-
rake (
|
|
96
|
-
|
|
95
|
+
rake (~> 13.3)
|
|
96
|
+
google-protobuf (4.35.1-arm64-darwin)
|
|
97
|
+
bigdecimal
|
|
98
|
+
rake (~> 13.3)
|
|
99
|
+
google-protobuf (4.35.1-x86_64-darwin)
|
|
100
|
+
bigdecimal
|
|
101
|
+
rake (~> 13.3)
|
|
102
|
+
google-protobuf (4.35.1-x86_64-linux-gnu)
|
|
103
|
+
bigdecimal
|
|
104
|
+
rake (~> 13.3)
|
|
105
|
+
google-protobuf (4.35.1-x86_64-linux-musl)
|
|
106
|
+
bigdecimal
|
|
107
|
+
rake (~> 13.3)
|
|
108
|
+
i18n (1.15.2)
|
|
97
109
|
concurrent-ruby (~> 1.0)
|
|
98
110
|
io-console (0.8.2)
|
|
99
|
-
irb (1.
|
|
111
|
+
irb (1.18.0)
|
|
100
112
|
pp (>= 0.6.0)
|
|
113
|
+
prism (>= 1.3.0)
|
|
101
114
|
rdoc (>= 4.0.0)
|
|
102
115
|
reline (>= 0.4.2)
|
|
103
|
-
json (2.
|
|
104
|
-
language_server-protocol (3.17.0.
|
|
116
|
+
json (2.21.1)
|
|
117
|
+
language_server-protocol (3.17.0.6)
|
|
105
118
|
lint_roller (1.1.0)
|
|
106
119
|
logger (1.7.0)
|
|
107
|
-
loofah (2.25.
|
|
120
|
+
loofah (2.25.2)
|
|
108
121
|
crass (~> 1.0.2)
|
|
109
122
|
nokogiri (>= 1.12.0)
|
|
110
123
|
memery (1.8.0)
|
|
@@ -112,29 +125,29 @@ GEM
|
|
|
112
125
|
minitest (6.0.6)
|
|
113
126
|
drb (~> 2.0)
|
|
114
127
|
prism (~> 1.5)
|
|
115
|
-
nokogiri (1.19.
|
|
128
|
+
nokogiri (1.19.4-aarch64-linux-gnu)
|
|
116
129
|
racc (~> 1.4)
|
|
117
|
-
nokogiri (1.19.
|
|
130
|
+
nokogiri (1.19.4-aarch64-linux-musl)
|
|
118
131
|
racc (~> 1.4)
|
|
119
|
-
nokogiri (1.19.
|
|
132
|
+
nokogiri (1.19.4-arm-linux-gnu)
|
|
120
133
|
racc (~> 1.4)
|
|
121
|
-
nokogiri (1.19.
|
|
134
|
+
nokogiri (1.19.4-arm-linux-musl)
|
|
122
135
|
racc (~> 1.4)
|
|
123
|
-
nokogiri (1.19.
|
|
136
|
+
nokogiri (1.19.4-arm64-darwin)
|
|
124
137
|
racc (~> 1.4)
|
|
125
|
-
nokogiri (1.19.
|
|
138
|
+
nokogiri (1.19.4-x86_64-darwin)
|
|
126
139
|
racc (~> 1.4)
|
|
127
|
-
nokogiri (1.19.
|
|
140
|
+
nokogiri (1.19.4-x86_64-linux-gnu)
|
|
128
141
|
racc (~> 1.4)
|
|
129
|
-
nokogiri (1.19.
|
|
142
|
+
nokogiri (1.19.4-x86_64-linux-musl)
|
|
130
143
|
racc (~> 1.4)
|
|
131
|
-
parallel (1.
|
|
144
|
+
parallel (2.1.0)
|
|
132
145
|
parser (3.3.11.1)
|
|
133
146
|
ast (~> 2.4.1)
|
|
134
147
|
racc
|
|
135
148
|
pg_query (6.2.2)
|
|
136
149
|
google-protobuf (>= 3.25.3)
|
|
137
|
-
pp (0.6.
|
|
150
|
+
pp (0.6.4)
|
|
138
151
|
prettyprint
|
|
139
152
|
prettyprint (0.2.0)
|
|
140
153
|
prism (1.9.0)
|
|
@@ -149,9 +162,6 @@ GEM
|
|
|
149
162
|
pry-byebug (3.12.0)
|
|
150
163
|
byebug (~> 13.0)
|
|
151
164
|
pry (>= 0.13, < 0.17)
|
|
152
|
-
psych (5.3.1)
|
|
153
|
-
date
|
|
154
|
-
stringio
|
|
155
165
|
racc (1.8.1)
|
|
156
166
|
rack (3.2.6)
|
|
157
167
|
rack-session (2.1.2)
|
|
@@ -165,8 +175,8 @@ GEM
|
|
|
165
175
|
activesupport (>= 5.0.0)
|
|
166
176
|
minitest
|
|
167
177
|
nokogiri (>= 1.6)
|
|
168
|
-
rails-html-sanitizer (1.
|
|
169
|
-
loofah (~> 2.
|
|
178
|
+
rails-html-sanitizer (1.7.1)
|
|
179
|
+
loofah (~> 2.25, >= 2.25.2)
|
|
170
180
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
171
181
|
railties (8.1.3)
|
|
172
182
|
actionpack (= 8.1.3)
|
|
@@ -181,14 +191,20 @@ GEM
|
|
|
181
191
|
rake (13.4.2)
|
|
182
192
|
rake-hooks (1.2.3)
|
|
183
193
|
rake
|
|
184
|
-
|
|
194
|
+
rbs (4.0.3)
|
|
195
|
+
logger
|
|
196
|
+
prism (>= 1.6.0)
|
|
197
|
+
tsort
|
|
198
|
+
rdoc (8.0.0)
|
|
185
199
|
erb
|
|
186
|
-
|
|
200
|
+
prism (>= 1.6.0)
|
|
201
|
+
rbs (>= 4.0.0)
|
|
187
202
|
tsort
|
|
188
203
|
regexp_parser (2.12.0)
|
|
189
204
|
reline (0.6.3)
|
|
190
205
|
io-console (~> 0.5)
|
|
191
|
-
rouge (
|
|
206
|
+
rouge (5.0.0)
|
|
207
|
+
strscan (~> 3.1)
|
|
192
208
|
rspec (3.13.2)
|
|
193
209
|
rspec-core (~> 3.13.0)
|
|
194
210
|
rspec-expectations (~> 3.13.0)
|
|
@@ -198,23 +214,23 @@ GEM
|
|
|
198
214
|
rspec-expectations (3.13.5)
|
|
199
215
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
200
216
|
rspec-support (~> 3.13.0)
|
|
201
|
-
rspec-mocks (3.13.
|
|
217
|
+
rspec-mocks (3.13.8)
|
|
202
218
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
203
219
|
rspec-support (~> 3.13.0)
|
|
204
220
|
rspec-parameterized (2.0.1)
|
|
205
221
|
rspec-parameterized-core (>= 2, < 3)
|
|
206
222
|
rspec-parameterized-table_syntax (>= 2, < 3)
|
|
207
|
-
rspec-parameterized-core (2.0.
|
|
223
|
+
rspec-parameterized-core (2.0.2)
|
|
208
224
|
parser
|
|
209
225
|
prism
|
|
210
226
|
proc_to_ast (>= 0.2.0)
|
|
211
227
|
rspec (>= 2.13, < 4)
|
|
212
228
|
unparser
|
|
213
|
-
rspec-parameterized-table_syntax (2.1.
|
|
214
|
-
binding_of_caller
|
|
229
|
+
rspec-parameterized-table_syntax (2.1.1)
|
|
230
|
+
binding_of_caller (>= 2)
|
|
215
231
|
rspec-parameterized-core (>= 2, < 3)
|
|
216
|
-
rspec-support (3.13.
|
|
217
|
-
rubocop (1.
|
|
232
|
+
rspec-support (3.13.7)
|
|
233
|
+
rubocop (1.88.2)
|
|
218
234
|
json (~> 2.3)
|
|
219
235
|
language_server-protocol (~> 3.17.0.2)
|
|
220
236
|
lint_roller (~> 1.1.0)
|
|
@@ -225,10 +241,10 @@ GEM
|
|
|
225
241
|
rubocop-ast (>= 1.49.0, < 2.0)
|
|
226
242
|
ruby-progressbar (~> 1.7)
|
|
227
243
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
228
|
-
rubocop-ast (1.
|
|
244
|
+
rubocop-ast (1.50.0)
|
|
229
245
|
parser (>= 3.3.7.2)
|
|
230
246
|
prism (~> 1.7)
|
|
231
|
-
rubocop-rails (2.
|
|
247
|
+
rubocop-rails (2.36.0)
|
|
232
248
|
activesupport (>= 4.2.0)
|
|
233
249
|
lint_roller (~> 1.1)
|
|
234
250
|
rack (>= 1.1)
|
|
@@ -237,12 +253,13 @@ GEM
|
|
|
237
253
|
rubocop-rake (0.7.1)
|
|
238
254
|
lint_roller (~> 1.1)
|
|
239
255
|
rubocop (>= 1.72.1)
|
|
240
|
-
rubocop-rspec (3.
|
|
256
|
+
rubocop-rspec (3.10.2)
|
|
241
257
|
lint_roller (~> 1.1)
|
|
242
|
-
|
|
258
|
+
regexp_parser (>= 2.0)
|
|
259
|
+
rubocop (~> 1.86, >= 1.86.2)
|
|
243
260
|
ruby-progressbar (1.13.0)
|
|
244
261
|
securerandom (0.4.1)
|
|
245
|
-
|
|
262
|
+
strscan (3.1.8)
|
|
246
263
|
thor (1.5.0)
|
|
247
264
|
timeout (0.6.1)
|
|
248
265
|
tsort (0.2.0)
|
|
@@ -251,13 +268,13 @@ GEM
|
|
|
251
268
|
unicode-display_width (3.2.0)
|
|
252
269
|
unicode-emoji (~> 4.1)
|
|
253
270
|
unicode-emoji (4.2.0)
|
|
254
|
-
unparser (0.
|
|
255
|
-
diff-lcs (
|
|
271
|
+
unparser (0.9.0)
|
|
272
|
+
diff-lcs (>= 1.6, < 3)
|
|
256
273
|
parser (>= 3.3.0)
|
|
257
274
|
prism (>= 1.5.1)
|
|
258
275
|
uri (1.1.1)
|
|
259
276
|
useragent (0.16.11)
|
|
260
|
-
zeitwerk (2.
|
|
277
|
+
zeitwerk (2.8.2)
|
|
261
278
|
|
|
262
279
|
PLATFORMS
|
|
263
280
|
aarch64-linux
|
data/README.md
CHANGED
|
@@ -32,6 +32,18 @@ Run the installation procedure to initialize directories structure and configura
|
|
|
32
32
|
bundle exec rails generate pg_objects:install
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
## Supported object types
|
|
36
|
+
|
|
37
|
+
The following `CREATE` statements are recognized as manageable objects:
|
|
38
|
+
|
|
39
|
+
`AGGREGATE`, `CONVERSION`, `DOMAIN`, `EVENT TRIGGER`, `EXTENSION`, `FUNCTION`,
|
|
40
|
+
`INDEX`, `MATERIALIZED VIEW`, `OPERATOR`, `OPERATOR CLASS`, `POLICY`, `RULE`,
|
|
41
|
+
`SEQUENCE`, `TABLE`, `TEXT SEARCH PARSER`, `TEXT SEARCH TEMPLATE`, `TRIGGER`,
|
|
42
|
+
`TYPE` (composite, enum, range, base, and shell forms), `VIEW`.
|
|
43
|
+
|
|
44
|
+
Files containing any other statement raise
|
|
45
|
+
`PgObjects::UnknownObjectTypeError` during loading.
|
|
46
|
+
|
|
35
47
|
## Usage
|
|
36
48
|
|
|
37
49
|
Store DB objects as CREATE (or CREATE OR UPDATE) queries in files within a directory structure (default: *db/objects*).
|
|
@@ -46,6 +58,21 @@ CREATE FUNCTION my_func()
|
|
|
46
58
|
|
|
47
59
|
The string after the directive should be the name of the file that the dependency refers to, without the file extension.
|
|
48
60
|
|
|
61
|
+
### Directive syntax
|
|
62
|
+
|
|
63
|
+
- The directive must start the line — no leading whitespace.
|
|
64
|
+
- Both `--!` (SQL comment) and `#!` prefixes are supported.
|
|
65
|
+
- List several dependencies on one line, separated by commas and/or whitespace,
|
|
66
|
+
or use a separate directive line for each:
|
|
67
|
+
|
|
68
|
+
```sql
|
|
69
|
+
--!depends_on func_a, func_b, func_c
|
|
70
|
+
--!depends_on func_d
|
|
71
|
+
#!depends_on func_e
|
|
72
|
+
CREATE FUNCTION my_func()
|
|
73
|
+
...
|
|
74
|
+
```
|
|
75
|
+
|
|
49
76
|
## Configuration
|
|
50
77
|
|
|
51
78
|
You have the option to configure the gem using either a YAML file or a Ruby initializer. The priority order for configuration is as follows:
|
|
@@ -55,7 +82,13 @@ You have the option to configure the gem using either a YAML file or a Ruby init
|
|
|
55
82
|
|
|
56
83
|
### YAML
|
|
57
84
|
|
|
58
|
-
Create `pg_objects.yml` in the application *config* directory
|
|
85
|
+
Create `pg_objects.yml` in the application *config* directory.
|
|
86
|
+
|
|
87
|
+
The file is loaded on first configuration access and resolved against
|
|
88
|
+
`Rails.root` in Rails applications, so it is found even when the gem is
|
|
89
|
+
required before the process changes into the app root (e.g. under the Spring
|
|
90
|
+
preloader). Outside Rails the path is relative to the current working
|
|
91
|
+
directory.
|
|
59
92
|
|
|
60
93
|
```yaml
|
|
61
94
|
# pg_objects.yml
|
|
@@ -70,8 +103,18 @@ extensions:
|
|
|
70
103
|
- sql
|
|
71
104
|
- txt
|
|
72
105
|
|
|
73
|
-
#
|
|
106
|
+
# Suppress non-error output to console (error messages are always printed)
|
|
74
107
|
silent: false
|
|
108
|
+
|
|
109
|
+
# Whether to wrap each object-creation run in a database transaction so a
|
|
110
|
+
# failure rolls back everything created in that run (default: true).
|
|
111
|
+
# Note: some PostgreSQL statements cannot run inside a transaction
|
|
112
|
+
# (e.g. CREATE INDEX CONCURRENTLY, VACUUM) — set to false if your
|
|
113
|
+
# object files contain them.
|
|
114
|
+
transactional: true
|
|
115
|
+
|
|
116
|
+
# Whether to install the Rake hooks that auto-create objects (default: true)
|
|
117
|
+
auto_hook_migrations: true
|
|
75
118
|
```
|
|
76
119
|
|
|
77
120
|
### Initializer
|
|
@@ -83,7 +126,8 @@ PgObjects.configure do |config|
|
|
|
83
126
|
config.before_path = 'path/to/objects/before' # default: 'db/objects/before'
|
|
84
127
|
config.after_path = 'path/to/objects/after' # default: 'db/objects/after'
|
|
85
128
|
config.extensions = ['sql', 'txt'] # default: 'sql'
|
|
86
|
-
config.silent = true #
|
|
129
|
+
config.silent = true # suppress non-error output to console (errors are always printed), default: false
|
|
130
|
+
config.transactional = false # opt out of the wrapping transaction, default: true
|
|
87
131
|
end
|
|
88
132
|
```
|
|
89
133
|
|
|
@@ -91,6 +135,118 @@ Otherwise, the default values will be used.
|
|
|
91
135
|
|
|
92
136
|
Please make sure to verify that the specified directories actually exist.
|
|
93
137
|
|
|
138
|
+
> [!NOTE]
|
|
139
|
+
> Object creation runs inside a single database transaction by default, so a
|
|
140
|
+
> failure mid-run rolls back every object created in that run. PostgreSQL
|
|
141
|
+
> rejects some statements inside a transaction block — for example
|
|
142
|
+
> `CREATE INDEX CONCURRENTLY`, `VACUUM`, or `ALTER TYPE ... ADD VALUE` on
|
|
143
|
+
> PostgreSQL versions before 12. If your object files contain such statements,
|
|
144
|
+
> set `config.transactional = false`.
|
|
145
|
+
|
|
146
|
+
### Rake tasks that trigger object creation
|
|
147
|
+
|
|
148
|
+
Object creation is hooked into Rake tasks. By default:
|
|
149
|
+
|
|
150
|
+
| Task | `before` objects | `after` objects |
|
|
151
|
+
| --- | :---: | :---: |
|
|
152
|
+
| `db:migrate` | ✓ | ✓ |
|
|
153
|
+
| `db:schema:load` | | ✓ |
|
|
154
|
+
| `db:migrate:redo` | ✓ | ✓ |
|
|
155
|
+
|
|
156
|
+
`db:rollback` is **not** hooked — rolling a migration back should not recreate
|
|
157
|
+
objects.
|
|
158
|
+
|
|
159
|
+
You can also invoke the underlying tasks directly: `db:create_objects:before`
|
|
160
|
+
and `db:create_objects:after`.
|
|
161
|
+
|
|
162
|
+
### Multiple databases
|
|
163
|
+
|
|
164
|
+
By default objects are created over the global connection
|
|
165
|
+
(`ActiveRecord::Base.connection`). In a Rails multi-database setup, target a
|
|
166
|
+
specific database by passing its connection to the manager:
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
PgObjects::Manager.new(connection: AnimalsRecord.connection).load_files(:before).create_objects
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
For the rake tasks, set `PG_OBJECTS_CONNECTION_CLASS` to the name of the
|
|
173
|
+
Active Record class whose connection should be used:
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
PG_OBJECTS_CONNECTION_CLASS=AnimalsRecord bin/rails db:create_objects:before
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
To disable all hooks entirely, set `auto_hook_migrations` to `false` in an
|
|
180
|
+
initializer; then create objects only by invoking those tasks manually:
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
PgObjects.configure do |config|
|
|
184
|
+
config.auto_hook_migrations = false # default: true
|
|
185
|
+
end
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Re-running and idempotency
|
|
189
|
+
|
|
190
|
+
The hooked tasks re-execute **every** object file on each run — the gem keeps
|
|
191
|
+
no state about what was already created. Files must therefore contain
|
|
192
|
+
re-runnable (idempotent) SQL, or the second `db:migrate` fails with errors
|
|
193
|
+
like `relation "..." already exists`.
|
|
194
|
+
|
|
195
|
+
What PostgreSQL offers per object type:
|
|
196
|
+
|
|
197
|
+
| Object type | Idempotent form |
|
|
198
|
+
| --- | --- |
|
|
199
|
+
| `FUNCTION`, `VIEW` | `CREATE OR REPLACE` |
|
|
200
|
+
| `RULE` | `CREATE OR REPLACE` |
|
|
201
|
+
| `AGGREGATE` | `CREATE OR REPLACE` (PostgreSQL 12+) |
|
|
202
|
+
| `TRIGGER` | `CREATE OR REPLACE` (PostgreSQL 14+), otherwise drop-and-recreate |
|
|
203
|
+
| `TABLE`, `INDEX`, `SEQUENCE`, `MATERIALIZED VIEW`, `EXTENSION` | `IF NOT EXISTS` |
|
|
204
|
+
| `TYPE`, `DOMAIN`, `POLICY`, `CONVERSION`, `OPERATOR`, `OPERATOR CLASS`, `EVENT TRIGGER`, `TEXT SEARCH PARSER/TEMPLATE` | none — use a guard (below) |
|
|
205
|
+
|
|
206
|
+
For types without an idempotent form, either drop first:
|
|
207
|
+
|
|
208
|
+
```sql
|
|
209
|
+
DROP POLICY IF EXISTS user_policy ON users;
|
|
210
|
+
CREATE POLICY user_policy ON users USING (user_id = current_user_id());
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
or swallow the duplicate error in a `DO` block:
|
|
214
|
+
|
|
215
|
+
```sql
|
|
216
|
+
DO $$ BEGIN
|
|
217
|
+
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
|
|
218
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
219
|
+
END $$;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
> [!NOTE]
|
|
223
|
+
> Object files are classified by parsing their **first** statement. When that
|
|
224
|
+
> statement is a `DROP` or a `DO` block (as in the guards above), the SQL
|
|
225
|
+
> object name cannot be extracted. The file still executes normally, but it
|
|
226
|
+
> can only be referenced by its **file identifiers** — the extensionless file
|
|
227
|
+
> name or the file path — while `--!depends_on` directives referring to the
|
|
228
|
+
> SQL object name (or its schema-qualified form) will not match it.
|
|
229
|
+
> The plain `IF NOT EXISTS` / `OR REPLACE` forms keep full name resolution.
|
|
230
|
+
|
|
231
|
+
Also note that object creation runs inside a single transaction by default
|
|
232
|
+
(see above), so one failing statement rolls back the entire run — a
|
|
233
|
+
half-idempotent set of files either all applies or not at all.
|
|
234
|
+
|
|
235
|
+
Override `hook_tasks` to customize which tasks/stages are hooked (e.g. an empty
|
|
236
|
+
hash also disables all hooks). Configure it in a Rails initializer: the hooks are installed when the
|
|
237
|
+
gem's rake tasks load, which happens after initializers run, so an initializer
|
|
238
|
+
value is always picked up. Changing `hook_tasks` later (after task loading) has
|
|
239
|
+
no effect on which hooks are installed.
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
PgObjects.configure do |config|
|
|
243
|
+
config.hook_tasks = {
|
|
244
|
+
'db:migrate' => %i[before after],
|
|
245
|
+
'db:schema:load' => %i[after]
|
|
246
|
+
}
|
|
247
|
+
end
|
|
248
|
+
```
|
|
249
|
+
|
|
94
250
|
## Development
|
|
95
251
|
|
|
96
252
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -145,3 +301,18 @@ Full Workflow Performance:
|
|
|
145
301
|
## Contributing
|
|
146
302
|
|
|
147
303
|
Bug reports and pull requests are welcome on GitHub at https://github.com/marinazzio/pg_objects.
|
|
304
|
+
|
|
305
|
+
Every pull request that changes gem behavior must add an entry to the
|
|
306
|
+
`[Unreleased]` section of [CHANGELOG.md](CHANGELOG.md) (following the
|
|
307
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format). Pure
|
|
308
|
+
refactorings, spec-only, and dependency-bump PRs may skip this.
|
|
309
|
+
|
|
310
|
+
## Releasing
|
|
311
|
+
|
|
312
|
+
1. Move the `[Unreleased]` entries in `CHANGELOG.md` under a new version
|
|
313
|
+
heading with the release date, and update the comparison links at the
|
|
314
|
+
bottom of the file.
|
|
315
|
+
2. Bump `PgObjects::VERSION` in `lib/pg_objects/version.rb` accordingly
|
|
316
|
+
(semantic versioning).
|
|
317
|
+
3. Tag the commit `vX.Y.Z` and publish a GitHub release — the publish
|
|
318
|
+
workflow builds and pushes the gem to RubyGems.
|