scenic-cascade 0.1.1 → 0.1.3
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/CHANGELOG.md +21 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +25 -19
- data/README.md +6 -0
- data/Steepfile +4 -1
- data/codecov.yml +3 -0
- data/lib/generators/scenic/view/cascade/cascade_generator.rb +114 -11
- data/lib/generators/scenic/view/cascade/templates/db/migrate/update_view.rb.erb +43 -5
- data/lib/scenic/cascade/definition_finder.rb +16 -5
- data/lib/scenic/cascade/dependency_finder.rb +14 -7
- data/lib/scenic/cascade/dependent_finder.rb +14 -7
- data/lib/scenic/cascade/version.rb +1 -1
- data/lib/scenic/cascade/view_with_version.rb +4 -2
- data/rbs_collection.lock.yaml +124 -24
- data/rbs_collection.yaml +3 -8
- data/sig/generators/scenic/view/cascade/cascade_generator.rbs +17 -0
- data/sig/generators/scenic/view/view_generator.rbs +12 -3
- data/sig/scenic/cascade/definition_finder.rbs +1 -1
- data/sig/scenic/cascade/view.rbs +2 -0
- data/sig/scenic/cascade/view_with_version.rbs +6 -1
- data/sig/scenic/cascade.rbs +1 -1
- data/sig/scenic/definition.rbs +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29ecc270cd637c5654557c3d349c43a59483476d7a0758a3988136d4c3fa4a28
|
|
4
|
+
data.tar.gz: b53b4f0a78d929753627aabcab2dbf75c6e6aad79fe5ee6a77b5a1b45b9b9af0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 642f9d3a40bf02b8da393a10e645c7609e5562652654c016ad27a6806b86d8bbf4f98ffd4e1554ef4fca5a60dab878badf298bbc0200b38ae1aa16c0baccddf3
|
|
7
|
+
data.tar.gz: b95a92d620f673192b07e82de00151e4e251e1ecaeb13c24df4c6fa85670a71093b04a2d0d44dde9b86bf7e066dc112689292b808eabe27e3549dddea849c134
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.3] - 2026-11-01
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Recreate dependent views when generating a migration with a Rails table name prefix.
|
|
15
|
+
- Discover and recreate dependent views across PostgreSQL schemas without mixing identically named views or their SQL definitions.
|
|
16
|
+
- Remove generated view definitions and partial migrations when migration generation fails, so retries use the correct version.
|
|
17
|
+
- Apply `--replace` and supported `--side-by-side` options when generating view update migrations.
|
|
18
|
+
- Avoid leaving an orphan SQL definition when `--skip` skips a conflicting migration.
|
|
19
|
+
|
|
20
|
+
## [0.1.2] - 2026-11-01
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Select the latest existing dependent view definition when SQL version numbers have gaps.
|
|
25
|
+
- Report noncanonical numeric view definition filenames instead of silently selecting an older definition.
|
|
26
|
+
- Leave view definition files untouched when a dependent view has no Scenic definition.
|
|
27
|
+
|
|
10
28
|
## [0.1.1] - 2026-10-30
|
|
11
29
|
|
|
12
30
|
### Fixed
|
|
@@ -19,6 +37,8 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
|
|
|
19
37
|
|
|
20
38
|
- Initial release of the cascading Scenic view migration generator.
|
|
21
39
|
|
|
22
|
-
[Unreleased]: https://github.com/akiomik/scenic-cascade/compare/v0.1.
|
|
40
|
+
[Unreleased]: https://github.com/akiomik/scenic-cascade/compare/v0.1.3...HEAD
|
|
41
|
+
[0.1.3]: https://github.com/akiomik/scenic-cascade/compare/v0.1.2...v0.1.3
|
|
42
|
+
[0.1.2]: https://github.com/akiomik/scenic-cascade/compare/v0.1.1...v0.1.2
|
|
23
43
|
[0.1.1]: https://github.com/akiomik/scenic-cascade/compare/v0.1.0...v0.1.1
|
|
24
44
|
[0.1.0]: https://github.com/akiomik/scenic-cascade/releases/tag/v0.1.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
scenic-cascade (0.1.
|
|
4
|
+
scenic-cascade (0.1.3)
|
|
5
5
|
scenic (~> 1.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
abbrev (0.1.1)
|
|
11
10
|
actionpack (7.1.6)
|
|
12
11
|
actionview (= 7.1.6)
|
|
13
12
|
activesupport (= 7.1.6)
|
|
@@ -58,7 +57,7 @@ GEM
|
|
|
58
57
|
concurrent-ruby (1.3.7)
|
|
59
58
|
connection_pool (2.4.1)
|
|
60
59
|
crass (1.0.8)
|
|
61
|
-
csv (3.
|
|
60
|
+
csv (3.3.7)
|
|
62
61
|
database_cleaner-active_record (2.1.0)
|
|
63
62
|
activerecord (>= 5.a)
|
|
64
63
|
database_cleaner-core (~> 2.0.0)
|
|
@@ -68,8 +67,10 @@ GEM
|
|
|
68
67
|
drb (2.2.0)
|
|
69
68
|
ruby2_keywords
|
|
70
69
|
erubi (1.12.0)
|
|
71
|
-
ffi (1.
|
|
72
|
-
|
|
70
|
+
ffi (1.17.4-aarch64-linux-musl)
|
|
71
|
+
ffi (1.17.4-arm64-darwin)
|
|
72
|
+
ffi (1.17.4-x86_64-linux-gnu)
|
|
73
|
+
fileutils (1.8.1)
|
|
73
74
|
i18n (1.14.1)
|
|
74
75
|
concurrent-ruby (~> 1.0)
|
|
75
76
|
io-console (0.6.0)
|
|
@@ -77,8 +78,9 @@ GEM
|
|
|
77
78
|
rdoc
|
|
78
79
|
reline (>= 0.3.8)
|
|
79
80
|
json (2.7.1)
|
|
80
|
-
language_server-protocol (3.17.0.
|
|
81
|
-
listen (3.
|
|
81
|
+
language_server-protocol (3.17.0.6)
|
|
82
|
+
listen (3.10.1)
|
|
83
|
+
logger
|
|
82
84
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
83
85
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
84
86
|
logger (1.6.0)
|
|
@@ -86,7 +88,7 @@ GEM
|
|
|
86
88
|
crass (~> 1.0.2)
|
|
87
89
|
nokogiri (>= 1.12.0)
|
|
88
90
|
minitest (5.20.0)
|
|
89
|
-
mutex_m (0.
|
|
91
|
+
mutex_m (0.3.0)
|
|
90
92
|
nokogiri (1.18.10-aarch64-linux-musl)
|
|
91
93
|
racc (~> 1.4)
|
|
92
94
|
nokogiri (1.18.10-arm64-darwin)
|
|
@@ -129,10 +131,11 @@ GEM
|
|
|
129
131
|
rainbow (3.1.1)
|
|
130
132
|
rake (13.1.0)
|
|
131
133
|
rb-fsevent (0.11.2)
|
|
132
|
-
rb-inotify (0.
|
|
134
|
+
rb-inotify (0.11.1)
|
|
133
135
|
ffi (~> 1.0)
|
|
134
|
-
rbs (3.
|
|
135
|
-
|
|
136
|
+
rbs (3.10.4)
|
|
137
|
+
logger
|
|
138
|
+
tsort
|
|
136
139
|
rdoc (6.6.3.1)
|
|
137
140
|
psych (>= 4.0.0)
|
|
138
141
|
regexp_parser (2.8.3)
|
|
@@ -201,31 +204,34 @@ GEM
|
|
|
201
204
|
simplecov (~> 0.19)
|
|
202
205
|
simplecov-html (0.12.3)
|
|
203
206
|
simplecov_json_formatter (0.1.4)
|
|
204
|
-
steep (1.
|
|
207
|
+
steep (1.10.0)
|
|
205
208
|
activesupport (>= 5.1)
|
|
206
209
|
concurrent-ruby (>= 1.1.10)
|
|
207
210
|
csv (>= 3.0.9)
|
|
208
211
|
fileutils (>= 1.1.0)
|
|
209
212
|
json (>= 2.1.0)
|
|
210
|
-
language_server-protocol (>= 3.
|
|
213
|
+
language_server-protocol (>= 3.17.0.4, < 4.0)
|
|
211
214
|
listen (~> 3.0)
|
|
212
215
|
logger (>= 1.3.0)
|
|
216
|
+
mutex_m (>= 0.3.0)
|
|
213
217
|
parser (>= 3.1)
|
|
214
218
|
rainbow (>= 2.2.2, < 4.0)
|
|
215
|
-
rbs (
|
|
219
|
+
rbs (~> 3.9)
|
|
216
220
|
securerandom (>= 0.1)
|
|
217
221
|
strscan (>= 1.0.0)
|
|
218
|
-
terminal-table (>= 2, <
|
|
222
|
+
terminal-table (>= 2, < 5)
|
|
223
|
+
uri (>= 0.12.0)
|
|
219
224
|
stringio (3.2.0)
|
|
220
|
-
strscan (3.1.
|
|
221
|
-
terminal-table (
|
|
222
|
-
unicode-display_width (>= 1.1.1, <
|
|
225
|
+
strscan (3.1.8)
|
|
226
|
+
terminal-table (4.0.0)
|
|
227
|
+
unicode-display_width (>= 1.1.1, < 4)
|
|
223
228
|
thor (1.4.0)
|
|
224
229
|
timeout (0.4.1)
|
|
225
230
|
tsort (0.2.0)
|
|
226
231
|
tzinfo (2.0.6)
|
|
227
232
|
concurrent-ruby (~> 1.0)
|
|
228
233
|
unicode-display_width (2.5.0)
|
|
234
|
+
uri (1.1.2)
|
|
229
235
|
webrick (1.8.2)
|
|
230
236
|
zeitwerk (2.6.12)
|
|
231
237
|
|
|
@@ -250,7 +256,7 @@ DEPENDENCIES
|
|
|
250
256
|
scenic-cascade!
|
|
251
257
|
simplecov
|
|
252
258
|
simplecov-cobertura (~> 3.2)
|
|
253
|
-
steep
|
|
259
|
+
steep (~> 1.10)
|
|
254
260
|
|
|
255
261
|
BUNDLED WITH
|
|
256
262
|
2.4.22
|
data/README.md
CHANGED
|
@@ -37,6 +37,12 @@ $ bin/rails generate scenic:view:cascade search_results
|
|
|
37
37
|
create db/migrate/20220714233704_create_search_results.rb
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
For a schema-qualified view, pass its database relation name, such as `reporting.orders`.
|
|
41
|
+
If Rails uses a table name prefix, include it after the schema name (for example, `reporting.app_orders`).
|
|
42
|
+
For unqualified names, pass the name without the prefix; Rails applies it in the migration.
|
|
43
|
+
If another schema precedes `public` in PostgreSQL's `search_path` and contains a view with the same name,
|
|
44
|
+
use a schema-qualified Scenic definition for the public dependent view (for example, `public_reports_v01.sql`).
|
|
45
|
+
|
|
40
46
|
## How it works
|
|
41
47
|
|
|
42
48
|
Consider a situation where the following three views exist:
|
data/Steepfile
CHANGED
data/codecov.yml
ADDED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'erb'
|
|
3
4
|
require 'generators/scenic/view/view_generator'
|
|
4
5
|
require 'scenic/cascade'
|
|
5
6
|
require 'scenic/cascade/view_with_version'
|
|
@@ -11,22 +12,84 @@ module Scenic
|
|
|
11
12
|
class CascadeGenerator < Scenic::Generators::ViewGenerator
|
|
12
13
|
source_root File.expand_path('templates', __dir__ || '.')
|
|
13
14
|
|
|
15
|
+
def create_view_definition
|
|
16
|
+
@definition_path = @original_definition = nil
|
|
17
|
+
validate_update_options! unless destroying? || creating_new_view?
|
|
18
|
+
dependents unless destroying? || creating_new_view?
|
|
19
|
+
path = Scenic::Definition.new(plural_file_name, version).full_path.to_s
|
|
20
|
+
@definition_path = path
|
|
21
|
+
@original_definition = File.binread(path) if File.file?(path)
|
|
22
|
+
super
|
|
23
|
+
rescue StandardError
|
|
24
|
+
restore_definition
|
|
25
|
+
raise
|
|
26
|
+
end
|
|
27
|
+
|
|
14
28
|
def create_migration_file
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
template, destination = migration_template_details
|
|
30
|
+
pattern = File.join(destination_root, 'db/migrate', "[0-9]*_#{File.basename(destination)}")
|
|
31
|
+
original_migrations = Dir.glob(pattern).to_h { |path| [path, File.binread(path)] }
|
|
32
|
+
migration_template(template, destination)
|
|
33
|
+
# Thor returns normally for --skip even though it did not create a migration.
|
|
34
|
+
restore_definition if options[:skip] && skipped_migration?(template, pattern, original_migrations)
|
|
35
|
+
rescue StandardError
|
|
36
|
+
restore_migrations(pattern, original_migrations) if pattern && original_migrations
|
|
37
|
+
restore_definition
|
|
38
|
+
raise
|
|
22
39
|
end
|
|
23
40
|
|
|
24
41
|
private
|
|
25
42
|
|
|
43
|
+
def validate_update_options!
|
|
44
|
+
raise ArgumentError, '--replace cannot update a materialized view' if options[:replace] && materialized?
|
|
45
|
+
|
|
46
|
+
validate_side_by_side_option! if options[:side_by_side]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def validate_side_by_side_option!
|
|
50
|
+
raise ArgumentError, '--side-by-side requires --materialized' unless materialized?
|
|
51
|
+
raise ArgumentError, '--side-by-side cannot update schema-qualified views' if plural_name.include?('.')
|
|
52
|
+
|
|
53
|
+
raise ArgumentError, '--side-by-side cannot be combined with --no-data' if options[:no_data]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def migration_template_details
|
|
57
|
+
return ['db/migrate/create_view.rb.erb', "db/migrate/create_#{plural_file_name}.rb"] if
|
|
58
|
+
creating_new_view? || destroying_initial_view?
|
|
59
|
+
|
|
60
|
+
['db/migrate/update_view.rb.erb', "db/migrate/update_#{plural_file_name}_to_version_#{version}.rb"]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def restore_definition
|
|
64
|
+
return unless (path = @definition_path)
|
|
65
|
+
|
|
66
|
+
if (original = @original_definition)
|
|
67
|
+
restore_file(path, original)
|
|
68
|
+
elsif File.file?(path)
|
|
69
|
+
File.delete(path)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def restore_migrations(pattern, originals)
|
|
74
|
+
(Dir.glob(pattern) - originals.keys).each { |path| File.delete(path) }
|
|
75
|
+
originals.each { |path, content| restore_file(path, content) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def restore_file(path, content)
|
|
79
|
+
File.binwrite(path, content) unless File.file?(path) && File.binread(path) == content
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def skipped_migration?(template, pattern, originals)
|
|
83
|
+
return false unless Dir.glob(pattern).to_h { |path| [path, File.binread(path)] } == originals
|
|
84
|
+
|
|
85
|
+
originals.values.first != ERB.new(File.read(find_in_source_paths(template)), trim_mode: '-').result(binding).b
|
|
86
|
+
end
|
|
87
|
+
|
|
26
88
|
def dependents
|
|
27
|
-
|
|
89
|
+
cached_dependents = @dependents
|
|
90
|
+
return cached_dependents unless cached_dependents.nil?
|
|
28
91
|
|
|
29
|
-
deps = Scenic::Cascade.view_dependents_of(
|
|
92
|
+
deps = Scenic::Cascade.view_dependents_of(database_view_name, recursive: true)
|
|
30
93
|
views = deps.map { |dep| view_with_version_for(dep) }
|
|
31
94
|
# The last visit follows every prerequisite, even when names sort in the opposite order.
|
|
32
95
|
@dependents = views.reverse.uniq { |view| [view.name, view.version, view.materialized?] }.reverse
|
|
@@ -34,8 +97,48 @@ module Scenic
|
|
|
34
97
|
|
|
35
98
|
def view_with_version_for(dep)
|
|
36
99
|
name = dep.from.name
|
|
37
|
-
|
|
38
|
-
Scenic::Cascade
|
|
100
|
+
definition_name = definition_name_for(name)
|
|
101
|
+
definition = Scenic::Cascade.find_definitions_of(definition_name).last
|
|
102
|
+
raise ArgumentError, "Dependent view #{name} has no Scenic definition file" if definition.nil?
|
|
103
|
+
|
|
104
|
+
Scenic::Cascade::ViewWithVersion.new(
|
|
105
|
+
name: definition_name, version: definition.version.to_i,
|
|
106
|
+
materialized: dep.from.materialized?, database_name: qualified_name(name)
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def definition_name_for(name)
|
|
111
|
+
return name if name.include?('.')
|
|
112
|
+
|
|
113
|
+
qualified = qualified_name(name)
|
|
114
|
+
qualified_definitions = Scenic::Cascade.find_definitions_of(qualified)
|
|
115
|
+
bare_definitions = Scenic::Cascade.find_definitions_of(name)
|
|
116
|
+
|
|
117
|
+
if qualified_definitions.any? && bare_definitions.any?
|
|
118
|
+
raise ArgumentError, "Dependent view #{name} has ambiguous Scenic definitions: #{name} and #{qualified}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
return qualified if qualified_definitions.any?
|
|
122
|
+
return name if bare_definitions.empty? || bare_name_resolves_to_public?(name)
|
|
123
|
+
|
|
124
|
+
raise ArgumentError, "Dependent view #{name} has no unambiguous Scenic definition file for #{qualified}"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def bare_name_resolves_to_public?(name)
|
|
128
|
+
connection = ActiveRecord::Base.connection
|
|
129
|
+
bare = connection.quote(connection.quote_table_name(name))
|
|
130
|
+
qualified = connection.quote(connection.quote_table_name(qualified_name(name)))
|
|
131
|
+
connection.select_value("SELECT to_regclass(#{bare}) = to_regclass(#{qualified})")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def qualified_name(name)
|
|
135
|
+
name.include?('.') ? name : "public.#{name}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def database_view_name
|
|
139
|
+
return plural_name if plural_name.include?('.')
|
|
140
|
+
|
|
141
|
+
"#{ActiveRecord::Base.table_name_prefix}#{plural_name}#{ActiveRecord::Base.table_name_suffix}"
|
|
39
142
|
end
|
|
40
143
|
end
|
|
41
144
|
end
|
|
@@ -1,26 +1,64 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class <%= migration_class_name %> < <%= activerecord_migration_class %>
|
|
4
|
+
<%- if dependents.any? || plural_name.include?('.') -%>
|
|
5
|
+
class ExactViewName < String
|
|
6
|
+
alias table_name to_s
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
<%- end -%>
|
|
10
|
+
<%- target_name = plural_name.include?('.') ? "ExactViewName.new(#{plural_name.inspect})" : formatted_plural_name -%>
|
|
11
|
+
<%- update_method = options[:replace] ? 'replace_view' : 'update_view' -%>
|
|
12
|
+
<%- materialized_flags = [] -%>
|
|
13
|
+
<%- materialized_flags << 'no_data: true' if options[:no_data] -%>
|
|
14
|
+
<%- materialized_flags << 'side_by_side: true' if options[:side_by_side] -%>
|
|
15
|
+
<%- materialized_options = materialized_flags.empty? ? 'true' : "{ #{materialized_flags.join(', ')} }" -%>
|
|
4
16
|
def change
|
|
5
17
|
<%- dependents.reverse_each do |dep| -%>
|
|
6
|
-
|
|
18
|
+
<%- if dep.database_name == dep.name -%>
|
|
19
|
+
drop_view ExactViewName.new(<%= dep.database_name.inspect %>),
|
|
7
20
|
revert_to_version: <%= dep.version %>,
|
|
8
21
|
materialized: <%= dep.materialized? %>
|
|
22
|
+
<%- else -%>
|
|
23
|
+
reversible do |direction|
|
|
24
|
+
direction.up do
|
|
25
|
+
drop_view ExactViewName.new(<%= dep.database_name.inspect %>), materialized: <%= dep.materialized? %>
|
|
26
|
+
end
|
|
27
|
+
direction.down do
|
|
28
|
+
create_view ExactViewName.new(<%= dep.database_name.inspect %>),
|
|
29
|
+
sql_definition: Scenic::Definition.new(<%= dep.name.inspect %>, <%= dep.version %>).to_sql,
|
|
30
|
+
materialized: <%= dep.materialized? %>
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
<%- end -%>
|
|
9
34
|
<%- end -%>
|
|
10
35
|
|
|
11
36
|
<%- if materialized? -%>
|
|
12
|
-
|
|
37
|
+
<%= update_method %> <%= target_name %>,
|
|
13
38
|
version: <%= version %>,
|
|
14
39
|
revert_to_version: <%= previous_version %>,
|
|
15
|
-
materialized: <%=
|
|
40
|
+
materialized: <%= materialized_options %>
|
|
16
41
|
<%- else -%>
|
|
17
|
-
|
|
42
|
+
<%= update_method %> <%= target_name %>, version: <%= version %>, revert_to_version: <%= previous_version %>
|
|
18
43
|
<%- end -%>
|
|
19
44
|
|
|
20
45
|
<%- dependents.each do |dep| -%>
|
|
21
|
-
|
|
46
|
+
<%- if dep.database_name == dep.name -%>
|
|
47
|
+
create_view ExactViewName.new(<%= dep.database_name.inspect %>),
|
|
22
48
|
version: <%= dep.version %>,
|
|
23
49
|
materialized: <%= dep.materialized? %>
|
|
50
|
+
<%- else -%>
|
|
51
|
+
reversible do |direction|
|
|
52
|
+
direction.up do
|
|
53
|
+
create_view ExactViewName.new(<%= dep.database_name.inspect %>),
|
|
54
|
+
sql_definition: Scenic::Definition.new(<%= dep.name.inspect %>, <%= dep.version %>).to_sql,
|
|
55
|
+
materialized: <%= dep.materialized? %>
|
|
56
|
+
end
|
|
57
|
+
direction.down do
|
|
58
|
+
drop_view ExactViewName.new(<%= dep.database_name.inspect %>), materialized: <%= dep.materialized? %>
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
<%- end -%>
|
|
24
62
|
<%- end -%>
|
|
25
63
|
end
|
|
26
64
|
end
|
|
@@ -14,7 +14,13 @@ module Scenic
|
|
|
14
14
|
# Provides class methods to injected class
|
|
15
15
|
module ClassMethods
|
|
16
16
|
def find_definitions_of(view_name)
|
|
17
|
-
|
|
17
|
+
first_path = Scenic::Definition.new(view_name, 1).full_path
|
|
18
|
+
directory = first_path.dirname
|
|
19
|
+
return [] unless directory.directory?
|
|
20
|
+
|
|
21
|
+
prefix = first_path.basename.to_s.sub(/\d+\.sql\z/, '')
|
|
22
|
+
directory.children.map { |path| definition_at(path, view_name, prefix) }
|
|
23
|
+
.compact.sort_by { |definition| definition.version.to_i }
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
def find_latest_definition_of(view_name)
|
|
@@ -29,11 +35,16 @@ module Scenic
|
|
|
29
35
|
|
|
30
36
|
private
|
|
31
37
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
def definition_at(path, view_name, prefix)
|
|
39
|
+
return unless path.file?
|
|
40
|
+
|
|
41
|
+
match = /\A#{Regexp.escape(prefix)}(?<version>\d+)\.sql\z/.match(path.basename.to_s)
|
|
42
|
+
return unless match && match[:version].to_i.positive?
|
|
43
|
+
|
|
44
|
+
definition = Scenic::Definition.new(view_name, match[:version].to_i)
|
|
45
|
+
return definition if definition.full_path == path
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
raise ArgumentError, "Noncanonical view definition #{path}; expected #{definition.full_path}"
|
|
37
48
|
end
|
|
38
49
|
end
|
|
39
50
|
end
|
|
@@ -14,21 +14,28 @@ module Scenic
|
|
|
14
14
|
module ClassMethods
|
|
15
15
|
DEPENDENCY_SQL = <<-SQL
|
|
16
16
|
SELECT DISTINCT
|
|
17
|
-
dependee.relname
|
|
17
|
+
CASE WHEN dependee_ns.nspname = 'public' THEN dependee.relname
|
|
18
|
+
ELSE dependee_ns.nspname || '.' || dependee.relname END AS to
|
|
18
19
|
, dependee.relkind = 'm' AS to_materialized
|
|
19
|
-
, depender.relname
|
|
20
|
+
, CASE WHEN depender_ns.nspname = 'public' THEN depender.relname
|
|
21
|
+
ELSE depender_ns.nspname || '.' || depender.relname END AS from
|
|
20
22
|
, depender.relkind = 'm' AS from_materialized
|
|
23
|
+
, format('%I.%I', dependee_ns.nspname, dependee.relname) AS to_lookup
|
|
21
24
|
FROM pg_depend d
|
|
22
25
|
JOIN pg_rewrite r
|
|
23
26
|
ON d.objid = r.oid
|
|
24
27
|
JOIN pg_class AS dependee
|
|
25
28
|
ON d.refobjid = dependee.oid
|
|
29
|
+
JOIN pg_namespace AS dependee_ns
|
|
30
|
+
ON dependee.relnamespace = dependee_ns.oid
|
|
26
31
|
JOIN pg_class AS depender
|
|
27
32
|
ON r.ev_class = depender.oid
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
JOIN pg_namespace AS depender_ns
|
|
34
|
+
ON depender.relnamespace = depender_ns.oid
|
|
35
|
+
WHERE depender.oid = to_regclass(?)
|
|
36
|
+
AND dependee.oid != depender.oid
|
|
30
37
|
AND dependee.relkind in ('m', 'v')
|
|
31
|
-
ORDER BY
|
|
38
|
+
ORDER BY to_lookup;
|
|
32
39
|
SQL
|
|
33
40
|
|
|
34
41
|
private_constant :DEPENDENCY_SQL
|
|
@@ -41,8 +48,8 @@ module Scenic
|
|
|
41
48
|
return [] if dependencies.empty?
|
|
42
49
|
return dependencies unless recursive
|
|
43
50
|
|
|
44
|
-
dependencies.flat_map do |dependency|
|
|
45
|
-
[dependency, *view_dependencies_of(
|
|
51
|
+
raw_dependencies.zip(dependencies).flat_map do |row, dependency|
|
|
52
|
+
[dependency, *view_dependencies_of(row.fetch('to_lookup'), recursive: true)]
|
|
46
53
|
end
|
|
47
54
|
end
|
|
48
55
|
end
|
|
@@ -14,21 +14,28 @@ module Scenic
|
|
|
14
14
|
module ClassMethods
|
|
15
15
|
DEPENDANT_SQL = <<-SQL
|
|
16
16
|
SELECT DISTINCT
|
|
17
|
-
dependee.relname
|
|
17
|
+
CASE WHEN dependee_ns.nspname = 'public' THEN dependee.relname
|
|
18
|
+
ELSE dependee_ns.nspname || '.' || dependee.relname END AS to
|
|
18
19
|
, dependee.relkind = 'm' AS to_materialized
|
|
19
|
-
, depender.relname
|
|
20
|
+
, CASE WHEN depender_ns.nspname = 'public' THEN depender.relname
|
|
21
|
+
ELSE depender_ns.nspname || '.' || depender.relname END AS from
|
|
20
22
|
, depender.relkind = 'm' AS from_materialized
|
|
23
|
+
, format('%I.%I', depender_ns.nspname, depender.relname) AS from_lookup
|
|
21
24
|
FROM pg_depend d
|
|
22
25
|
JOIN pg_rewrite r
|
|
23
26
|
ON d.objid = r.oid
|
|
24
27
|
JOIN pg_class AS dependee
|
|
25
28
|
ON d.refobjid = dependee.oid
|
|
29
|
+
JOIN pg_namespace AS dependee_ns
|
|
30
|
+
ON dependee.relnamespace = dependee_ns.oid
|
|
26
31
|
JOIN pg_class AS depender
|
|
27
32
|
ON r.ev_class = depender.oid
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
JOIN pg_namespace AS depender_ns
|
|
34
|
+
ON depender.relnamespace = depender_ns.oid
|
|
35
|
+
WHERE dependee.oid = to_regclass(?)
|
|
36
|
+
AND depender.oid != dependee.oid
|
|
30
37
|
AND depender.relkind in ('m', 'v')
|
|
31
|
-
ORDER BY
|
|
38
|
+
ORDER BY from_lookup;
|
|
32
39
|
SQL
|
|
33
40
|
|
|
34
41
|
private_constant :DEPENDANT_SQL
|
|
@@ -41,8 +48,8 @@ module Scenic
|
|
|
41
48
|
return [] if dependencies.empty?
|
|
42
49
|
return dependencies unless recursive
|
|
43
50
|
|
|
44
|
-
dependencies.flat_map do |dependency|
|
|
45
|
-
[dependency, *view_dependents_of(
|
|
51
|
+
raw_dependencies.zip(dependencies).flat_map do |row, dependency|
|
|
52
|
+
[dependency, *view_dependents_of(row.fetch('from_lookup'), recursive: true)]
|
|
46
53
|
end
|
|
47
54
|
end
|
|
48
55
|
|
|
@@ -6,14 +6,16 @@ module Scenic
|
|
|
6
6
|
module Cascade
|
|
7
7
|
# Represents a view with version
|
|
8
8
|
class ViewWithVersion < Scenic::Cascade::View
|
|
9
|
-
attr_reader :version
|
|
9
|
+
attr_reader :version, :database_name
|
|
10
10
|
|
|
11
|
-
def initialize(name:, version:, materialized:)
|
|
11
|
+
def initialize(name:, version:, materialized:, database_name: name)
|
|
12
12
|
super(name: name, materialized: materialized)
|
|
13
13
|
|
|
14
14
|
raise TypeError unless version.is_a?(Integer)
|
|
15
|
+
raise TypeError unless database_name.is_a?(String)
|
|
15
16
|
|
|
16
17
|
@version = version
|
|
18
|
+
@database_name = database_name
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def ==(other)
|
data/rbs_collection.lock.yaml
CHANGED
|
@@ -6,7 +6,7 @@ gems:
|
|
|
6
6
|
source:
|
|
7
7
|
type: git
|
|
8
8
|
name: ruby/gem_rbs_collection
|
|
9
|
-
revision:
|
|
9
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
10
10
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
11
11
|
repo_dir: gems
|
|
12
12
|
- name: actionview
|
|
@@ -14,47 +14,67 @@ gems:
|
|
|
14
14
|
source:
|
|
15
15
|
type: git
|
|
16
16
|
name: ruby/gem_rbs_collection
|
|
17
|
-
revision:
|
|
17
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
18
18
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
19
19
|
repo_dir: gems
|
|
20
20
|
- name: activemodel
|
|
21
|
-
version: '
|
|
21
|
+
version: '7.1'
|
|
22
22
|
source:
|
|
23
23
|
type: git
|
|
24
24
|
name: ruby/gem_rbs_collection
|
|
25
|
-
revision:
|
|
25
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
26
26
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
27
27
|
repo_dir: gems
|
|
28
28
|
- name: activerecord
|
|
29
|
-
version: '
|
|
29
|
+
version: '7.1'
|
|
30
30
|
source:
|
|
31
31
|
type: git
|
|
32
32
|
name: ruby/gem_rbs_collection
|
|
33
|
-
revision:
|
|
33
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
34
34
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
35
35
|
repo_dir: gems
|
|
36
36
|
- name: activesupport
|
|
37
|
-
version: '
|
|
37
|
+
version: '7.0'
|
|
38
38
|
source:
|
|
39
39
|
type: git
|
|
40
40
|
name: ruby/gem_rbs_collection
|
|
41
|
-
revision:
|
|
41
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
42
42
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
43
43
|
repo_dir: gems
|
|
44
44
|
- name: base64
|
|
45
|
+
version: '0.1'
|
|
46
|
+
source:
|
|
47
|
+
type: git
|
|
48
|
+
name: ruby/gem_rbs_collection
|
|
49
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
50
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
51
|
+
repo_dir: gems
|
|
52
|
+
- name: benchmark
|
|
45
53
|
version: '0'
|
|
46
54
|
source:
|
|
47
55
|
type: stdlib
|
|
48
56
|
- name: bigdecimal
|
|
49
|
-
version: '
|
|
57
|
+
version: '3.1'
|
|
50
58
|
source:
|
|
51
|
-
type:
|
|
59
|
+
type: git
|
|
60
|
+
name: ruby/gem_rbs_collection
|
|
61
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
62
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
63
|
+
repo_dir: gems
|
|
64
|
+
- name: cgi
|
|
65
|
+
version: '0.5'
|
|
66
|
+
source:
|
|
67
|
+
type: git
|
|
68
|
+
name: ruby/gem_rbs_collection
|
|
69
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
70
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
71
|
+
repo_dir: gems
|
|
52
72
|
- name: concurrent-ruby
|
|
53
73
|
version: '1.1'
|
|
54
74
|
source:
|
|
55
75
|
type: git
|
|
56
76
|
name: ruby/gem_rbs_collection
|
|
57
|
-
revision:
|
|
77
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
58
78
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
59
79
|
repo_dir: gems
|
|
60
80
|
- name: connection_pool
|
|
@@ -62,7 +82,7 @@ gems:
|
|
|
62
82
|
source:
|
|
63
83
|
type: git
|
|
64
84
|
name: ruby/gem_rbs_collection
|
|
65
|
-
revision:
|
|
85
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
66
86
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
67
87
|
repo_dir: gems
|
|
68
88
|
- name: date
|
|
@@ -73,6 +93,26 @@ gems:
|
|
|
73
93
|
version: '0'
|
|
74
94
|
source:
|
|
75
95
|
type: stdlib
|
|
96
|
+
- name: delegate
|
|
97
|
+
version: '0'
|
|
98
|
+
source:
|
|
99
|
+
type: stdlib
|
|
100
|
+
- name: diff-lcs
|
|
101
|
+
version: '1.5'
|
|
102
|
+
source:
|
|
103
|
+
type: git
|
|
104
|
+
name: ruby/gem_rbs_collection
|
|
105
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
106
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
107
|
+
repo_dir: gems
|
|
108
|
+
- name: digest
|
|
109
|
+
version: '0'
|
|
110
|
+
source:
|
|
111
|
+
type: stdlib
|
|
112
|
+
- name: erb
|
|
113
|
+
version: '0'
|
|
114
|
+
source:
|
|
115
|
+
type: stdlib
|
|
76
116
|
- name: fileutils
|
|
77
117
|
version: '0'
|
|
78
118
|
source:
|
|
@@ -82,7 +122,7 @@ gems:
|
|
|
82
122
|
source:
|
|
83
123
|
type: git
|
|
84
124
|
name: ruby/gem_rbs_collection
|
|
85
|
-
revision:
|
|
125
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
86
126
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
87
127
|
repo_dir: gems
|
|
88
128
|
- name: io-console
|
|
@@ -94,25 +134,33 @@ gems:
|
|
|
94
134
|
source:
|
|
95
135
|
type: stdlib
|
|
96
136
|
- name: minitest
|
|
97
|
-
version: '
|
|
137
|
+
version: '5.25'
|
|
98
138
|
source:
|
|
99
|
-
type:
|
|
139
|
+
type: git
|
|
140
|
+
name: ruby/gem_rbs_collection
|
|
141
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
142
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
143
|
+
repo_dir: gems
|
|
100
144
|
- name: monitor
|
|
101
145
|
version: '0'
|
|
102
146
|
source:
|
|
103
147
|
type: stdlib
|
|
104
148
|
- name: mutex_m
|
|
105
|
-
version:
|
|
149
|
+
version: 0.3.0
|
|
106
150
|
source:
|
|
107
|
-
type:
|
|
151
|
+
type: rubygems
|
|
108
152
|
- name: nokogiri
|
|
109
153
|
version: '1.11'
|
|
110
154
|
source:
|
|
111
155
|
type: git
|
|
112
156
|
name: ruby/gem_rbs_collection
|
|
113
|
-
revision:
|
|
157
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
114
158
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
115
159
|
repo_dir: gems
|
|
160
|
+
- name: openssl
|
|
161
|
+
version: '0'
|
|
162
|
+
source:
|
|
163
|
+
type: stdlib
|
|
116
164
|
- name: pathname
|
|
117
165
|
version: '0'
|
|
118
166
|
source:
|
|
@@ -125,12 +173,20 @@ gems:
|
|
|
125
173
|
version: '0'
|
|
126
174
|
source:
|
|
127
175
|
type: stdlib
|
|
176
|
+
- name: racc
|
|
177
|
+
version: '1.8'
|
|
178
|
+
source:
|
|
179
|
+
type: git
|
|
180
|
+
name: ruby/gem_rbs_collection
|
|
181
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
182
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
183
|
+
repo_dir: gems
|
|
128
184
|
- name: rack
|
|
129
|
-
version: 2.2
|
|
185
|
+
version: '2.2'
|
|
130
186
|
source:
|
|
131
187
|
type: git
|
|
132
188
|
name: ruby/gem_rbs_collection
|
|
133
|
-
revision:
|
|
189
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
134
190
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
135
191
|
repo_dir: gems
|
|
136
192
|
- name: rails-dom-testing
|
|
@@ -138,7 +194,15 @@ gems:
|
|
|
138
194
|
source:
|
|
139
195
|
type: git
|
|
140
196
|
name: ruby/gem_rbs_collection
|
|
141
|
-
revision:
|
|
197
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
198
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
199
|
+
repo_dir: gems
|
|
200
|
+
- name: rails-html-sanitizer
|
|
201
|
+
version: '1.6'
|
|
202
|
+
source:
|
|
203
|
+
type: git
|
|
204
|
+
name: ruby/gem_rbs_collection
|
|
205
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
142
206
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
143
207
|
repo_dir: gems
|
|
144
208
|
- name: railties
|
|
@@ -146,7 +210,7 @@ gems:
|
|
|
146
210
|
source:
|
|
147
211
|
type: git
|
|
148
212
|
name: ruby/gem_rbs_collection
|
|
149
|
-
revision:
|
|
213
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
150
214
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
151
215
|
repo_dir: gems
|
|
152
216
|
- name: rake
|
|
@@ -154,23 +218,39 @@ gems:
|
|
|
154
218
|
source:
|
|
155
219
|
type: git
|
|
156
220
|
name: ruby/gem_rbs_collection
|
|
157
|
-
revision:
|
|
221
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
158
222
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
159
223
|
repo_dir: gems
|
|
160
224
|
- name: rdoc
|
|
161
225
|
version: '0'
|
|
162
226
|
source:
|
|
163
227
|
type: stdlib
|
|
228
|
+
- name: securerandom
|
|
229
|
+
version: '0'
|
|
230
|
+
source:
|
|
231
|
+
type: stdlib
|
|
164
232
|
- name: singleton
|
|
165
233
|
version: '0'
|
|
166
234
|
source:
|
|
167
235
|
type: stdlib
|
|
236
|
+
- name: socket
|
|
237
|
+
version: '0'
|
|
238
|
+
source:
|
|
239
|
+
type: stdlib
|
|
240
|
+
- name: stringio
|
|
241
|
+
version: '0'
|
|
242
|
+
source:
|
|
243
|
+
type: stdlib
|
|
244
|
+
- name: tempfile
|
|
245
|
+
version: '0'
|
|
246
|
+
source:
|
|
247
|
+
type: stdlib
|
|
168
248
|
- name: thor
|
|
169
249
|
version: '1.2'
|
|
170
250
|
source:
|
|
171
251
|
type: git
|
|
172
252
|
name: ruby/gem_rbs_collection
|
|
173
|
-
revision:
|
|
253
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
174
254
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
175
255
|
repo_dir: gems
|
|
176
256
|
- name: time
|
|
@@ -185,4 +265,24 @@ gems:
|
|
|
185
265
|
version: '0'
|
|
186
266
|
source:
|
|
187
267
|
type: stdlib
|
|
268
|
+
- name: tzinfo
|
|
269
|
+
version: '2.0'
|
|
270
|
+
source:
|
|
271
|
+
type: git
|
|
272
|
+
name: ruby/gem_rbs_collection
|
|
273
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
274
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
275
|
+
repo_dir: gems
|
|
276
|
+
- name: uri
|
|
277
|
+
version: '0'
|
|
278
|
+
source:
|
|
279
|
+
type: stdlib
|
|
280
|
+
- name: zeitwerk
|
|
281
|
+
version: '2.8'
|
|
282
|
+
source:
|
|
283
|
+
type: git
|
|
284
|
+
name: ruby/gem_rbs_collection
|
|
285
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
286
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
287
|
+
repo_dir: gems
|
|
188
288
|
gemfile_lock_path: Gemfile.lock
|
data/rbs_collection.yaml
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
sources:
|
|
3
3
|
- name: ruby/gem_rbs_collection
|
|
4
4
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
5
|
-
|
|
5
|
+
# To refresh upstream signatures, update this SHA, then run:
|
|
6
|
+
# bundle exec rbs collection update && bundle exec rbs collection install
|
|
7
|
+
revision: 9e17daa08b1710667699a208981cffd21dbf15f6
|
|
6
8
|
repo_dir: gems
|
|
7
9
|
|
|
8
10
|
# A directory to install the downloaded RBSs
|
|
@@ -13,10 +15,3 @@ gems:
|
|
|
13
15
|
# It's unnecessary if you don't use rbs as a library.
|
|
14
16
|
- name: rbs
|
|
15
17
|
ignore: true
|
|
16
|
-
# Racc is not used directly, and its current signatures require a newer RBS parser.
|
|
17
|
-
- name: racc
|
|
18
|
-
ignore: true
|
|
19
|
-
# The CGI gem's signatures depend on StringIO signatures absent from RBS 3.3.2.
|
|
20
|
-
# CGI is not used by this library directly.
|
|
21
|
-
- name: cgi
|
|
22
|
-
ignore: true
|
|
@@ -2,11 +2,28 @@ module Scenic
|
|
|
2
2
|
module Generators
|
|
3
3
|
module View
|
|
4
4
|
class CascadeGenerator < Scenic::Generators::ViewGenerator
|
|
5
|
+
@dependents: Array[Scenic::Cascade::ViewWithVersion]?
|
|
6
|
+
@definition_path: String?
|
|
7
|
+
@original_definition: String?
|
|
8
|
+
|
|
9
|
+
def create_view_definition: -> void
|
|
5
10
|
def create_migration_file: -> void
|
|
6
11
|
|
|
7
12
|
private
|
|
8
13
|
|
|
14
|
+
def validate_update_options!: -> void
|
|
15
|
+
def validate_side_by_side_option!: -> void
|
|
9
16
|
def dependents: -> Array[Scenic::Cascade::ViewWithVersion]
|
|
17
|
+
def migration_template_details: -> [String, String]
|
|
18
|
+
def restore_definition: -> void
|
|
19
|
+
def restore_migrations: (String, Hash[String, String]) -> void
|
|
20
|
+
def restore_file: (String, String) -> void
|
|
21
|
+
def skipped_migration?: (String, String, Hash[String, String]) -> bool
|
|
22
|
+
def view_with_version_for: (Scenic::Cascade::Dependency) -> Scenic::Cascade::ViewWithVersion
|
|
23
|
+
def database_view_name: -> String
|
|
24
|
+
def definition_name_for: (String) -> String
|
|
25
|
+
def bare_name_resolves_to_public?: (String) -> bool
|
|
26
|
+
def qualified_name: (String) -> String
|
|
10
27
|
end
|
|
11
28
|
end
|
|
12
29
|
end
|
|
@@ -2,13 +2,22 @@ module Scenic
|
|
|
2
2
|
module Generators
|
|
3
3
|
class ViewGenerator
|
|
4
4
|
def self.source_root: (String?) -> void
|
|
5
|
-
def plural_name: -> String
|
|
6
|
-
def plural_file_name: -> String
|
|
7
5
|
def migration_template: (String, String) -> void
|
|
6
|
+
def destination_root: -> String
|
|
7
|
+
def find_in_source_paths: (String) -> String
|
|
8
|
+
def options: -> Hash[Symbol, untyped]
|
|
9
|
+
|
|
10
|
+
def create_view_definition: -> void
|
|
11
|
+
def version: -> Integer
|
|
8
12
|
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def materialized?: -> bool
|
|
16
|
+
def plural_name: -> String
|
|
17
|
+
def plural_file_name: -> String
|
|
9
18
|
def creating_new_view?: -> bool
|
|
19
|
+
def destroying?: -> bool
|
|
10
20
|
def destroying_initial_view?: -> bool
|
|
11
|
-
def version: -> String
|
|
12
21
|
end
|
|
13
22
|
end
|
|
14
23
|
end
|
data/sig/scenic/cascade/view.rbs
CHANGED
|
@@ -8,10 +8,15 @@ module Scenic
|
|
|
8
8
|
|
|
9
9
|
class ViewWithVersion < Scenic::Cascade::View
|
|
10
10
|
attr_reader version: Integer
|
|
11
|
+
attr_reader database_name: String
|
|
11
12
|
|
|
12
|
-
def initialize: (name: String, version: Integer, materialized: bool) -> void
|
|
13
|
+
def initialize: (name: String, version: Integer, materialized: bool, ?database_name: String) -> void
|
|
13
14
|
|
|
14
15
|
def ==: (_ViewWithVersionLike) -> bool
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def formatted_version: -> String
|
|
15
20
|
end
|
|
16
21
|
end
|
|
17
22
|
end
|
data/sig/scenic/cascade.rbs
CHANGED
|
@@ -2,7 +2,7 @@ module Scenic
|
|
|
2
2
|
module Cascade
|
|
3
3
|
VERSION: String
|
|
4
4
|
|
|
5
|
-
def self.find_definitions_of: (String) -> Scenic::Definition
|
|
5
|
+
def self.find_definitions_of: (String) -> Array[Scenic::Definition]
|
|
6
6
|
def self.find_latest_definition_of: (String) -> Scenic::Definition
|
|
7
7
|
|
|
8
8
|
def self.view_dependents_of: (String, ?recursive: bool) -> Array[Dependency]
|
data/sig/scenic/definition.rbs
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scenic-cascade
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Akiomi Kamakura
|
|
@@ -44,6 +44,7 @@ files:
|
|
|
44
44
|
- README.md
|
|
45
45
|
- Rakefile
|
|
46
46
|
- Steepfile
|
|
47
|
+
- codecov.yml
|
|
47
48
|
- docker-compose.yml
|
|
48
49
|
- lib/generators/scenic/view/cascade/USAGE
|
|
49
50
|
- lib/generators/scenic/view/cascade/cascade_generator.rb
|