scenic 1.6.0 → 1.8.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 +24 -4
- data/CHANGELOG.md +25 -8
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +3 -3
- data/README.md +29 -29
- data/Rakefile +1 -1
- data/bin/standardrb +27 -0
- data/lib/generators/scenic/materializable.rb +9 -0
- data/lib/generators/scenic/model/model_generator.rb +9 -7
- data/lib/generators/scenic/model/templates/model.erb +4 -0
- data/lib/generators/scenic/view/templates/db/migrate/update_view.erb +3 -2
- data/lib/generators/scenic/view/view_generator.rb +5 -5
- data/lib/scenic/adapters/postgres/indexes.rb +1 -1
- data/lib/scenic/adapters/postgres/refresh_dependencies.rb +3 -3
- data/lib/scenic/adapters/postgres/views.rb +5 -5
- data/lib/scenic/adapters/postgres.rb +28 -3
- data/lib/scenic/definition.rb +1 -1
- data/lib/scenic/statements.rb +5 -5
- data/lib/scenic/version.rb +1 -1
- data/lib/scenic/view.rb +1 -1
- data/scenic.gemspec +10 -10
- data/spec/dummy/Rakefile +5 -5
- data/spec/dummy/bin/bundle +2 -2
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/db/migrate/20220112154220_add_pg_stat_statements_extension.rb +1 -1
- data/spec/dummy/db/schema.rb +0 -2
- data/spec/generators/scenic/model/model_generator_spec.rb +9 -1
- data/spec/generators/scenic/view/view_generator_spec.rb +13 -1
- data/spec/integration/revert_spec.rb +1 -1
- data/spec/scenic/adapters/postgres/connection_spec.rb +1 -1
- data/spec/scenic/adapters/postgres/refresh_dependencies_spec.rb +9 -9
- data/spec/scenic/adapters/postgres_spec.rb +52 -6
- data/spec/scenic/command_recorder/statement_arguments_spec.rb +4 -4
- data/spec/scenic/command_recorder_spec.rb +12 -12
- data/spec/scenic/schema_dumper_spec.rb +6 -6
- data/spec/scenic/statements_spec.rb +4 -4
- data/spec/support/generator_spec_setup.rb +2 -2
- data/spec/support/view_definition_helpers.rb +1 -1
- metadata +19 -40
- data/.hound.yml +0 -2
- data/.rubocop.yml +0 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9085d1f24783682a52d5874ce82bf44543b2a60d6edbfd72b026bf84b4bc0ab
|
4
|
+
data.tar.gz: fd7efd82eb88c0550c410f50e363db99eaf3e7fc6b5e3ac4eb374bd681afd7cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0c624619ae62c1c9e8186b8cde870e81dde6f47c8eacc93faad863c38d8fc57c3f15b81c0f1a515bad57318d2bef56f8a57b83934346542e4fbe9bbc6315209
|
7
|
+
data.tar.gz: 6a4e9ae269ee6ffb86a4e23fa1d0e741ee2b3ed12fabca23696d2d462c4359d9fceea53ffbf696f72357bfa10a4abf66ede72b1bfa1a37ce7fcf5fdc5f6aeca7
|
data/.github/workflows/ci.yml
CHANGED
@@ -7,15 +7,35 @@ on:
|
|
7
7
|
branches: "*"
|
8
8
|
|
9
9
|
jobs:
|
10
|
+
standard:
|
11
|
+
name: Lint with Standard
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- name: Checkout
|
16
|
+
uses: actions/checkout@v3
|
17
|
+
|
18
|
+
- name: Run standardrb
|
19
|
+
uses: standardrb/standard-ruby-action@f533e61f461ccb766b2d9c235abf59be02aea793
|
20
|
+
env:
|
21
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
22
|
+
|
23
|
+
permissions:
|
24
|
+
checks: write
|
25
|
+
contents: read
|
26
|
+
|
10
27
|
build:
|
11
28
|
name: Ruby ${{ matrix.ruby }}, Rails ${{ matrix.rails }}
|
12
29
|
|
13
30
|
strategy:
|
14
31
|
fail-fast: false
|
15
32
|
matrix:
|
16
|
-
ruby: ["2.7", "3.0", "3.1"]
|
17
|
-
rails: ["6.1", "7.0"
|
33
|
+
ruby: ["2.7", "3.0", "3.1", "3.2"]
|
34
|
+
rails: ["6.1", "7.0"]
|
18
35
|
continue-on-error: [false]
|
36
|
+
exclude:
|
37
|
+
- ruby: "3.2"
|
38
|
+
rails: "6.1"
|
19
39
|
|
20
40
|
runs-on: ubuntu-latest
|
21
41
|
|
@@ -40,7 +60,7 @@ jobs:
|
|
40
60
|
|
41
61
|
steps:
|
42
62
|
- name: Checkout
|
43
|
-
uses: actions/checkout@
|
63
|
+
uses: actions/checkout@v3
|
44
64
|
|
45
65
|
- name: Install Ruby ${{ matrix.ruby }}
|
46
66
|
uses: ruby/setup-ruby@v1
|
@@ -54,7 +74,7 @@ jobs:
|
|
54
74
|
run: bundle lock
|
55
75
|
|
56
76
|
- name: Cache dependencies
|
57
|
-
uses: actions/cache@
|
77
|
+
uses: actions/cache@v3
|
58
78
|
with:
|
59
79
|
path: vendor/bundle
|
60
80
|
key: bundle-${{ hashFiles('Gemfile.lock') }}
|
data/CHANGELOG.md
CHANGED
@@ -5,21 +5,38 @@ changelog, see the [commits] for each version via the version links.
|
|
5
5
|
|
6
6
|
[commits]: https://github.com/scenic-views/scenic/commits/master
|
7
7
|
|
8
|
-
## [1.
|
8
|
+
## [1.8.0] - March 28, 2024
|
9
9
|
|
10
|
-
|
10
|
+
[1.8.0]: https://github.com/scenic-views/scenic/compare/v1.7.0...v1.8.0
|
11
|
+
|
12
|
+
### Added
|
11
13
|
|
12
|
-
*
|
14
|
+
* Added `#populated?` to check the state of materialized views - *Daisuke
|
15
|
+
Fujimura*, *Dr Nic Williams*
|
13
16
|
|
14
|
-
|
17
|
+
## [1.7.0] - December 8, 2022
|
15
18
|
|
16
|
-
|
19
|
+
[1.7.0]: https://github.com/scenic-views/scenic/compare/v1.6.0...v1.7.0
|
17
20
|
|
18
|
-
|
21
|
+
### Added
|
22
|
+
|
23
|
+
* Added the `--replace` CLI flag to generate a migration that uses the
|
24
|
+
`replace_view` schema statement - *Dan Hixon*
|
19
25
|
|
20
|
-
|
26
|
+
### Fixed
|
27
|
+
|
28
|
+
* Fixed deprecation notice from newer versions of ERB when using scenic
|
29
|
+
generators - *Ali Ismayilov*
|
30
|
+
|
31
|
+
## [1.6.0] - February 13, 2022
|
32
|
+
|
33
|
+
[1.6.0]: https://github.com/scenic-views/scenic/compare/v1.5.5...v1.6.0
|
34
|
+
|
35
|
+
### Fixed
|
21
36
|
|
22
|
-
|
37
|
+
* Exclude pg_stat_statements_info (#349) 76bface - *Caleb Hearth*
|
38
|
+
* Fix serialization of views with backslashes c625d1b - *Ben Sheldon*
|
39
|
+
* Handle ActiveRecord table name prefix and suffix b1544dc - *Derek Prior*
|
23
40
|
|
24
41
|
## [1.5.5] - December 15, 2021
|
25
42
|
|
data/CONTRIBUTING.md
CHANGED
@@ -13,6 +13,7 @@ agree to abide by our [code of conduct].
|
|
13
13
|
3. Run `rake` to verify that the tests pass against the version of Rails you are
|
14
14
|
running locally.
|
15
15
|
4. Make your change with new passing tests, following existing style.
|
16
|
+
5. Run `standardrb --fix` to ensure your code is formatted correctly.
|
16
17
|
5. Write a [good commit message], push your fork, and submit a pull request.
|
17
18
|
6. CI will run the test suite on all configured versions of Ruby and Rails.
|
18
19
|
Address any failures.
|
data/Gemfile
CHANGED
@@ -5,10 +5,10 @@ gemspec
|
|
5
5
|
|
6
6
|
rails_version = ENV.fetch("RAILS_VERSION", "6.1")
|
7
7
|
|
8
|
-
if rails_version == "master"
|
9
|
-
|
8
|
+
rails_constraint = if rails_version == "master"
|
9
|
+
{github: "rails/rails"}
|
10
10
|
else
|
11
|
-
|
11
|
+
"~> #{rails_version}.0"
|
12
12
|
end
|
13
13
|
|
14
14
|
gem "rails", rails_constraint
|
data/README.md
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
|
5
5
|
[](https://github.com/scenic-views/scenic/actions/workflows/ci.yml)
|
6
6
|
[](http://inch-ci.org/github/scenic-views/scenic)
|
7
|
-
[](https://houndci.com)
|
8
7
|
|
9
8
|
Scenic adds methods to `ActiveRecord::Migration` to create and manage database
|
10
9
|
views in Rails.
|
@@ -86,36 +85,24 @@ schema in the new definition and run the `update_view` migration.
|
|
86
85
|
|
87
86
|
## What if I want to change a view without dropping it?
|
88
87
|
|
89
|
-
The `update_view` statement used by default will drop your view then create
|
90
|
-
|
88
|
+
The `update_view` statement used by default will drop your view then create a
|
89
|
+
new version of it. This may not be desirable when you have complicated
|
90
|
+
hierarchies of dependent views.
|
91
91
|
|
92
|
-
|
93
|
-
|
92
|
+
Scenic offers a `replace_view` schema statement, resulting in a `CREATE OR
|
93
|
+
REPLACE VIEW` SQL query which will update the supplied view in place, retaining
|
94
|
+
all dependencies. Materialized views cannot be replaced in this fashion.
|
94
95
|
|
95
|
-
You can
|
96
|
-
|
97
|
-
See Postgres documentation on how this works:
|
98
|
-
http://www.postgresql.org/docs/current/static/sql-createview.html
|
99
|
-
|
100
|
-
To start replacing a view run the generator like for a regular change:
|
96
|
+
You can generate a migration that uses the `replace_view` schema statement by
|
97
|
+
passing the `--replace` option to the `scenic:view` generator:
|
101
98
|
|
102
99
|
```sh
|
103
|
-
$ rails generate scenic:view search_results
|
100
|
+
$ rails generate scenic:view search_results --replace
|
104
101
|
create db/views/search_results_v02.sql
|
105
102
|
create db/migrate/[TIMESTAMP]_update_search_results_to_version_2.rb
|
106
103
|
```
|
107
104
|
|
108
|
-
|
109
|
-
|
110
|
-
```ruby
|
111
|
-
class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
|
112
|
-
def change
|
113
|
-
update_view :search_results, version: 2, revert_to_version: 1
|
114
|
-
end
|
115
|
-
end
|
116
|
-
```
|
117
|
-
|
118
|
-
Update it to use replace view:
|
105
|
+
The migration will look something like this:
|
119
106
|
|
120
107
|
```ruby
|
121
108
|
class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
|
@@ -125,8 +112,6 @@ class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
|
|
125
112
|
end
|
126
113
|
```
|
127
114
|
|
128
|
-
Now you can run the migration like normal.
|
129
|
-
|
130
115
|
## Can I use this view to back a model?
|
131
116
|
|
132
117
|
You bet! Using view-backed models can help promote concepts hidden in your
|
@@ -138,6 +123,11 @@ no different than a table.
|
|
138
123
|
class SearchResult < ApplicationRecord
|
139
124
|
belongs_to :searchable, polymorphic: true
|
140
125
|
|
126
|
+
# If you want to be able to call +Model.find+, you
|
127
|
+
# must declare the primary key. It can not be
|
128
|
+
# inferred from column information.
|
129
|
+
# self.primary_key = :id
|
130
|
+
|
141
131
|
# this isn't strictly necessary, but it will prevent
|
142
132
|
# rails from calling save, which would fail anyway.
|
143
133
|
def readonly?
|
@@ -252,16 +242,26 @@ accommodate adapter gems.
|
|
252
242
|
We are aware of the following existing adapter libraries for Scenic which may
|
253
243
|
meet your needs:
|
254
244
|
|
255
|
-
* [scenic_sqlite_adapter](https://github.com/pdebelak/scenic_sqlite_adapter)
|
256
|
-
* [scenic-mysql_adapter](https://github.com/EmpaticoOrg/scenic-mysql_adapter)
|
257
|
-
* [scenic-sqlserver-adapter](https://github.com/ClickMechanic/scenic_sqlserver_adapter)
|
258
|
-
* [scenic-oracle_adapter](https://github.com/cdinger/scenic-oracle_adapter)
|
245
|
+
* [`scenic_sqlite_adapter`](<https://github.com/pdebelak/scenic_sqlite_adapter>)
|
246
|
+
* [`scenic-mysql_adapter`](<https://github.com/EmpaticoOrg/scenic-mysql_adapter>)
|
247
|
+
* [`scenic-sqlserver-adapter`](<https://github.com/ClickMechanic/scenic_sqlserver_adapter>)
|
248
|
+
* [`scenic-oracle_adapter`](<https://github.com/cdinger/scenic-oracle_adapter>)
|
259
249
|
|
260
250
|
Please note that the maintainers of Scenic make no assertions about the
|
261
251
|
quality or security of the above adapters.
|
262
252
|
|
253
|
+
**Related projects**
|
254
|
+
|
255
|
+
- [`fx`](<https://github.com/teoljungberg/fx>) Versioned database functions and
|
256
|
+
triggers for Rails
|
257
|
+
|
263
258
|
## About
|
264
259
|
|
260
|
+
Scenic is used by some popular open source Rails apps:
|
261
|
+
[Mastodon](<https://github.com/mastodon/mastodon/>),
|
262
|
+
[Code.org](<https://github.com/code-dot-org/code-dot-org>), and
|
263
|
+
[Lobste.rs](<https://github.com/lobsters/lobsters/>).
|
264
|
+
|
265
265
|
Scenic is maintained by [Derek Prior], [Caleb Hearth], and you, our
|
266
266
|
contributors.
|
267
267
|
|
data/Rakefile
CHANGED
data/bin/standardrb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'standardrb' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("standard", "standardrb")
|
@@ -15,6 +15,11 @@ module Scenic
|
|
15
15
|
required: false,
|
16
16
|
desc: "Adds WITH NO DATA when materialized view creates/updates",
|
17
17
|
default: false
|
18
|
+
class_option :replace,
|
19
|
+
type: :boolean,
|
20
|
+
required: false,
|
21
|
+
desc: "Uses replace_view instead of update_view",
|
22
|
+
default: false
|
18
23
|
end
|
19
24
|
|
20
25
|
private
|
@@ -23,6 +28,10 @@ module Scenic
|
|
23
28
|
options[:materialized]
|
24
29
|
end
|
25
30
|
|
31
|
+
def replace_view?
|
32
|
+
options[:replace]
|
33
|
+
end
|
34
|
+
|
26
35
|
def no_data?
|
27
36
|
options[:no_data]
|
28
37
|
end
|
@@ -15,7 +15,7 @@ module Scenic
|
|
15
15
|
[file_path.singularize],
|
16
16
|
options.merge(
|
17
17
|
fixture_replacement: false,
|
18
|
-
migration: false
|
18
|
+
migration: false
|
19
19
|
)
|
20
20
|
end
|
21
21
|
|
@@ -34,14 +34,16 @@ module Scenic
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def evaluate_template(source)
|
37
|
-
source
|
37
|
+
source = File.expand_path(find_in_source_paths(source.to_s))
|
38
38
|
context = instance_eval("binding", __FILE__, __LINE__)
|
39
|
-
|
39
|
+
|
40
|
+
erb = ERB.new(
|
40
41
|
::File.binread(source),
|
41
|
-
|
42
|
-
"
|
43
|
-
|
44
|
-
|
42
|
+
trim_mode: "-",
|
43
|
+
eoutvar: "@output_buffer"
|
44
|
+
)
|
45
|
+
|
46
|
+
erb.result(context)
|
45
47
|
end
|
46
48
|
|
47
49
|
def generating?
|
@@ -1,12 +1,13 @@
|
|
1
1
|
class <%= migration_class_name %> < <%= activerecord_migration_class %>
|
2
2
|
def change
|
3
|
+
<%- method_name = replace_view? ? 'replace_view' : 'update_view' -%>
|
3
4
|
<%- if materialized? -%>
|
4
|
-
|
5
|
+
<%= method_name %> <%= formatted_plural_name %>,
|
5
6
|
version: <%= version %>,
|
6
7
|
revert_to_version: <%= previous_version %>,
|
7
8
|
materialized: <%= no_data? ? "{ no_data: true }" : true %>
|
8
9
|
<%- else -%>
|
9
|
-
|
10
|
+
<%= method_name %> <%= formatted_plural_name %>, version: <%= version %>, revert_to_version: <%= previous_version %>
|
10
11
|
<%- end -%>
|
11
12
|
end
|
12
13
|
end
|
@@ -28,12 +28,12 @@ module Scenic
|
|
28
28
|
if creating_new_view? || destroying_initial_view?
|
29
29
|
migration_template(
|
30
30
|
"db/migrate/create_view.erb",
|
31
|
-
"db/migrate/create_#{plural_file_name}.rb"
|
31
|
+
"db/migrate/create_#{plural_file_name}.rb"
|
32
32
|
)
|
33
33
|
else
|
34
34
|
migration_template(
|
35
35
|
"db/migrate/update_view.erb",
|
36
|
-
"db/migrate/update_#{plural_file_name}_to_version_#{version}.rb"
|
36
|
+
"db/migrate/update_#{plural_file_name}_to_version_#{version}.rb"
|
37
37
|
)
|
38
38
|
end
|
39
39
|
end
|
@@ -56,7 +56,7 @@ module Scenic
|
|
56
56
|
|
57
57
|
def migration_class_name
|
58
58
|
if creating_new_view?
|
59
|
-
"Create#{class_name.tr(
|
59
|
+
"Create#{class_name.tr(".", "").pluralize}"
|
60
60
|
else
|
61
61
|
"Update#{class_name.pluralize}ToVersion#{version}"
|
62
62
|
end
|
@@ -73,7 +73,7 @@ module Scenic
|
|
73
73
|
|
74
74
|
private
|
75
75
|
|
76
|
-
|
76
|
+
alias_method :singular_name, :file_name
|
77
77
|
|
78
78
|
def file_name
|
79
79
|
super.tr(".", "_")
|
@@ -113,7 +113,7 @@ module Scenic
|
|
113
113
|
|
114
114
|
def create_view_options
|
115
115
|
if materialized?
|
116
|
-
", materialized: #{no_data? ?
|
116
|
+
", materialized: #{no_data? ? "{ no_data: true }" : true}"
|
117
117
|
else
|
118
118
|
""
|
119
119
|
end
|
@@ -17,7 +17,7 @@ module Scenic
|
|
17
17
|
dependencies.each do |dependency|
|
18
18
|
adapter.refresh_materialized_view(
|
19
19
|
dependency,
|
20
|
-
concurrently: concurrently
|
20
|
+
concurrently: concurrently
|
21
21
|
)
|
22
22
|
end
|
23
23
|
end
|
@@ -103,8 +103,8 @@ module Scenic
|
|
103
103
|
ORDER BY class_for_rewrite.relname;
|
104
104
|
SQL
|
105
105
|
|
106
|
-
private_constant
|
107
|
-
private_constant
|
106
|
+
private_constant :DependencyParser
|
107
|
+
private_constant :DEPENDENCY_SQL
|
108
108
|
|
109
109
|
def dependencies
|
110
110
|
raw_dependency_info = connection.select_rows(DEPENDENCY_SQL)
|
@@ -43,21 +43,21 @@ module Scenic
|
|
43
43
|
def to_scenic_view(result)
|
44
44
|
namespace, viewname = result.values_at "namespace", "viewname"
|
45
45
|
|
46
|
-
if namespace != "public"
|
47
|
-
|
46
|
+
namespaced_viewname = if namespace != "public"
|
47
|
+
"#{pg_identifier(namespace)}.#{pg_identifier(viewname)}"
|
48
48
|
else
|
49
|
-
|
49
|
+
pg_identifier(viewname)
|
50
50
|
end
|
51
51
|
|
52
52
|
Scenic::View.new(
|
53
53
|
name: namespaced_viewname,
|
54
54
|
definition: result["definition"].strip,
|
55
|
-
materialized: result["kind"] == "m"
|
55
|
+
materialized: result["kind"] == "m"
|
56
56
|
)
|
57
57
|
end
|
58
58
|
|
59
59
|
def pg_identifier(name)
|
60
|
-
return name if
|
60
|
+
return name if /^[a-zA-Z_][a-zA-Z0-9_]*$/.match?(name)
|
61
61
|
|
62
62
|
pgconn.quote_ident(name)
|
63
63
|
end
|
@@ -137,8 +137,8 @@ module Scenic
|
|
137
137
|
|
138
138
|
execute <<-SQL
|
139
139
|
CREATE MATERIALIZED VIEW #{quote_table_name(name)} AS
|
140
|
-
#{sql_definition.rstrip.chomp(
|
141
|
-
#{
|
140
|
+
#{sql_definition.rstrip.chomp(";")}
|
141
|
+
#{"WITH NO DATA" if no_data};
|
142
142
|
SQL
|
143
143
|
end
|
144
144
|
|
@@ -222,6 +222,31 @@ module Scenic
|
|
222
222
|
end
|
223
223
|
end
|
224
224
|
|
225
|
+
# True if supplied relation name is populated. Useful for checking the
|
226
|
+
# state of materialized views which may error if created `WITH NO DATA`
|
227
|
+
# and used before they are refreshed. True for all other relation types.
|
228
|
+
#
|
229
|
+
# @param name The name of the relation
|
230
|
+
#
|
231
|
+
# @raise [MaterializedViewsNotSupportedError] if the version of Postgres
|
232
|
+
# in use does not support materialized views.
|
233
|
+
#
|
234
|
+
# @return [boolean]
|
235
|
+
def populated?(name)
|
236
|
+
raise_unless_materialized_views_supported
|
237
|
+
|
238
|
+
schemaless_name = name.split(".").last
|
239
|
+
|
240
|
+
sql = "SELECT relispopulated FROM pg_class WHERE relname = '#{schemaless_name}'"
|
241
|
+
relations = execute(sql)
|
242
|
+
|
243
|
+
if relations.count.positive?
|
244
|
+
relations.first["relispopulated"].in?(["t", true])
|
245
|
+
else
|
246
|
+
false
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
225
250
|
private
|
226
251
|
|
227
252
|
attr_reader :connectable
|
@@ -248,7 +273,7 @@ module Scenic
|
|
248
273
|
name,
|
249
274
|
self,
|
250
275
|
connection,
|
251
|
-
concurrently: concurrently
|
276
|
+
concurrently: concurrently
|
252
277
|
)
|
253
278
|
end
|
254
279
|
end
|
data/lib/scenic/definition.rb
CHANGED
data/lib/scenic/statements.rb
CHANGED
@@ -26,7 +26,7 @@ module Scenic
|
|
26
26
|
if version.present? && sql_definition.present?
|
27
27
|
raise(
|
28
28
|
ArgumentError,
|
29
|
-
"sql_definition and version cannot both be set"
|
29
|
+
"sql_definition and version cannot both be set"
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
@@ -40,7 +40,7 @@ module Scenic
|
|
40
40
|
Scenic.database.create_materialized_view(
|
41
41
|
name,
|
42
42
|
sql_definition,
|
43
|
-
no_data: no_data(materialized)
|
43
|
+
no_data: no_data(materialized)
|
44
44
|
)
|
45
45
|
else
|
46
46
|
Scenic.database.create_view(name, sql_definition)
|
@@ -92,14 +92,14 @@ module Scenic
|
|
92
92
|
if version.blank? && sql_definition.blank?
|
93
93
|
raise(
|
94
94
|
ArgumentError,
|
95
|
-
"sql_definition or version must be specified"
|
95
|
+
"sql_definition or version must be specified"
|
96
96
|
)
|
97
97
|
end
|
98
98
|
|
99
99
|
if version.present? && sql_definition.present?
|
100
100
|
raise(
|
101
101
|
ArgumentError,
|
102
|
-
"sql_definition and version cannot both be set"
|
102
|
+
"sql_definition and version cannot both be set"
|
103
103
|
)
|
104
104
|
end
|
105
105
|
|
@@ -109,7 +109,7 @@ module Scenic
|
|
109
109
|
Scenic.database.update_materialized_view(
|
110
110
|
name,
|
111
111
|
sql_definition,
|
112
|
-
no_data: no_data(materialized)
|
112
|
+
no_data: no_data(materialized)
|
113
113
|
)
|
114
114
|
else
|
115
115
|
Scenic.database.update_view(name, sql_definition)
|
data/lib/scenic/version.rb
CHANGED
data/lib/scenic/view.rb
CHANGED
@@ -26,7 +26,7 @@ module Scenic
|
|
26
26
|
#
|
27
27
|
# @param name [String] The name of the view.
|
28
28
|
# @param definition [String] The SQL for the query that defines the view.
|
29
|
-
# @param materialized [
|
29
|
+
# @param materialized [Boolean] `true` if the view is materialized.
|
30
30
|
def initialize(name:, definition:, materialized:)
|
31
31
|
@name = name
|
32
32
|
@definition = definition
|
data/scenic.gemspec
CHANGED
@@ -3,20 +3,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
require "scenic/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
7
|
-
spec.version
|
8
|
-
spec.authors
|
9
|
-
spec.email
|
10
|
-
spec.summary
|
11
|
-
spec.description
|
6
|
+
spec.name = "scenic"
|
7
|
+
spec.version = Scenic::VERSION
|
8
|
+
spec.authors = ["Derek Prior", "Caleb Hearth"]
|
9
|
+
spec.email = ["derekprior@gmail.com", "caleb@calebhearth.com"]
|
10
|
+
spec.summary = "Support for database views in Rails migrations"
|
11
|
+
spec.description = <<-DESCRIPTION
|
12
12
|
Adds methods to ActiveRecord::Migration to create and manage database views
|
13
13
|
in Rails
|
14
14
|
DESCRIPTION
|
15
|
-
spec.homepage
|
16
|
-
spec.license
|
15
|
+
spec.homepage = "https://github.com/scenic-views/scenic"
|
16
|
+
spec.license = "MIT"
|
17
17
|
|
18
|
-
spec.files
|
19
|
-
spec.test_files = spec.files.grep(%r{^spec/})
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
19
|
spec.require_paths = ["lib"]
|
21
20
|
|
22
21
|
spec.add_development_dependency "bundler", ">= 1.5"
|
@@ -28,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
28
27
|
spec.add_development_dependency "ammeter", ">= 1.1.3"
|
29
28
|
spec.add_development_dependency "yard"
|
30
29
|
spec.add_development_dependency "redcarpet"
|
30
|
+
spec.add_development_dependency "standard"
|
31
31
|
|
32
32
|
spec.add_dependency "activerecord", ">= 4.0.0"
|
33
33
|
spec.add_dependency "railties", ">= 4.0.0"
|
data/spec/dummy/Rakefile
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
2
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
3
|
|
4
|
-
require File.expand_path(
|
4
|
+
require File.expand_path("../config/application", __FILE__)
|
5
5
|
|
6
6
|
Rails.application.load_tasks
|
7
7
|
|
8
|
-
unless Rake::Task.task_defined?(
|
9
|
-
desc
|
10
|
-
task
|
11
|
-
#no op
|
8
|
+
unless Rake::Task.task_defined?("db:environment:set")
|
9
|
+
desc "dummy task for rails versions where this task does not exist"
|
10
|
+
task "db:environment:set" do
|
11
|
+
# no op
|
12
12
|
end
|
13
13
|
end
|
data/spec/dummy/bin/bundle
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
ENV[
|
3
|
-
load Gem.bin_path(
|
2
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
3
|
+
load Gem.bin_path("bundler", "bundle")
|
data/spec/dummy/bin/rails
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
APP_PATH = File.expand_path(
|
3
|
-
require_relative
|
4
|
-
require
|
2
|
+
APP_PATH = File.expand_path("../../config/application", __FILE__)
|
3
|
+
require_relative "../config/boot"
|
4
|
+
require "rails/commands"
|