scenic 1.4.1 → 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 +5 -5
- data/.hound.yml +2 -4
- data/.rubocop.yml +129 -0
- data/.travis.yml +11 -17
- data/Appraisals +14 -21
- data/CODE_OF_CONDUCT.md +76 -0
- data/CONTRIBUTING.md +3 -7
- data/Gemfile +1 -1
- data/NEWS.md +32 -13
- data/README.md +15 -16
- data/Rakefile +2 -2
- data/gemfiles/rails42.gemfile +1 -1
- data/gemfiles/rails50.gemfile +1 -1
- data/gemfiles/rails51.gemfile +1 -1
- data/gemfiles/rails52.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile +3 -3
- data/lib/generators/scenic/materializable.rb +9 -0
- data/lib/generators/scenic/model/model_generator.rb +2 -2
- data/lib/generators/scenic/view/USAGE +1 -0
- data/lib/generators/scenic/view/templates/db/migrate/create_view.erb +1 -1
- data/lib/generators/scenic/view/templates/db/migrate/update_view.erb +1 -1
- data/lib/generators/scenic/view/view_generator.rb +13 -5
- data/lib/scenic/adapters/postgres.rb +14 -4
- data/lib/scenic/adapters/postgres/refresh_dependencies.rb +12 -2
- data/lib/scenic/adapters/postgres/views.rb +10 -1
- data/lib/scenic/schema_dumper.rb +2 -2
- data/lib/scenic/statements.rb +24 -6
- data/lib/scenic/version.rb +1 -1
- data/lib/scenic/view.rb +1 -2
- data/scenic.gemspec +22 -23
- data/spec/acceptance/user_manages_views_spec.rb +2 -1
- data/spec/dummy/app/models/application_record.rb +5 -0
- data/spec/generators/scenic/model/model_generator_spec.rb +1 -1
- data/spec/generators/scenic/view/view_generator_spec.rb +1 -1
- data/spec/scenic/adapters/postgres/refresh_dependencies_spec.rb +60 -26
- data/spec/scenic/adapters/postgres_spec.rb +2 -2
- data/spec/scenic/definition_spec.rb +1 -1
- data/spec/scenic/schema_dumper_spec.rb +17 -2
- data/spec/scenic/statements_spec.rb +48 -13
- data/spec/spec_helper.rb +1 -1
- data/spec/support/generator_spec_setup.rb +1 -1
- metadata +15 -13
- data/gemfiles/rails40.gemfile +0 -8
- data/gemfiles/rails41.gemfile +0 -8
@@ -1,4 +1,5 @@
|
|
1
1
|
require "acceptance_helper"
|
2
|
+
require "English"
|
2
3
|
|
3
4
|
describe "User manages views" do
|
4
5
|
it "handles simple views" do
|
@@ -56,7 +57,7 @@ describe "User manages views" do
|
|
56
57
|
|
57
58
|
def successfully(command)
|
58
59
|
`RAILS_ENV=test #{command}`
|
59
|
-
expect(
|
60
|
+
expect($CHILD_STATUS.exitstatus).to eq(0), "'#{command}' was unsuccessful"
|
60
61
|
end
|
61
62
|
|
62
63
|
def write_definition(file, contents)
|
@@ -31,7 +31,7 @@ describe Scenic::Generators::ViewGenerator, :generator do
|
|
31
31
|
|
32
32
|
run_generator ["aired_episode", "--materialized"]
|
33
33
|
migration = migration_file(
|
34
|
-
"db/migrate/update_aired_episodes_to_version_2.rb"
|
34
|
+
"db/migrate/update_aired_episodes_to_version_2.rb",
|
35
35
|
)
|
36
36
|
expect(migration).to contain "materialized: true"
|
37
37
|
end
|
@@ -3,39 +3,73 @@ require "spec_helper"
|
|
3
3
|
module Scenic
|
4
4
|
module Adapters
|
5
5
|
describe Postgres::RefreshDependencies, :db do
|
6
|
-
|
7
|
-
adapter
|
6
|
+
context "view has dependencies" do
|
7
|
+
let(:adapter) { Postgres.new }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
before do
|
10
|
+
adapter.create_materialized_view(
|
11
|
+
"first",
|
12
|
+
"SELECT text 'hi' AS greeting",
|
13
|
+
)
|
14
|
+
adapter.create_materialized_view(
|
15
|
+
"second",
|
16
|
+
"SELECT * FROM first",
|
17
|
+
)
|
18
|
+
adapter.create_materialized_view(
|
19
|
+
"third",
|
20
|
+
"SELECT * FROM first UNION SELECT * FROM second",
|
21
|
+
)
|
22
|
+
adapter.create_materialized_view(
|
23
|
+
"fourth_1",
|
24
|
+
"SELECT * FROM third",
|
25
|
+
)
|
26
|
+
adapter.create_materialized_view(
|
27
|
+
"x_fourth",
|
28
|
+
"SELECT * FROM fourth_1",
|
29
|
+
)
|
30
|
+
adapter.create_materialized_view(
|
31
|
+
"fourth",
|
32
|
+
"SELECT * FROM fourth_1 UNION SELECT * FROM x_fourth",
|
33
|
+
)
|
13
34
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
35
|
+
expect(adapter).to receive(:refresh_materialized_view)
|
36
|
+
.with("public.first").ordered
|
37
|
+
expect(adapter).to receive(:refresh_materialized_view)
|
38
|
+
.with("public.second").ordered
|
39
|
+
expect(adapter).to receive(:refresh_materialized_view)
|
40
|
+
.with("public.third").ordered
|
41
|
+
expect(adapter).to receive(:refresh_materialized_view)
|
42
|
+
.with("public.fourth_1").ordered
|
43
|
+
expect(adapter).to receive(:refresh_materialized_view)
|
44
|
+
.with("public.x_fourth").ordered
|
45
|
+
end
|
18
46
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
)
|
47
|
+
it "refreshes in the right order when called without namespace" do
|
48
|
+
described_class.call(:fourth, adapter, ActiveRecord::Base.connection)
|
49
|
+
end
|
23
50
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
51
|
+
it "refreshes in the right order when called with namespace" do
|
52
|
+
described_class.call(
|
53
|
+
"public.fourth",
|
54
|
+
adapter,
|
55
|
+
ActiveRecord::Base.connection,
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
31
59
|
|
32
|
-
|
33
|
-
|
60
|
+
context "view has no dependencies" do
|
61
|
+
it "does not raise an error" do
|
62
|
+
adapter = Postgres.new
|
34
63
|
|
35
|
-
|
36
|
-
|
64
|
+
adapter.create_materialized_view(
|
65
|
+
"first",
|
66
|
+
"SELECT text 'hi' AS greeting",
|
67
|
+
)
|
37
68
|
|
38
|
-
|
69
|
+
expect {
|
70
|
+
described_class.call(:first, adapter, ActiveRecord::Base.connection)
|
71
|
+
}.not_to raise_error
|
72
|
+
end
|
39
73
|
end
|
40
74
|
end
|
41
75
|
end
|
@@ -104,8 +104,8 @@ module Scenic
|
|
104
104
|
connection = double("Connection").as_null_object
|
105
105
|
connectable = double("Connectable", connection: connection)
|
106
106
|
adapter = Postgres.new(connectable)
|
107
|
-
expect(Scenic::Adapters::Postgres::RefreshDependencies)
|
108
|
-
to receive(:call).with(:tests, adapter, connection)
|
107
|
+
expect(Scenic::Adapters::Postgres::RefreshDependencies)
|
108
|
+
.to receive(:call).with(:tests, adapter, connection)
|
109
109
|
adapter.refresh_materialized_view(:tests, cascade: true)
|
110
110
|
end
|
111
111
|
|
@@ -22,7 +22,7 @@ module Scenic
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "path" do
|
25
|
-
it "returns a sql file in db/views with padded version and view name"
|
25
|
+
it "returns a sql file in db/views with padded version and view name" do
|
26
26
|
expected = "db/views/searches_v01.sql"
|
27
27
|
|
28
28
|
definition = Definition.new("searches", 1)
|
@@ -15,7 +15,8 @@ describe Scenic::SchemaDumper, :db do
|
|
15
15
|
ActiveRecord::SchemaDumper.dump(Search.connection, stream)
|
16
16
|
|
17
17
|
output = stream.string
|
18
|
-
|
18
|
+
|
19
|
+
expect(output).to include 'create_view "searches", sql_definition: <<-SQL'
|
19
20
|
expect(output).to include view_definition
|
20
21
|
|
21
22
|
Search.connection.drop_view :searches
|
@@ -25,6 +26,19 @@ describe Scenic::SchemaDumper, :db do
|
|
25
26
|
expect(Search.first.haystack).to eq "needle"
|
26
27
|
end
|
27
28
|
|
29
|
+
it "dumps a create_view for a materialized view in the database" do
|
30
|
+
view_definition = "SELECT 'needle'::text AS haystack"
|
31
|
+
Search.connection.create_view :searches, materialized: true, sql_definition: view_definition
|
32
|
+
stream = StringIO.new
|
33
|
+
|
34
|
+
ActiveRecord::SchemaDumper.dump(Search.connection, stream)
|
35
|
+
|
36
|
+
output = stream.string
|
37
|
+
|
38
|
+
expect(output).to include 'create_view "searches", materialized: true, sql_definition: <<-SQL'
|
39
|
+
expect(output).to include view_definition
|
40
|
+
end
|
41
|
+
|
28
42
|
context "with views in non public schemas" do
|
29
43
|
it "dumps a create_view including namespace for a view in the database" do
|
30
44
|
view_definition = "SELECT 'needle'::text AS haystack"
|
@@ -79,7 +93,8 @@ describe Scenic::SchemaDumper, :db do
|
|
79
93
|
it "dumps a create_view for a view in the database" do
|
80
94
|
view_definition = "SELECT 'needle'::text AS haystack"
|
81
95
|
Search.connection.execute(
|
82
|
-
"CREATE SCHEMA scenic; SET search_path TO scenic, public"
|
96
|
+
"CREATE SCHEMA scenic; SET search_path TO scenic, public",
|
97
|
+
)
|
83
98
|
Search.connection.create_view 'scenic."search in a haystack"',
|
84
99
|
sql_definition: view_definition
|
85
100
|
stream = StringIO.new
|
@@ -33,14 +33,14 @@ module Scenic
|
|
33
33
|
it "creates version 1 of the view if neither version nor sql_defintion are provided" do
|
34
34
|
version = 1
|
35
35
|
definition_stub = instance_double("Definition", to_sql: "foo")
|
36
|
-
allow(Definition).to receive(:new)
|
37
|
-
with(:views, version)
|
38
|
-
and_return(definition_stub)
|
36
|
+
allow(Definition).to receive(:new)
|
37
|
+
.with(:views, version)
|
38
|
+
.and_return(definition_stub)
|
39
39
|
|
40
40
|
connection.create_view :views
|
41
41
|
|
42
|
-
expect(Scenic.database).to have_received(:create_view)
|
43
|
-
with(:views, definition_stub.to_sql)
|
42
|
+
expect(Scenic.database).to have_received(:create_view)
|
43
|
+
.with(:views, definition_stub.to_sql)
|
44
44
|
end
|
45
45
|
|
46
46
|
it "raises an error if both version and sql_defintion are provided" do
|
@@ -52,12 +52,29 @@ module Scenic
|
|
52
52
|
|
53
53
|
describe "create_view :materialized" do
|
54
54
|
it "sends the create_materialized_view message" do
|
55
|
-
|
56
|
-
|
55
|
+
definition = instance_double("Scenic::Definition", to_sql: "definition")
|
56
|
+
allow(Definition).to receive(:new).and_return(definition)
|
57
57
|
|
58
58
|
connection.create_view(:views, version: 1, materialized: true)
|
59
59
|
|
60
60
|
expect(Scenic.database).to have_received(:create_materialized_view)
|
61
|
+
.with(:views, definition.to_sql, no_data: false)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "create_view :materialized with :no_data" do
|
66
|
+
it "sends the create_materialized_view message" do
|
67
|
+
definition = instance_double("Scenic::Definition", to_sql: "definition")
|
68
|
+
allow(Definition).to receive(:new).and_return(definition)
|
69
|
+
|
70
|
+
connection.create_view(
|
71
|
+
:views,
|
72
|
+
version: 1,
|
73
|
+
materialized: { no_data: true },
|
74
|
+
)
|
75
|
+
|
76
|
+
expect(Scenic.database).to have_received(:create_materialized_view)
|
77
|
+
.with(:views, definition.to_sql, no_data: true)
|
61
78
|
end
|
62
79
|
end
|
63
80
|
|
@@ -95,8 +112,8 @@ module Scenic
|
|
95
112
|
|
96
113
|
connection.update_view(:name, sql_definition: sql_definition)
|
97
114
|
|
98
|
-
expect(Scenic.database).to have_received(:update_view)
|
99
|
-
with(:name, sql_definition)
|
115
|
+
expect(Scenic.database).to have_received(:update_view)
|
116
|
+
.with(:name, sql_definition)
|
100
117
|
end
|
101
118
|
|
102
119
|
it "updates the materialized view in the database" do
|
@@ -107,14 +124,31 @@ module Scenic
|
|
107
124
|
|
108
125
|
connection.update_view(:name, version: 3, materialized: true)
|
109
126
|
|
110
|
-
expect(Scenic.database).to have_received(:update_materialized_view)
|
111
|
-
with(:name, definition.to_sql)
|
127
|
+
expect(Scenic.database).to have_received(:update_materialized_view)
|
128
|
+
.with(:name, definition.to_sql, no_data: false)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "updates the materialized view in the database with NO DATA" do
|
132
|
+
definition = instance_double("Definition", to_sql: "definition")
|
133
|
+
allow(Definition).to receive(:new)
|
134
|
+
.with(:name, 3)
|
135
|
+
.and_return(definition)
|
136
|
+
|
137
|
+
connection.update_view(
|
138
|
+
:name,
|
139
|
+
version: 3,
|
140
|
+
materialized: { no_data: true },
|
141
|
+
)
|
142
|
+
|
143
|
+
expect(Scenic.database).to have_received(:update_materialized_view)
|
144
|
+
.with(:name, definition.to_sql, no_data: true)
|
112
145
|
end
|
113
146
|
|
114
147
|
it "raises an error if not supplied a version or sql_defintion" do
|
115
148
|
expect { connection.update_view :views }.to raise_error(
|
116
149
|
ArgumentError,
|
117
|
-
/sql_definition or version must be specified
|
150
|
+
/sql_definition or version must be specified/,
|
151
|
+
)
|
118
152
|
end
|
119
153
|
|
120
154
|
it "raises an error if both version and sql_defintion are provided" do
|
@@ -122,7 +156,8 @@ module Scenic
|
|
122
156
|
connection.update_view(
|
123
157
|
:views,
|
124
158
|
version: 1,
|
125
|
-
sql_definition: "a defintion"
|
159
|
+
sql_definition: "a defintion",
|
160
|
+
)
|
126
161
|
end.to raise_error ArgumentError, /cannot both be set/
|
127
162
|
end
|
128
163
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
ENV["RAILS_ENV"] = "test"
|
2
2
|
require "database_cleaner"
|
3
3
|
|
4
|
-
require File.expand_path("
|
4
|
+
require File.expand_path("dummy/config/environment", __dir__)
|
5
5
|
require "support/generator_spec_setup"
|
6
6
|
require "support/view_definition_helpers"
|
7
7
|
|
@@ -5,7 +5,7 @@ require "ammeter/init"
|
|
5
5
|
|
6
6
|
RSpec.configure do |config|
|
7
7
|
config.before(:example, :generator) do
|
8
|
-
fake_rails_root = File.expand_path("
|
8
|
+
fake_rails_root = File.expand_path("../../tmp", __dir__)
|
9
9
|
allow(Rails).to receive(:root).and_return(Pathname.new(fake_rails_root))
|
10
10
|
|
11
11
|
destination fake_rails_root
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scenic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Prior
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-02-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: appraisal
|
@@ -85,16 +85,16 @@ dependencies:
|
|
85
85
|
name: pg
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '0'
|
90
|
+
version: '0.19'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '0'
|
97
|
+
version: '0.19'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: pry
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,9 +191,11 @@ extra_rdoc_files: []
|
|
191
191
|
files:
|
192
192
|
- ".gitignore"
|
193
193
|
- ".hound.yml"
|
194
|
+
- ".rubocop.yml"
|
194
195
|
- ".travis.yml"
|
195
196
|
- ".yardopts"
|
196
197
|
- Appraisals
|
198
|
+
- CODE_OF_CONDUCT.md
|
197
199
|
- CONTRIBUTING.md
|
198
200
|
- Gemfile
|
199
201
|
- LICENSE.txt
|
@@ -205,11 +207,10 @@ files:
|
|
205
207
|
- bin/rspec
|
206
208
|
- bin/setup
|
207
209
|
- bin/yard
|
208
|
-
- gemfiles/rails40.gemfile
|
209
|
-
- gemfiles/rails41.gemfile
|
210
210
|
- gemfiles/rails42.gemfile
|
211
211
|
- gemfiles/rails50.gemfile
|
212
212
|
- gemfiles/rails51.gemfile
|
213
|
+
- gemfiles/rails52.gemfile
|
213
214
|
- gemfiles/rails_edge.gemfile
|
214
215
|
- lib/generators/scenic/generators.rb
|
215
216
|
- lib/generators/scenic/materializable.rb
|
@@ -243,6 +244,7 @@ files:
|
|
243
244
|
- spec/acceptance_helper.rb
|
244
245
|
- spec/dummy/.gitignore
|
245
246
|
- spec/dummy/Rakefile
|
247
|
+
- spec/dummy/app/models/application_record.rb
|
246
248
|
- spec/dummy/bin/bundle
|
247
249
|
- spec/dummy/bin/rails
|
248
250
|
- spec/dummy/bin/rake
|
@@ -269,7 +271,7 @@ files:
|
|
269
271
|
- spec/spec_helper.rb
|
270
272
|
- spec/support/generator_spec_setup.rb
|
271
273
|
- spec/support/view_definition_helpers.rb
|
272
|
-
homepage: https://github.com/
|
274
|
+
homepage: https://github.com/scenic-views/scenic
|
273
275
|
licenses:
|
274
276
|
- MIT
|
275
277
|
metadata: {}
|
@@ -279,17 +281,16 @@ require_paths:
|
|
279
281
|
- lib
|
280
282
|
required_ruby_version: !ruby/object:Gem::Requirement
|
281
283
|
requirements:
|
282
|
-
- - "
|
284
|
+
- - ">="
|
283
285
|
- !ruby/object:Gem::Version
|
284
|
-
version:
|
286
|
+
version: 2.3.0
|
285
287
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
286
288
|
requirements:
|
287
289
|
- - ">="
|
288
290
|
- !ruby/object:Gem::Version
|
289
291
|
version: '0'
|
290
292
|
requirements: []
|
291
|
-
|
292
|
-
rubygems_version: 2.6.14
|
293
|
+
rubygems_version: 3.0.1
|
293
294
|
signing_key:
|
294
295
|
specification_version: 4
|
295
296
|
summary: Support for database views in Rails migrations
|
@@ -298,6 +299,7 @@ test_files:
|
|
298
299
|
- spec/acceptance_helper.rb
|
299
300
|
- spec/dummy/.gitignore
|
300
301
|
- spec/dummy/Rakefile
|
302
|
+
- spec/dummy/app/models/application_record.rb
|
301
303
|
- spec/dummy/bin/bundle
|
302
304
|
- spec/dummy/bin/rails
|
303
305
|
- spec/dummy/bin/rake
|
data/gemfiles/rails40.gemfile
DELETED