scenic 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1617d9008cabf9f0117f71f812735e8f89bf932
4
- data.tar.gz: 31babdfa7c8fc2bc200f9457bc6f8fcab9f16a8e
3
+ metadata.gz: d319d2791defb8c1025c78605b3003c0275664ba
4
+ data.tar.gz: 0c79eb3cb32bf171ec085987b83ac89df8bd4ffe
5
5
  SHA512:
6
- metadata.gz: aebbd7f6d99c20b35420a68977a4231849543393c01d2a37487cfcde775cc26b33af792d13b61a4618db12dfe4eef0fc0a581ad27a5b76842d4701c0452302db
7
- data.tar.gz: 05ea1809e4c4777903a297a9ee1e8c83d59ac3550aa455a82ef2d0e52f0a5f715211ed721e1f425aa87f4d08e7f04c7e7c9b1bec284861ab667e555eefe226c0
6
+ metadata.gz: f858662b6d60d851a0aa402401c750da7a9c482d018e49e6fcdde39cd5672bd4d8cbd5593f422afa7541c0867805f28e0a73cb1add550c0742552851f67359a3
7
+ data.tar.gz: 81c7ec7accf60272ff77476c73b31ed7b332334874d150b655b5933a4546be4a009a75c9dcd4a2d93a623de702c34c6e6f80bb76d5f3f8665ff65a56dc2ca896
data/README.md CHANGED
@@ -78,6 +78,49 @@ Scenic detected that we already had an existing `search_results` view at version
78
78
  update to the version 2 schema. All that's left for you to do is tweak the
79
79
  schema in the new definition and run the `update_view` migration.
80
80
 
81
+ ## What if I want to change a view without dropping it?
82
+
83
+ The `update_view` statement used by default will drop your view then create
84
+ a new version of it.
85
+
86
+ This is not desirable when you have complicated hierarchies of views, especially
87
+ when some of those views may be materialized and take a long time to recreate.
88
+
89
+ You can use `replace_view` to generate a CREATE OR REPLACE VIEW SQL statement.
90
+
91
+ See postgresql documentation on how this works:
92
+ http://www.postgresql.org/docs/current/static/sql-createview.html
93
+
94
+ To start replacing a view run the generator like for a regular change:
95
+
96
+ ```sh
97
+ $ rails generate scenic:view search_results
98
+ create db/views/search_results_v02.sql
99
+ create db/migrate/[TIMESTAMP]_update_search_results_to_version_2.rb
100
+ ```
101
+
102
+ Now, edit the migration. It should look something like:
103
+
104
+ ```ruby
105
+ class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
106
+ def change
107
+ update_view :search_results, version: 2, revert_to_version: 1
108
+ end
109
+ end
110
+ ```
111
+
112
+ Update it to use replace view:
113
+
114
+ ```ruby
115
+ class UpdateSearchResultsToVersion2 < ActiveRecord::Migration
116
+ def change
117
+ replace_view :search_results, version: 2, revert_to_version: 1
118
+ end
119
+ end
120
+ ```
121
+
122
+ Now you can run the migration like normal.
123
+
81
124
  ## Can I use this view to back a model?
82
125
 
83
126
  You bet! Using view-backed models can help promote concepts hidden in your
data/Rakefile CHANGED
@@ -12,4 +12,18 @@ namespace :dummy do
12
12
  Dummy::Application.load_tasks
13
13
  end
14
14
 
15
- task default: [:spec, :smoke]
15
+ task(:spec).clear
16
+ desc "Run specs other than spec/acceptance"
17
+ RSpec::Core::RakeTask.new("spec") do |task|
18
+ task.exclude_pattern = "spec/acceptance/**/*_spec.rb"
19
+ task.verbose = false
20
+ end
21
+
22
+ desc "Run acceptance specs in spec/acceptance"
23
+ RSpec::Core::RakeTask.new("spec:acceptance") do |task|
24
+ task.pattern = "spec/acceptance/**/*_spec.rb"
25
+ task.verbose = false
26
+ end
27
+
28
+ desc "Run the specs and acceptance tests"
29
+ task default: %w(spec spec:acceptance)
@@ -11,12 +11,12 @@ module Scenic
11
11
  source_root File.expand_path("../templates", __FILE__)
12
12
 
13
13
  def invoke_rails_model_generator
14
- invoke "model", [name], options.merge(migration: false)
14
+ invoke "model", [file_path.singularize], options.merge(migration: false)
15
15
  end
16
16
 
17
17
  def inject_model_methods
18
18
  if materialized? && generating?
19
- inject_into_class "app/models/#{file_path}.rb", class_name do
19
+ inject_into_class "app/models/#{file_path.singularize}.rb", class_name do
20
20
  evaluate_template("model.erb")
21
21
  end
22
22
  end
@@ -81,6 +81,31 @@ module Scenic
81
81
  create_view(name, sql_definition)
82
82
  end
83
83
 
84
+ # Replaces a view in the database using `CREATE OR REPLACE VIEW`.
85
+ #
86
+ # This results in a `CREATE OR REPLACE VIEW`. Most of the time the
87
+ # explicitness of the two step process used in {#update_view} is preferred
88
+ # to `CREATE OR REPLACE VIEW` because the former ensures that the view you
89
+ # are trying to update did, in fact, already exist. Additionally,
90
+ # `CREATE OR REPLACE VIEW` is allowed only to add new columns to the end
91
+ # of an existing view schema. Existing columns cannot be re-ordered,
92
+ # removed, or have their types changed. Drop and create overcomes this
93
+ # limitation as well.
94
+ #
95
+ # However, when there is a tangled dependency tree
96
+ # `CREATE OR REPLACE VIEW` can be preferable.
97
+ #
98
+ # This is typically called in a migration via
99
+ # {Statements#replace_view}.
100
+ #
101
+ # @param name The name of the view to update
102
+ # @param sql_definition The SQL schema for the updated view.
103
+ #
104
+ # @return [void]
105
+ def replace_view(name, sql_definition)
106
+ execute "CREATE OR REPLACE VIEW #{quote_table_name(name)} AS #{sql_definition};"
107
+ end
108
+
84
109
  # Drops the named view from the database
85
110
  #
86
111
  # This is typically called in a migration via {Statements#drop_view}.
@@ -27,7 +27,8 @@ module Scenic
27
27
  SELECT
28
28
  c.relname as viewname,
29
29
  pg_get_viewdef(c.oid) AS definition,
30
- c.relkind AS kind
30
+ c.relkind AS kind,
31
+ n.nspname AS namespace
31
32
  FROM pg_class c
32
33
  LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
33
34
  WHERE
@@ -39,8 +40,16 @@ module Scenic
39
40
  end
40
41
 
41
42
  def to_scenic_view(result)
43
+ namespace, viewname = result.values_at "namespace", "viewname"
44
+
45
+ if namespace != "public"
46
+ namespaced_viewname = "#{namespace}.#{viewname}"
47
+ else
48
+ namespaced_viewname = viewname
49
+ end
50
+
42
51
  Scenic::View.new(
43
- name: result["viewname"],
52
+ name: namespaced_viewname,
44
53
  definition: result["definition"].strip,
45
54
  materialized: result["kind"] == "m",
46
55
  )
@@ -15,6 +15,10 @@ module Scenic
15
15
  record(:update_view, args)
16
16
  end
17
17
 
18
+ def replace_view(*args)
19
+ record(:replace_view, args)
20
+ end
21
+
18
22
  def invert_create_view(args)
19
23
  [:drop_view, args]
20
24
  end
@@ -27,6 +31,10 @@ module Scenic
27
31
  perform_scenic_inversion(:update_view, args)
28
32
  end
29
33
 
34
+ def invert_replace_view(args)
35
+ perform_scenic_inversion(:replace_view, args)
36
+ end
37
+
30
38
  private
31
39
 
32
40
  def perform_scenic_inversion(method, args)
@@ -89,6 +89,36 @@ module Scenic
89
89
  end
90
90
  end
91
91
 
92
+ # Update a database view to a new version using `CREATE OR REPLACE VIEW`.
93
+ #
94
+ # The existing view is replaced using the supplied `version`
95
+ # parameter.
96
+ #
97
+ # Does not work with materialized views due to lack of database support.
98
+ #
99
+ # @param name [String, Symbol] The name of the database view.
100
+ # @param version [Fixnum] The version number of the view.
101
+ # @param revert_to_version [Fixnum] The version number to rollback to on
102
+ # `rake db rollback`
103
+ # @return The database response from executing the create statement.
104
+ #
105
+ # @example
106
+ # replace_view :engagement_reports, version: 3, revert_to_version: 2
107
+ #
108
+ def replace_view(name, version: nil, revert_to_version: nil, materialized: false)
109
+ if version.blank?
110
+ raise ArgumentError, "version is required"
111
+ end
112
+
113
+ if materialized
114
+ raise ArgumentError, "Cannot replace materialized views"
115
+ end
116
+
117
+ sql_definition = definition(name, version)
118
+
119
+ Scenic.database.replace_view(name, sql_definition)
120
+ end
121
+
92
122
  private
93
123
 
94
124
  def definition(name, version)
@@ -1,3 +1,3 @@
1
1
  module Scenic
2
- VERSION = "1.2.0".freeze
2
+ VERSION = "1.3.0".freeze
3
3
  end
@@ -43,8 +43,10 @@ module Scenic
43
43
  # @api private
44
44
  def to_schema
45
45
  materialized_option = materialized ? "materialized: true, " : ""
46
+ safe_to_symbolize_name = name.include?(".") ? "'#{name}'" : name
47
+
46
48
  <<-DEFINITION
47
- create_view :#{name}, #{materialized_option} sql_definition: <<-\SQL
49
+ create_view :#{safe_to_symbolize_name}, #{materialized_option} sql_definition: <<-\SQL
48
50
  #{definition.indent(2)}
49
51
  SQL
50
52
 
@@ -0,0 +1,86 @@
1
+ require "acceptance_helper"
2
+
3
+ describe "User manages views" do
4
+ it "handles simple views" do
5
+ successfully "rails generate scenic:model search_result"
6
+ write_definition "search_results_v01", "SELECT 'needle'::text AS term"
7
+
8
+ successfully "rake db:migrate"
9
+ verify_result "SearchResult.take.term", "needle"
10
+
11
+ successfully "rails generate scenic:view search_results"
12
+ verify_identical_view_definitions "search_results_v01", "search_results_v02"
13
+
14
+ write_definition "search_results_v02", "SELECT 'haystack'::text AS term"
15
+ successfully "rake db:migrate"
16
+
17
+ successfully "rake db:reset"
18
+ verify_result "SearchResult.take.term", "haystack"
19
+
20
+ successfully "rake db:rollback"
21
+ successfully "rake db:rollback"
22
+ successfully "rails destroy scenic:model search_result"
23
+ end
24
+
25
+ it "handles materialized views" do
26
+ successfully "rails generate scenic:model child --materialized"
27
+ write_definition "children_v01", "SELECT 'Owen'::text AS name, 5 AS age"
28
+
29
+ successfully "rake db:migrate"
30
+ verify_result "Child.take.name", "Owen"
31
+
32
+ add_index "children", "name"
33
+ add_index "children", "age"
34
+
35
+ successfully "rails runner 'Child.refresh'"
36
+
37
+ successfully "rails generate scenic:view child --materialized"
38
+ verify_identical_view_definitions "children_v01", "children_v02"
39
+
40
+ write_definition "children_v02", "SELECT 'Elliot'::text AS name"
41
+ successfully "rake db:migrate"
42
+
43
+ successfully "rake db:reset"
44
+ verify_result "Child.take.name", "Elliot"
45
+ verify_schema_contains 'add_index "children"'
46
+
47
+ successfully "rake db:rollback"
48
+ successfully "rake db:rollback"
49
+ successfully "rails destroy scenic:model child"
50
+ end
51
+
52
+ it "handles plural view names gracefully during generation" do
53
+ successfully "rails generate scenic:model search_results --materialized"
54
+ end
55
+
56
+ def successfully(command)
57
+ `RAILS_ENV=test #{command}`
58
+ expect($?.exitstatus).to eq(0), "'#{command}' was unsuccessful"
59
+ end
60
+
61
+ def write_definition(file, contents)
62
+ File.open("db/views/#{file}.sql", File::WRONLY) do |definition|
63
+ definition.truncate(0)
64
+ definition.write(contents)
65
+ end
66
+ end
67
+
68
+ def verify_result(command, expected_output)
69
+ successfully %{rails runner "#{command} == '#{expected_output}' || exit(1)"}
70
+ end
71
+
72
+ def verify_identical_view_definitions(def_a, def_b)
73
+ successfully "cmp db/views/#{def_a}.sql db/views/#{def_b}.sql"
74
+ end
75
+
76
+ def add_index(table, column)
77
+ successfully(<<-CMD.strip)
78
+ rails runner 'ActiveRecord::Migration.add_index "#{table}", "#{column}"'
79
+ CMD
80
+ end
81
+
82
+ def verify_schema_contains(statement)
83
+ expect(File.readlines("db/schema.rb").grep(/#{statement}/))
84
+ .not_to be_empty, "Schema does not contain '#{statement}'"
85
+ end
86
+ end
@@ -0,0 +1,32 @@
1
+ require "bundler"
2
+
3
+ ENV["RAILS_ENV"] = "test"
4
+
5
+ RSpec.configure do |config|
6
+ config.around(:each) do |example|
7
+ Dir.chdir("spec/dummy") do
8
+ example.run
9
+ end
10
+ end
11
+
12
+ config.before(:suite) do
13
+ Dir.chdir("spec/dummy") do
14
+ system <<-CMD
15
+ git init 1>/dev/null &&
16
+ git add -A &&
17
+ git commit --no-gpg-sign --message 'initial' 1>/dev/null
18
+ CMD
19
+ end
20
+ end
21
+
22
+ config.after(:suite) do
23
+ Dir.chdir("spec/dummy") do
24
+ system <<-CMD
25
+ rake db:drop db:create &&
26
+ git add -A &&
27
+ git reset --hard HEAD 1>/dev/null &&
28
+ rm -rf .git/ 1>/dev/null
29
+ CMD
30
+ end
31
+ end
32
+ end
@@ -38,6 +38,22 @@ module Scenic
38
38
  end
39
39
  end
40
40
 
41
+ describe "#replace_view" do
42
+ it "successfully replaces a view" do
43
+ adapter = Postgres.new
44
+
45
+ adapter.create_view("greetings", "SELECT text 'hi' AS greeting")
46
+
47
+ view = adapter.views.first.definition
48
+ expect(view).to eql "SELECT 'hi'::text AS greeting;"
49
+
50
+ adapter.replace_view("greetings", "SELECT text 'hello' AS greeting")
51
+
52
+ view = adapter.views.first.definition
53
+ expect(view).to eql "SELECT 'hello'::text AS greeting;"
54
+ end
55
+ end
56
+
41
57
  describe "#drop_view" do
42
58
  it "successfully drops a view" do
43
59
  adapter = Postgres.new
@@ -137,6 +153,27 @@ module Scenic
137
153
  "people_with_names",
138
154
  ]
139
155
  end
156
+
157
+ context "with views in non public schemas" do
158
+ it "returns also the non public views" do
159
+ adapter = Postgres.new
160
+
161
+ ActiveRecord::Base.connection.execute <<-SQL
162
+ CREATE VIEW parents AS SELECT text 'Joe' AS name
163
+ SQL
164
+
165
+ ActiveRecord::Base.connection.execute <<-SQL
166
+ CREATE SCHEMA scenic;
167
+ CREATE VIEW scenic.parents AS SELECT text 'Maarten' AS name;
168
+ SET search_path TO scenic, public;
169
+ SQL
170
+
171
+ expect(adapter.views.map(&:name)).to eq [
172
+ "parents",
173
+ "scenic.parents",
174
+ ]
175
+ end
176
+ end
140
177
  end
141
178
  end
142
179
  end
@@ -65,6 +65,32 @@ describe Scenic::CommandRecorder do
65
65
  end
66
66
  end
67
67
 
68
+ describe "#replace_view" do
69
+ it "records the replaced view" do
70
+ args = [:users, { version: 2 }]
71
+
72
+ recorder.replace_view(*args)
73
+
74
+ expect(recorder.commands).to eq [[:replace_view, args, nil]]
75
+ end
76
+
77
+ it "reverts to replace_view with the specified revert_to_version" do
78
+ args = [:users, { version: 2, revert_to_version: 1 }]
79
+ revert_args = [:users, { version: 1 }]
80
+
81
+ recorder.revert { recorder.replace_view(*args) }
82
+
83
+ expect(recorder.commands).to eq [[:replace_view, revert_args]]
84
+ end
85
+
86
+ it "raises when reverting without revert_to_version set" do
87
+ args = [:users, { version: 42, another_argument: 1 }]
88
+
89
+ expect { recorder.revert { recorder.replace_view(*args) } }
90
+ .to raise_error(ActiveRecord::IrreversibleMigration)
91
+ end
92
+ end
93
+
68
94
  def recorder
69
95
  @recorder ||= ActiveRecord::Migration::CommandRecorder.new
70
96
  end
@@ -20,4 +20,20 @@ describe Scenic::SchemaDumper, :db do
20
20
 
21
21
  expect(Search.first.haystack).to eq "needle"
22
22
  end
23
+
24
+ context "with views in non public schemas" do
25
+ it "dumps a create_view including namespace for a view in the database" do
26
+ view_definition = "SELECT 'needle'::text AS haystack"
27
+ Search.connection.execute "CREATE SCHEMA scenic; SET search_path TO scenic, public"
28
+ Search.connection.create_view :"scenic.searches", sql_definition: view_definition
29
+ stream = StringIO.new
30
+
31
+ ActiveRecord::SchemaDumper.dump(Search.connection, stream)
32
+
33
+ output = stream.string
34
+ expect(output).to include "create_view :'scenic.searches',"
35
+
36
+ Search.connection.drop_view :'scenic.searches'
37
+ end
38
+ end
23
39
  end
@@ -95,6 +95,36 @@ module Scenic
95
95
  end
96
96
  end
97
97
 
98
+ describe "replace_view" do
99
+ it "replaces the view in the database" do
100
+ definition = instance_double("Definition", to_sql: "definition")
101
+ allow(Definition).to receive(:new)
102
+ .with(:name, 3)
103
+ .and_return(definition)
104
+
105
+ connection.replace_view(:name, version: 3)
106
+
107
+ expect(Scenic.database).to have_received(:replace_view)
108
+ .with(:name, definition.to_sql)
109
+ end
110
+
111
+ it "fails to replace the materialized view in the database" do
112
+ definition = instance_double("Definition", to_sql: "definition")
113
+ allow(Definition).to receive(:new)
114
+ .with(:name, 3)
115
+ .and_return(definition)
116
+
117
+ expect do
118
+ connection.replace_view(:name, version: 3, materialized: true)
119
+ end.to raise_error(ArgumentError, /Cannot replace materialized views/)
120
+ end
121
+
122
+ it "raises an error if not supplied a version" do
123
+ expect { connection.replace_view :views }
124
+ .to raise_error(ArgumentError, /version is required/)
125
+ end
126
+ end
127
+
98
128
  def connection
99
129
  Class.new { extend Statements }
100
130
  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.2.0
4
+ version: 1.3.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: 2016-02-06 00:00:00.000000000 Z
12
+ date: 2016-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: appraisal
@@ -234,6 +234,8 @@ files:
234
234
  - lib/scenic/version.rb
235
235
  - lib/scenic/view.rb
236
236
  - scenic.gemspec
237
+ - spec/acceptance/user_manages_views_spec.rb
238
+ - spec/acceptance_helper.rb
237
239
  - spec/dummy/.gitignore
238
240
  - spec/dummy/Rakefile
239
241
  - spec/dummy/bin/bundle
@@ -258,7 +260,6 @@ files:
258
260
  - spec/scenic/definition_spec.rb
259
261
  - spec/scenic/schema_dumper_spec.rb
260
262
  - spec/scenic/statements_spec.rb
261
- - spec/smoke
262
263
  - spec/spec_helper.rb
263
264
  - spec/support/generator_spec_setup.rb
264
265
  - spec/support/view_definition_helpers.rb
@@ -282,11 +283,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
282
283
  version: '0'
283
284
  requirements: []
284
285
  rubyforge_project:
285
- rubygems_version: 2.2.5
286
+ rubygems_version: 2.5.1
286
287
  signing_key:
287
288
  specification_version: 4
288
289
  summary: Support for database views in Rails migrations
289
290
  test_files:
291
+ - spec/acceptance/user_manages_views_spec.rb
292
+ - spec/acceptance_helper.rb
290
293
  - spec/dummy/.gitignore
291
294
  - spec/dummy/Rakefile
292
295
  - spec/dummy/bin/bundle
@@ -311,7 +314,6 @@ test_files:
311
314
  - spec/scenic/definition_spec.rb
312
315
  - spec/scenic/schema_dumper_spec.rb
313
316
  - spec/scenic/statements_spec.rb
314
- - spec/smoke
315
317
  - spec/spec_helper.rb
316
318
  - spec/support/generator_spec_setup.rb
317
319
  - spec/support/view_definition_helpers.rb
data/spec/smoke DELETED
@@ -1,135 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -euo pipefail
4
-
5
- setup() {
6
- cd spec/dummy
7
- git init
8
- git add -A
9
- git commit --no-gpg-sign --message "initial"
10
- }
11
-
12
- teardown() {
13
- git add -A
14
- git reset --hard HEAD
15
- rm -rf .git/
16
- rake db:drop db:create
17
- }
18
-
19
- trap teardown EXIT
20
-
21
- verifySearchResults() {
22
- echo "verify search results"
23
- local expectedResult=$1
24
- local actualResult=$(rails runner "puts Search.take.results")
25
- [[ "$actualResult" == "$expectedResult" ]] || exit 1
26
- echo "[success]"
27
- }
28
-
29
- verifySchemaContains() {
30
- local expectedString=$1
31
- echo "verify schema contains '$expectedString'"
32
- grep -q "$expectedString" db/schema.rb || exit 1
33
- echo "[success]"
34
- }
35
-
36
- writeToFileAndMigrateAndVerifySearchResults() {
37
- echo "write search definition and migrate"
38
- local version=$1
39
- local expectedResult=$2
40
- local filePath=db/views/searches_v$version\.sql
41
- cp /dev/null $filePath
42
- echo "SELECT '$expectedResult'::text AS results, 1 AS user_id" >> $filePath
43
- rake db:migrate
44
- echo "[success]"
45
- verifySearchResults $expectedResult
46
- }
47
-
48
- main() {
49
- setup
50
- echo "rails generate scenic:model search"
51
- rails generate scenic:model search
52
- [[ -f db/views/searches_v01.sql ]] || exit 1
53
- [[ -f app/models/search.rb ]] || exit 1
54
- [[ -n "$(find db/migrate -maxdepth 1 -name "*create_searches.rb" -print -quit)" ]] || exit 1
55
- echo "[success]"
56
-
57
- writeToFileAndMigrateAndVerifySearchResults "01" "search-results"
58
-
59
- echo "rails generate scenic:view search (to get updates search view)"
60
- rails generate scenic:view search
61
- [[ -f db/views/searches_v02.sql ]] || exit 1
62
- cmp db/views/searches_v01.sql db/views/searches_v02.sql || exit 1
63
- [[ -n "$(find db/migrate -maxdepth 1 -name "*update_searches_to_version_2.rb" -print -quit)" ]] || exit 1
64
- echo "[success]"
65
-
66
- writeToFileAndMigrateAndVerifySearchResults "02" "different-results"
67
-
68
- echo "rake db:rollback"
69
- rake db:rollback
70
- echo "[success]"
71
-
72
- verifySearchResults "search-results"
73
-
74
- echo "rails destroy scenic:view search"
75
- rails destroy scenic:view search
76
- [[ ! -f db/views/searches_v02.sql ]] || exit 1
77
- [[ -z "$(find db/migrate -maxdepth 1 -name "*update_searches_to_version_2.rb" -print -quit)" ]] || exit 1
78
- [[ -f db/views/searches_v01.sql ]] || exit 1
79
- [[ -f app/models/search.rb ]] || exit 1
80
- [[ -n "$(find db/migrate -maxdepth 1 -name "*create_searches.rb" -print -quit)" ]] || exit 1
81
- echo "[success]"
82
-
83
- echo "rake db:rollback"
84
- rake db:rollback
85
- echo "[success]"
86
-
87
- echo "rails destroy scenic:view search"
88
- rails destroy scenic:model search
89
- [[ ! -f db/views/searches_v01.sql ]] || exit 1
90
- [[ ! -f app/models/search.rb ]] || exit 1
91
- [[ -z "$(find db/migrate -maxdepth 1 -name "*create_searches.rb" -print -quit)" ]] || exit 1
92
- echo "[success]"
93
-
94
- echo "rails generate scenic:model search (materialized)"
95
- rails generate scenic:model search --materialized
96
- [[ -f db/views/searches_v01.sql ]] || exit 1
97
- [[ -f app/models/search.rb ]] || exit 1
98
- [[ -n "$(find db/migrate -maxdepth 1 -name "*create_searches.rb" -print -quit)" ]] || exit 1
99
- echo "[success]"
100
-
101
- writeToFileAndMigrateAndVerifySearchResults "01" "search-results"
102
-
103
- echo "refresh materialized view"
104
- rails runner "Search.refresh" || exit 1
105
- echo "[success]"
106
-
107
- echo "add indexes to materialized view"
108
- rails runner 'ActiveRecord::Migration.add_index :searches, :results' || exit 1
109
- rails runner 'ActiveRecord::Migration.add_index :searches, :user_id' || exit 1
110
- echo "[success]"
111
-
112
- echo "update materialized view"
113
- rails generate scenic:view search --materialized
114
- echo "SELECT 'test'::text AS results" > db/views/searches_v02.sql
115
- rake db:migrate
116
- verifySearchResults 'test'
117
- verifySchemaContains 'add_index "searches"'
118
-
119
- echo "rake db:rollback"
120
- rake db:rollback
121
- rake db:rollback
122
- echo "[success]"
123
-
124
- echo "rails destroy scenic:model search --materialized"
125
- rails destroy scenic:view search --materialized
126
- rails destroy scenic:model search --materialized
127
- [[ ! -f app/models/search.rb ]] || exit 1
128
- [[ ! -f db/views/searches_v01.sql ]] || exit 1
129
- [[ -z "$(find db/migrate -maxdepth 1 -name "*create_searches.rb" -print -quit)" ]] || exit 1
130
- echo "[success]"
131
-
132
- echo "[done]"
133
- }
134
-
135
- main $*