scenic 1.5.4 → 1.7.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/.devcontainer/Dockerfile +6 -0
- data/.devcontainer/devcontainer.json +11 -0
- data/.devcontainer/docker-compose.yml +24 -0
- data/.github/workflows/ci.yml +5 -12
- data/.gitignore +1 -0
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/README.md +17 -23
- data/lib/generators/scenic/materializable.rb +9 -0
- data/lib/generators/scenic/model/model_generator.rb +17 -6
- data/lib/generators/scenic/view/templates/db/migrate/update_view.erb +3 -2
- data/lib/scenic/adapters/postgres/index_reapplication.rb +1 -1
- data/lib/scenic/adapters/postgres/views.rb +1 -0
- data/lib/scenic/command_recorder/statement_arguments.rb +12 -2
- data/lib/scenic/command_recorder.rb +4 -0
- data/lib/scenic/definition.rb +4 -2
- data/lib/scenic/unaffixed_name.rb +31 -0
- data/lib/scenic/version.rb +1 -1
- data/lib/scenic/view.rb +7 -3
- data/lib/scenic.rb +1 -0
- data/spec/dummy/config/database.yml +1 -1
- data/spec/dummy/db/migrate/20220112154220_add_pg_stat_statements_extension.rb +5 -0
- data/spec/dummy/db/schema.rb +19 -0
- data/spec/generators/scenic/view/view_generator_spec.rb +12 -0
- data/spec/scenic/definition_spec.rb +8 -0
- data/spec/scenic/schema_dumper_spec.rb +31 -1
- data/spec/scenic/statements_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/support/rails_configuration_helpers.rb +10 -0
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b378292bd7d642dcd235d01f5a31d94c74065b798ab469a9c091f68e936f4d9c
|
4
|
+
data.tar.gz: b97f6e156685d4c03761543d5748f1381447c94cfcc42f7d6ddb8714e16791d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ffb0c73e52da5122a8ce3092b7f280d1a1dcaac9ca03a5f8ea63fe361d1b011d3c71f54706ff17d8ee1768fbdc1ba32c38bfebbcda320271e0b751eaea340f3
|
7
|
+
data.tar.gz: 846d53ffe8c0d0209ab6517c47e0447ee3b40a81e5f55f845f16a1b3f697cebd44ad38550a5fe8d10016ab19b3c1197f36ea9f3f5f7f42395a1431790684e0c1
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"name": "Scenic Development",
|
3
|
+
"dockerComposeFile": "docker-compose.yml",
|
4
|
+
"service": "app",
|
5
|
+
"workspaceFolder": "/workspace",
|
6
|
+
"settings": { },
|
7
|
+
"extensions": ["rebornix.Ruby"],
|
8
|
+
"postCreateCommand": "bin/setup",
|
9
|
+
"remoteUser": "vscode",
|
10
|
+
"features": { "github-cli": "latest" }
|
11
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
version: '3'
|
2
|
+
|
3
|
+
services:
|
4
|
+
app:
|
5
|
+
build:
|
6
|
+
context: ..
|
7
|
+
dockerfile: .devcontainer/Dockerfile
|
8
|
+
args:
|
9
|
+
VARIANT: "3"
|
10
|
+
volumes:
|
11
|
+
- ..:/workspace:cached
|
12
|
+
command: sleep infinity
|
13
|
+
network_mode: service:db
|
14
|
+
db:
|
15
|
+
image: postgres:latest
|
16
|
+
restart: unless-stopped
|
17
|
+
volumes:
|
18
|
+
- postgres-data:/var/lib/postgresql/data
|
19
|
+
environment:
|
20
|
+
POSTGRES_USER: postgres
|
21
|
+
POSTGRES_DB: postgres
|
22
|
+
POSTGRES_PASSWORD: postgres
|
23
|
+
volumes:
|
24
|
+
postgres-data: null
|
data/.github/workflows/ci.yml
CHANGED
@@ -2,7 +2,7 @@ name: CI
|
|
2
2
|
|
3
3
|
on:
|
4
4
|
push:
|
5
|
-
branches:
|
5
|
+
branches: main
|
6
6
|
pull_request:
|
7
7
|
branches: "*"
|
8
8
|
|
@@ -13,16 +13,9 @@ jobs:
|
|
13
13
|
strategy:
|
14
14
|
fail-fast: false
|
15
15
|
matrix:
|
16
|
-
ruby: ["2.7","
|
17
|
-
rails: ["
|
18
|
-
|
19
|
-
- ruby: "2.4"
|
20
|
-
rails: "6.0"
|
21
|
-
- ruby: "2.4"
|
22
|
-
rails: "master"
|
23
|
-
include:
|
24
|
-
- rails: "master"
|
25
|
-
continue-on-error: true
|
16
|
+
ruby: ["2.7", "3.0", "3.1"]
|
17
|
+
rails: ["6.1", "7.0"]
|
18
|
+
continue-on-error: [false]
|
26
19
|
|
27
20
|
runs-on: ubuntu-latest
|
28
21
|
|
@@ -50,7 +43,7 @@ jobs:
|
|
50
43
|
uses: actions/checkout@v2
|
51
44
|
|
52
45
|
- name: Install Ruby ${{ matrix.ruby }}
|
53
|
-
uses: ruby/setup-ruby@v1
|
46
|
+
uses: ruby/setup-ruby@v1
|
54
47
|
with:
|
55
48
|
ruby-version: ${{ matrix.ruby }}
|
56
49
|
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,39 @@ 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.7.0] - December 8, 2022
|
9
|
+
|
10
|
+
[1.7.0]: https://github.com/scenic-views/scenic/compare/v1.6.0...v1.7.0
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
* Added the `--replace` CLI flag to generate a migration that uses the
|
15
|
+
`replace_view` schema statement - *Dan Hixon*
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
* Fixed deprecation notice from newer versions of ERB when using scenic
|
20
|
+
generators - *Ali Ismayilov*
|
21
|
+
|
22
|
+
## [1.6.0] - February 13, 2022
|
23
|
+
|
24
|
+
[1.6.0]: https://github.com/scenic-views/scenic/compare/v1.5.5...v1.6.0
|
25
|
+
|
26
|
+
### Fixed
|
27
|
+
|
28
|
+
* Exclude pg_stat_statements_info (#349) 76bface - *Caleb Hearth*
|
29
|
+
* Fix serialization of views with backslashes c625d1b - *Ben Sheldon*
|
30
|
+
* Handle ActiveRecord table name prefix and suffix b1544dc - *Derek Prior*
|
31
|
+
|
32
|
+
## [1.5.5] - December 15, 2021
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- Fixed an issue reverting migrations under Ruby 3
|
37
|
+
- Fixed an issue in index reapplication where sometimes `say` was undefined
|
38
|
+
|
39
|
+
[1.5.5]: https://github.com/scenic-views/scenic/compare/v1.5.4...v1.5.5
|
40
|
+
|
8
41
|
## [1.5.4] - September 16, 2020
|
9
42
|
|
10
43
|
[1.5.4]: https://github.com/scenic-views/scenic/compare/v1.5.3...v1.5.4
|
data/Gemfile
CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in scenic.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
rails_version = ENV.fetch("RAILS_VERSION", "6.
|
6
|
+
rails_version = ENV.fetch("RAILS_VERSION", "6.1")
|
7
7
|
|
8
8
|
if rails_version == "master"
|
9
9
|
rails_constraint = { github: "rails/rails" }
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
-
[](https://github.com/scenic-views/scenic/actions/workflows/ci.yml)
|
6
6
|
[](http://inch-ci.org/github/scenic-views/scenic)
|
7
7
|
[](https://houndci.com)
|
8
8
|
|
@@ -92,30 +92,19 @@ a new version of it.
|
|
92
92
|
This is not desirable when you have complicated hierarchies of views, especially
|
93
93
|
when some of those views may be materialized and take a long time to recreate.
|
94
94
|
|
95
|
-
You can use `replace_view` to generate a CREATE OR REPLACE VIEW SQL statement
|
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:
|
95
|
+
You can use `replace_view` to generate a CREATE OR REPLACE VIEW SQL statement
|
96
|
+
instead by adding the `--replace` option to the generate command:
|
101
97
|
|
102
98
|
```sh
|
103
|
-
$ rails generate scenic:view search_results
|
99
|
+
$ rails generate scenic:view search_results --replace
|
104
100
|
create db/views/search_results_v02.sql
|
105
101
|
create db/migrate/[TIMESTAMP]_update_search_results_to_version_2.rb
|
106
102
|
```
|
107
103
|
|
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
|
-
```
|
104
|
+
See Postgres documentation on how this works:
|
105
|
+
http://www.postgresql.org/docs/current/static/sql-createview.html
|
117
106
|
|
118
|
-
|
107
|
+
The migration will look something like this:
|
119
108
|
|
120
109
|
```ruby
|
121
110
|
class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
|
@@ -125,7 +114,7 @@ class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
|
|
125
114
|
end
|
126
115
|
```
|
127
116
|
|
128
|
-
|
117
|
+
You can run the migration and the view will be replaced instead.
|
129
118
|
|
130
119
|
## Can I use this view to back a model?
|
131
120
|
|
@@ -252,16 +241,21 @@ accommodate adapter gems.
|
|
252
241
|
We are aware of the following existing adapter libraries for Scenic which may
|
253
242
|
meet your needs:
|
254
243
|
|
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)
|
244
|
+
* [`scenic_sqlite_adapter`](<https://github.com/pdebelak/scenic_sqlite_adapter>)
|
245
|
+
* [`scenic-mysql_adapter`](<https://github.com/EmpaticoOrg/scenic-mysql_adapter>)
|
246
|
+
* [`scenic-sqlserver-adapter`](<https://github.com/ClickMechanic/scenic_sqlserver_adapter>)
|
247
|
+
* [`scenic-oracle_adapter`](<https://github.com/cdinger/scenic-oracle_adapter>)
|
259
248
|
|
260
249
|
Please note that the maintainers of Scenic make no assertions about the
|
261
250
|
quality or security of the above adapters.
|
262
251
|
|
263
252
|
## About
|
264
253
|
|
254
|
+
Scenic is used by some popular open source Rails apps:
|
255
|
+
[Mastodon](<https://github.com/mastodon/mastodon/>),
|
256
|
+
[Code.org](<https://github.com/code-dot-org/code-dot-org>), and
|
257
|
+
[Lobste.rs](<https://github.com/lobsters/lobsters/>).
|
258
|
+
|
265
259
|
Scenic is maintained by [Derek Prior], [Caleb Hearth], and you, our
|
266
260
|
contributors.
|
267
261
|
|
@@ -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
|
@@ -36,12 +36,23 @@ module Scenic
|
|
36
36
|
def evaluate_template(source)
|
37
37
|
source = File.expand_path(find_in_source_paths(source.to_s))
|
38
38
|
context = instance_eval("binding", __FILE__, __LINE__)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
|
40
|
+
if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
|
41
|
+
erb = ERB.new(
|
42
|
+
::File.binread(source),
|
43
|
+
trim_mode: "-",
|
44
|
+
eoutvar: "@output_buffer",
|
45
|
+
)
|
46
|
+
else
|
47
|
+
erb = ERB.new(
|
48
|
+
::File.binread(source),
|
49
|
+
nil,
|
50
|
+
"-",
|
51
|
+
"@output_buffer",
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
erb.result(context)
|
45
56
|
end
|
46
57
|
|
47
58
|
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
|
@@ -13,7 +13,7 @@ module Scenic
|
|
13
13
|
# @param connection [Connection] The connection to execute SQL against.
|
14
14
|
# @param speaker [#say] (ActiveRecord::Migration) The object used for
|
15
15
|
# logging the results of reapplying indexes.
|
16
|
-
def initialize(connection:, speaker: ActiveRecord::Migration)
|
16
|
+
def initialize(connection:, speaker: ActiveRecord::Migration.new)
|
17
17
|
@connection = connection
|
18
18
|
@speaker = speaker
|
19
19
|
end
|
@@ -36,15 +36,25 @@ module Scenic
|
|
36
36
|
@options ||= @args[1] || {}
|
37
37
|
end
|
38
38
|
|
39
|
+
def keyword_hash(hash)
|
40
|
+
if Hash.respond_to? :ruby2_keywords_hash
|
41
|
+
Hash.ruby2_keywords_hash(hash)
|
42
|
+
else
|
43
|
+
hash
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
def options_for_revert
|
40
|
-
options.clone.tap do |revert_options|
|
48
|
+
opts = options.clone.tap do |revert_options|
|
41
49
|
revert_options[:version] = revert_to_version
|
42
50
|
revert_options.delete(:revert_to_version)
|
43
51
|
end
|
52
|
+
|
53
|
+
keyword_hash(opts)
|
44
54
|
end
|
45
55
|
|
46
56
|
def options_without_version
|
47
|
-
options.except(:version)
|
57
|
+
keyword_hash(options.except(:version))
|
48
58
|
end
|
49
59
|
end
|
50
60
|
end
|
@@ -6,18 +6,22 @@ module Scenic
|
|
6
6
|
def create_view(*args)
|
7
7
|
record(:create_view, args)
|
8
8
|
end
|
9
|
+
ruby2_keywords :create_view if respond_to?(:ruby2_keywords, true)
|
9
10
|
|
10
11
|
def drop_view(*args)
|
11
12
|
record(:drop_view, args)
|
12
13
|
end
|
14
|
+
ruby2_keywords :drop_view if respond_to?(:ruby2_keywords, true)
|
13
15
|
|
14
16
|
def update_view(*args)
|
15
17
|
record(:update_view, args)
|
16
18
|
end
|
19
|
+
ruby2_keywords :update_view if respond_to?(:ruby2_keywords, true)
|
17
20
|
|
18
21
|
def replace_view(*args)
|
19
22
|
record(:replace_view, args)
|
20
23
|
end
|
24
|
+
ruby2_keywords :replace_view if respond_to?(:ruby2_keywords, true)
|
21
25
|
|
22
26
|
def invert_create_view(args)
|
23
27
|
drop_view_args = StatementArguments.new(args).remove_version.to_a
|
data/lib/scenic/definition.rb
CHANGED
@@ -2,7 +2,7 @@ module Scenic
|
|
2
2
|
# @api private
|
3
3
|
class Definition
|
4
4
|
def initialize(name, version)
|
5
|
-
@name = name
|
5
|
+
@name = name.to_s
|
6
6
|
@version = version.to_i
|
7
7
|
end
|
8
8
|
|
@@ -28,8 +28,10 @@ module Scenic
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
+
attr_reader :name
|
32
|
+
|
31
33
|
def filename
|
32
|
-
"#{
|
34
|
+
"#{UnaffixedName.for(name).tr('.', '_')}_v#{version}.sql"
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Scenic
|
2
|
+
# The name of a view or table according to rails.
|
3
|
+
#
|
4
|
+
# This removes any table name prefix or suffix that is configured via
|
5
|
+
# ActiveRecord. This allows, for example, the SchemaDumper to dump a view with
|
6
|
+
# its unaffixed name, consistent with how rails handles table dumping.
|
7
|
+
class UnaffixedName
|
8
|
+
# Gets the unaffixed name for the provided string
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
# @param name [String] The (potentially) affixed view name
|
12
|
+
def self.for(name)
|
13
|
+
new(name, config: ActiveRecord::Base).call
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(name, config:)
|
17
|
+
@name = name
|
18
|
+
@config = config
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
prefix = Regexp.escape(config.table_name_prefix)
|
23
|
+
suffix = Regexp.escape(config.table_name_suffix)
|
24
|
+
name.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :name, :config
|
30
|
+
end
|
31
|
+
end
|
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
|
@@ -45,10 +45,14 @@ module Scenic
|
|
45
45
|
materialized_option = materialized ? "materialized: true, " : ""
|
46
46
|
|
47
47
|
<<-DEFINITION
|
48
|
-
create_view #{name.inspect}, #{materialized_option}sql_definition: <<-\SQL
|
49
|
-
#{
|
48
|
+
create_view #{UnaffixedName.for(name).inspect}, #{materialized_option}sql_definition: <<-\SQL
|
49
|
+
#{escaped_definition.indent(2)}
|
50
50
|
SQL
|
51
51
|
DEFINITION
|
52
52
|
end
|
53
|
+
|
54
|
+
def escaped_definition
|
55
|
+
definition.gsub("\\", "\\\\\\")
|
56
|
+
end
|
53
57
|
end
|
54
58
|
end
|
data/lib/scenic.rb
CHANGED
@@ -4,7 +4,7 @@ development: &default
|
|
4
4
|
encoding: unicode
|
5
5
|
host: localhost
|
6
6
|
pool: 5
|
7
|
-
<% if ENV.fetch("GITHUB_ACTIONS", false) %>
|
7
|
+
<% if ENV.fetch("GITHUB_ACTIONS", false) || ENV.fetch("CODESPACES", false) %>
|
8
8
|
username: <%= ENV.fetch("POSTGRES_USER") %>
|
9
9
|
password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
|
10
10
|
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# This file is the source Rails uses to define your schema when running `bin/rails
|
6
|
+
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
7
|
+
# be faster and is potentially less error prone than running all of your
|
8
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
9
|
+
# migrations use external dependencies or application code.
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 2022_01_12_154220) do
|
14
|
+
|
15
|
+
# These are extensions that must be enabled in order to support this database
|
16
|
+
enable_extension "pg_stat_statements"
|
17
|
+
enable_extension "plpgsql"
|
18
|
+
|
19
|
+
end
|
@@ -37,6 +37,18 @@ describe Scenic::Generators::ViewGenerator, :generator do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
it "uses 'replace_view' instead of 'update_view' if replace flag is set" do
|
41
|
+
with_view_definition("aired_episodes", 1, "hello") do
|
42
|
+
allow(Dir).to receive(:entries).and_return(["aired_episodes_v01.sql"])
|
43
|
+
|
44
|
+
run_generator ["aired_episode", "--replace"]
|
45
|
+
migration = migration_file(
|
46
|
+
"db/migrate/update_aired_episodes_to_version_2.rb",
|
47
|
+
)
|
48
|
+
expect(migration).to contain "replace_view"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
40
52
|
context "for views created in a schema other than 'public'" do
|
41
53
|
it "creates a view definition" do
|
42
54
|
view_definition = file("db/views/non_public_searches_v01.sql")
|
@@ -35,6 +35,14 @@ module Scenic
|
|
35
35
|
|
36
36
|
expect(definition.path).to eq "db/views/non_public_searches_v01.sql"
|
37
37
|
end
|
38
|
+
|
39
|
+
it "handles active record view prefix and suffixing" do
|
40
|
+
with_affixed_tables(prefix: "foo_", suffix: "_bar") do
|
41
|
+
definition = Definition.new("foo_searches_bar", 1)
|
42
|
+
|
43
|
+
expect(definition.path).to eq "db/views/searches_v01.sql"
|
44
|
+
end
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
describe "full_path" do
|
@@ -26,6 +26,22 @@ describe Scenic::SchemaDumper, :db do
|
|
26
26
|
expect(Search.first.haystack).to eq "needle"
|
27
27
|
end
|
28
28
|
|
29
|
+
it "accurately dumps create view statements with a regular expression" do
|
30
|
+
view_definition = "SELECT 'needle'::text AS haystack WHERE 'a2z' ~ '\\d+'"
|
31
|
+
Search.connection.create_view :searches, sql_definition: view_definition
|
32
|
+
stream = StringIO.new
|
33
|
+
|
34
|
+
ActiveRecord::SchemaDumper.dump(Search.connection, stream)
|
35
|
+
|
36
|
+
output = stream.string
|
37
|
+
expect(output).to include "~ '\\\\d+'::text"
|
38
|
+
|
39
|
+
Search.connection.drop_view :searches
|
40
|
+
silence_stream(STDOUT) { eval(output) }
|
41
|
+
|
42
|
+
expect(Search.first.haystack).to eq "needle"
|
43
|
+
end
|
44
|
+
|
29
45
|
it "dumps a create_view for a materialized view in the database" do
|
30
46
|
view_definition = "SELECT 'needle'::text AS haystack"
|
31
47
|
Search.connection.create_view :searches, materialized: true, sql_definition: view_definition
|
@@ -55,6 +71,20 @@ describe Scenic::SchemaDumper, :db do
|
|
55
71
|
end
|
56
72
|
end
|
57
73
|
|
74
|
+
it "handles active record table name prefixes and suffixes" do
|
75
|
+
with_affixed_tables(prefix: "a_", suffix: "_z") do
|
76
|
+
view_definition = "SELECT 'needle'::text AS haystack"
|
77
|
+
Search.connection.create_view :a_searches_z, sql_definition: view_definition
|
78
|
+
stream = StringIO.new
|
79
|
+
|
80
|
+
ActiveRecord::SchemaDumper.dump(Search.connection, stream)
|
81
|
+
|
82
|
+
output = stream.string
|
83
|
+
|
84
|
+
expect(output).to include 'create_view "searches"'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
58
88
|
it "ignores tables internal to Rails" do
|
59
89
|
view_definition = "SELECT 'needle'::text AS haystack"
|
60
90
|
Search.connection.create_view :searches, sql_definition: view_definition
|
@@ -65,7 +95,7 @@ describe Scenic::SchemaDumper, :db do
|
|
65
95
|
output = stream.string
|
66
96
|
|
67
97
|
expect(output).to include 'create_view "searches"'
|
68
|
-
expect(output).not_to include "
|
98
|
+
expect(output).not_to include "pg_stat_statements_info"
|
69
99
|
expect(output).not_to include "schema_migrations"
|
70
100
|
end
|
71
101
|
|
@@ -3,7 +3,7 @@ require "spec_helper"
|
|
3
3
|
module Scenic
|
4
4
|
describe Scenic::Statements do
|
5
5
|
before do
|
6
|
-
adapter = instance_double("Scenic::
|
6
|
+
adapter = instance_double("Scenic::Adapters::Postgres").as_null_object
|
7
7
|
allow(Scenic).to receive(:database).and_return(adapter)
|
8
8
|
end
|
9
9
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,15 +2,19 @@ ENV["RAILS_ENV"] = "test"
|
|
2
2
|
require "database_cleaner"
|
3
3
|
|
4
4
|
require File.expand_path("dummy/config/environment", __dir__)
|
5
|
+
require "support/rails_configuration_helpers"
|
5
6
|
require "support/generator_spec_setup"
|
6
7
|
require "support/view_definition_helpers"
|
7
8
|
|
8
9
|
RSpec.configure do |config|
|
9
10
|
config.order = "random"
|
10
11
|
config.include ViewDefinitionHelpers
|
12
|
+
config.include RailsConfigurationHelpers
|
11
13
|
DatabaseCleaner.strategy = :transaction
|
12
14
|
|
13
15
|
config.around(:each, db: true) do |example|
|
16
|
+
ActiveRecord::SchemaMigration.create_table
|
17
|
+
|
14
18
|
DatabaseCleaner.start
|
15
19
|
example.run
|
16
20
|
DatabaseCleaner.clean
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module RailsConfigurationHelpers
|
2
|
+
def with_affixed_tables(prefix: "", suffix: "")
|
3
|
+
ActiveRecord::Base.table_name_prefix = prefix
|
4
|
+
ActiveRecord::Base.table_name_suffix = suffix
|
5
|
+
yield
|
6
|
+
ensure
|
7
|
+
ActiveRecord::Base.table_name_prefix = ""
|
8
|
+
ActiveRecord::Base.table_name_suffix = ""
|
9
|
+
end
|
10
|
+
end
|
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.7.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: 2022-12-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -175,6 +175,9 @@ executables: []
|
|
175
175
|
extensions: []
|
176
176
|
extra_rdoc_files: []
|
177
177
|
files:
|
178
|
+
- ".devcontainer/Dockerfile"
|
179
|
+
- ".devcontainer/devcontainer.json"
|
180
|
+
- ".devcontainer/docker-compose.yml"
|
178
181
|
- ".github/workflows/ci.yml"
|
179
182
|
- ".gitignore"
|
180
183
|
- ".hound.yml"
|
@@ -217,6 +220,7 @@ files:
|
|
217
220
|
- lib/scenic/railtie.rb
|
218
221
|
- lib/scenic/schema_dumper.rb
|
219
222
|
- lib/scenic/statements.rb
|
223
|
+
- lib/scenic/unaffixed_name.rb
|
220
224
|
- lib/scenic/version.rb
|
221
225
|
- lib/scenic/view.rb
|
222
226
|
- scenic.gemspec
|
@@ -234,6 +238,8 @@ files:
|
|
234
238
|
- spec/dummy/config/database.yml
|
235
239
|
- spec/dummy/config/environment.rb
|
236
240
|
- spec/dummy/db/migrate/.keep
|
241
|
+
- spec/dummy/db/migrate/20220112154220_add_pg_stat_statements_extension.rb
|
242
|
+
- spec/dummy/db/schema.rb
|
237
243
|
- spec/dummy/db/views/.keep
|
238
244
|
- spec/generators/scenic/model/model_generator_spec.rb
|
239
245
|
- spec/generators/scenic/view/view_generator_spec.rb
|
@@ -250,6 +256,7 @@ files:
|
|
250
256
|
- spec/scenic/statements_spec.rb
|
251
257
|
- spec/spec_helper.rb
|
252
258
|
- spec/support/generator_spec_setup.rb
|
259
|
+
- spec/support/rails_configuration_helpers.rb
|
253
260
|
- spec/support/view_definition_helpers.rb
|
254
261
|
homepage: https://github.com/scenic-views/scenic
|
255
262
|
licenses:
|
@@ -270,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
270
277
|
- !ruby/object:Gem::Version
|
271
278
|
version: '0'
|
272
279
|
requirements: []
|
273
|
-
rubygems_version: 3.
|
280
|
+
rubygems_version: 3.2.32
|
274
281
|
signing_key:
|
275
282
|
specification_version: 4
|
276
283
|
summary: Support for database views in Rails migrations
|
@@ -289,6 +296,8 @@ test_files:
|
|
289
296
|
- spec/dummy/config/database.yml
|
290
297
|
- spec/dummy/config/environment.rb
|
291
298
|
- spec/dummy/db/migrate/.keep
|
299
|
+
- spec/dummy/db/migrate/20220112154220_add_pg_stat_statements_extension.rb
|
300
|
+
- spec/dummy/db/schema.rb
|
292
301
|
- spec/dummy/db/views/.keep
|
293
302
|
- spec/generators/scenic/model/model_generator_spec.rb
|
294
303
|
- spec/generators/scenic/view/view_generator_spec.rb
|
@@ -305,4 +314,5 @@ test_files:
|
|
305
314
|
- spec/scenic/statements_spec.rb
|
306
315
|
- spec/spec_helper.rb
|
307
316
|
- spec/support/generator_spec_setup.rb
|
317
|
+
- spec/support/rails_configuration_helpers.rb
|
308
318
|
- spec/support/view_definition_helpers.rb
|