activerecord_views 0.1.5 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_record_views/database_tasks.rb +91 -0
  3. data/lib/active_record_views/railtie.rb +0 -4
  4. data/lib/active_record_views/version.rb +1 -1
  5. data/lib/active_record_views.rb +2 -0
  6. metadata +11 -65
  7. data/.gitignore +0 -8
  8. data/.rspec +0 -2
  9. data/.tool-versions +0 -1
  10. data/Appraisals +0 -15
  11. data/Gemfile +0 -3
  12. data/LICENSE.txt +0 -22
  13. data/Rakefile +0 -14
  14. data/activerecord_views.gemspec +0 -27
  15. data/gemfiles/rails5_2.gemfile +0 -7
  16. data/gemfiles/rails6_0.gemfile +0 -7
  17. data/gemfiles/rails6_1.gemfile +0 -7
  18. data/gemfiles/rails7_0.gemfile +0 -7
  19. data/lib/tasks/active_record_views.rake +0 -106
  20. data/spec/active_record_views_checksum_cache_spec.rb +0 -112
  21. data/spec/active_record_views_extension_spec.rb +0 -459
  22. data/spec/active_record_views_spec.rb +0 -344
  23. data/spec/internal/Rakefile +0 -24
  24. data/spec/internal/app/models/dependency_a.rb +0 -3
  25. data/spec/internal/app/models/dependency_b.rb +0 -3
  26. data/spec/internal/app/models/dependency_c.rb +0 -3
  27. data/spec/internal/app/models/erb_test_model.rb +0 -7
  28. data/spec/internal/app/models/erb_test_model.sql.erb +0 -1
  29. data/spec/internal/app/models/external_file_test_model.rb +0 -3
  30. data/spec/internal/app/models/external_file_test_model.sql +0 -1
  31. data/spec/internal/app/models/heredoc_test_model.rb +0 -5
  32. data/spec/internal/app/models/modified_a.rb +0 -3
  33. data/spec/internal/app/models/modified_b.rb +0 -3
  34. data/spec/internal/app/models/namespace/test_model.rb +0 -3
  35. data/spec/internal/app/models/namespace/test_model.sql +0 -1
  36. data/spec/internal/config/database.yml +0 -9
  37. data/spec/internal/config/routes.rb +0 -3
  38. data/spec/spec_helper.rb +0 -130
  39. data/spec/support/silence_warnings.rb +0 -6
  40. data/spec/tasks_spec.rb +0 -113
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc8196b50d197fd74c7c92238a69124295490b6a991f1618fae1daf610ad041d
4
- data.tar.gz: 235d0e987824299051a1249e9f955a11ccc8966e77ffb0939485797f5285e559
3
+ metadata.gz: 1d93737bced44308bbcb87a5cade4bc0b51a2039af6856ee100bd9db8f41ea41
4
+ data.tar.gz: 85c689e1ed601ddccca52e330aef993c70d647ab43026f202f853d1690bf127c
5
5
  SHA512:
6
- metadata.gz: 7f9370196f53175590f98636c67d98885c7a6e0ac29a030baaea0357536e643500eb4f937d06da114a0054b5febd6b91c1c13abcb3f5853118c4e9685ed1ac82
7
- data.tar.gz: 3f751a3bbdd5761dff8e3e73d587cdc335a68d9b3d08fbfc3a6b7285f1e5de22236857dfc7f842024a5486db6e6ebb7c41186147d56640c1316f40941e20083a
6
+ metadata.gz: 487ccac58d77a45d991ada7496c002c5897821804738973b7ac2ad426d946104b428325e43be9e18a8e7951389e97410829001ffde21b349514354b5fafe99ea
7
+ data.tar.gz: 5bba1a29d6eca9c70fdddf4f4d57a915ab9bee864ce10c760b8e546047f8984e3d53ce712a9affcc91fe798529f6b5f6b82329f099ae98adb02de6e98cb2ddbe
@@ -0,0 +1,91 @@
1
+ module ActiveRecordViews::DatabaseTasks
2
+ def migrate(*)
3
+ super
4
+
5
+ unless ActiveRecordViews::Extension.create_enabled
6
+ Rails.application.eager_load!
7
+ ActiveRecordViews::Extension.process_create_queue!
8
+ ActiveRecordViews.drop_unregistered_views!
9
+ end
10
+ end
11
+
12
+ def dump_schema(db_config, format = ActiveRecord.respond_to?(:schema_format) ? ActiveRecord.schema_format : ActiveRecord::Base.schema_format, *args)
13
+ super
14
+
15
+ return unless format == :sql
16
+
17
+ connection = if respond_to?(:migration_connection)
18
+ migration_connection
19
+ else
20
+ ActiveRecord::Base.connection
21
+ end
22
+ return unless connection.data_source_exists?('active_record_views')
23
+
24
+ filename = case
25
+ when respond_to?(:schema_dump_path)
26
+ schema_dump_path(db_config, format)
27
+ when respond_to?(:dump_filename)
28
+ spec_name = args.first
29
+ dump_filename(spec_name || db_config.name, format)
30
+ else
31
+ raise 'unsupported ActiveRecord version'
32
+ end
33
+
34
+ adapter = case
35
+ when respond_to?(:database_adapter_for)
36
+ database_adapter_for(db_config)
37
+ when respond_to?(:class_for_adapter, true)
38
+ adapter_name = if db_config.respond_to?(:adapter)
39
+ db_config.adapter
40
+ else
41
+ db_config.fetch('adapter')
42
+ end
43
+ class_for_adapter(adapter_name).new(db_config)
44
+ else
45
+ raise 'unsupported ActiveRecord version'
46
+ end
47
+
48
+ database_name = if db_config.respond_to?(:database)
49
+ db_config.database
50
+ else
51
+ db_config.fetch('database')
52
+ end
53
+
54
+ active_record_views_dump = Tempfile.open(['active_record_views_dump', '.sql'])
55
+ adapter.send(:run_cmd, 'pg_dump', %W[--data-only --no-owner --table=active_record_views #{database_name} -f #{active_record_views_dump.path}], 'dumping')
56
+ adapter.send(:remove_sql_header_comments, active_record_views_dump.path)
57
+
58
+ active_record_views_dump_content = active_record_views_dump.read
59
+
60
+ # Substitute out any timestamps that were dumped from the active_record_views table
61
+ #
62
+ # Before:
63
+ #
64
+ # COPY public.active_record_views (name, class_name, checksum, options, refreshed_at) FROM stdin;
65
+ # test_view TestView 42364a017b73ef516a0eca9827e6fa00623257ee {"dependencies":[]} 2021-10-26 02:49:12.247494
66
+ # \.
67
+ #
68
+ # After:
69
+ #
70
+ # COPY public.active_record_views (name, class_name, checksum, options, refreshed_at) FROM stdin;
71
+ # test_view TestView 42364a017b73ef516a0eca9827e6fa00623257ee {"dependencies":[]} \N
72
+ # \.
73
+ if active_record_views_dump_content !~ /^COPY public.active_record_views \(.+, refreshed_at\) FROM stdin;$/
74
+ raise 'refreshed_at is not final column'
75
+ end
76
+ active_record_views_dump_content.gsub!(/\t\d\d\d\d-\d\d-\d\d.*$/, "\t\\N")
77
+
78
+ active_record_views_dump_content = active_record_views_dump_content
79
+ .lines
80
+ .chunk { |line| line.include?("\t") }
81
+ .flat_map { |is_data, lines| is_data ? lines.sort : lines }
82
+ .join
83
+
84
+ File.open filename, 'a' do |io|
85
+ io.puts active_record_views_dump_content
86
+ end
87
+ ensure
88
+ active_record_views_dump&.close
89
+ active_record_views_dump&.unlink
90
+ end
91
+ end
@@ -16,9 +16,5 @@ module ActiveRecordViews
16
16
  end
17
17
  end
18
18
  end
19
-
20
- rake_tasks do
21
- load 'tasks/active_record_views.rake'
22
- end
23
19
  end
24
20
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordViews
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.7'
3
3
  end
@@ -15,6 +15,8 @@ module ActiveRecordViews
15
15
  def self.init!
16
16
  require 'active_record_views/extension'
17
17
  ::ActiveRecord::Base.send :include, ActiveRecordViews::Extension
18
+ require 'active_record_views/database_tasks'
19
+ ::ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend ActiveRecordViews::DatabaseTasks
18
20
  require 'active_record_views/database_cleaner/truncation_extension' if defined? ::DatabaseCleaner
19
21
  end
20
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_views
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Weathered
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2024-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: '6.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '7.1'
22
+ version: '7.3'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.2'
29
+ version: '6.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '7.1'
32
+ version: '7.3'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: appraisal
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -64,14 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 0.5.1
67
+ version: 1.4.0
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
- version: 0.5.1
74
+ version: 1.4.0
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: pg
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -107,49 +107,16 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
- - ".gitignore"
111
- - ".rspec"
112
- - ".tool-versions"
113
- - Appraisals
114
- - Gemfile
115
- - LICENSE.txt
116
110
  - README.markdown
117
- - Rakefile
118
- - activerecord_views.gemspec
119
- - gemfiles/rails5_2.gemfile
120
- - gemfiles/rails6_0.gemfile
121
- - gemfiles/rails6_1.gemfile
122
- - gemfiles/rails7_0.gemfile
123
111
  - lib/active_record_views.rb
124
112
  - lib/active_record_views/checksum_cache.rb
125
113
  - lib/active_record_views/database_cleaner/truncation_extension.rb
114
+ - lib/active_record_views/database_tasks.rb
126
115
  - lib/active_record_views/extension.rb
127
116
  - lib/active_record_views/railtie.rb
128
117
  - lib/active_record_views/registered_view.rb
129
118
  - lib/active_record_views/version.rb
130
119
  - lib/activerecord_views.rb
131
- - lib/tasks/active_record_views.rake
132
- - spec/active_record_views_checksum_cache_spec.rb
133
- - spec/active_record_views_extension_spec.rb
134
- - spec/active_record_views_spec.rb
135
- - spec/internal/Rakefile
136
- - spec/internal/app/models/dependency_a.rb
137
- - spec/internal/app/models/dependency_b.rb
138
- - spec/internal/app/models/dependency_c.rb
139
- - spec/internal/app/models/erb_test_model.rb
140
- - spec/internal/app/models/erb_test_model.sql.erb
141
- - spec/internal/app/models/external_file_test_model.rb
142
- - spec/internal/app/models/external_file_test_model.sql
143
- - spec/internal/app/models/heredoc_test_model.rb
144
- - spec/internal/app/models/modified_a.rb
145
- - spec/internal/app/models/modified_b.rb
146
- - spec/internal/app/models/namespace/test_model.rb
147
- - spec/internal/app/models/namespace/test_model.sql
148
- - spec/internal/config/database.yml
149
- - spec/internal/config/routes.rb
150
- - spec/spec_helper.rb
151
- - spec/support/silence_warnings.rb
152
- - spec/tasks_spec.rb
153
120
  homepage: http://github.com/jasoncodes/activerecord_views
154
121
  licenses:
155
122
  - MIT
@@ -169,29 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
169
136
  - !ruby/object:Gem::Version
170
137
  version: '0'
171
138
  requirements: []
172
- rubygems_version: 3.1.6
139
+ rubygems_version: 3.4.10
173
140
  signing_key:
174
141
  specification_version: 4
175
142
  summary: Automatic database view creation for ActiveRecord
176
- test_files:
177
- - spec/active_record_views_checksum_cache_spec.rb
178
- - spec/active_record_views_extension_spec.rb
179
- - spec/active_record_views_spec.rb
180
- - spec/internal/Rakefile
181
- - spec/internal/app/models/dependency_a.rb
182
- - spec/internal/app/models/dependency_b.rb
183
- - spec/internal/app/models/dependency_c.rb
184
- - spec/internal/app/models/erb_test_model.rb
185
- - spec/internal/app/models/erb_test_model.sql.erb
186
- - spec/internal/app/models/external_file_test_model.rb
187
- - spec/internal/app/models/external_file_test_model.sql
188
- - spec/internal/app/models/heredoc_test_model.rb
189
- - spec/internal/app/models/modified_a.rb
190
- - spec/internal/app/models/modified_b.rb
191
- - spec/internal/app/models/namespace/test_model.rb
192
- - spec/internal/app/models/namespace/test_model.sql
193
- - spec/internal/config/database.yml
194
- - spec/internal/config/routes.rb
195
- - spec/spec_helper.rb
196
- - spec/support/silence_warnings.rb
197
- - spec/tasks_spec.rb
143
+ test_files: []
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- .bundle
2
- tmp/**
3
- Gemfile.lock
4
- gemfiles/*.gemfile.lock
5
- pkg
6
- spec/internal/db/schema.rb
7
- spec/internal/app/models_temp/**
8
- spec/internal/log/*.log
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --colour
2
- --format progress
data/.tool-versions DELETED
@@ -1 +0,0 @@
1
- ruby 2.7.7
data/Appraisals DELETED
@@ -1,15 +0,0 @@
1
- appraise 'rails5_2' do
2
- gem 'rails', '~> 5.2.0'
3
- end
4
-
5
- appraise 'rails6_0' do
6
- gem 'rails', '~> 6.0.0'
7
- end
8
-
9
- appraise 'rails6_1' do
10
- gem 'rails', '~> 6.1.0'
11
- end
12
-
13
- appraise 'rails7_0' do
14
- gem 'rails', '~> 7.0.0'
15
- end
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
data/LICENSE.txt DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2012 Jason Weathered
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile DELETED
@@ -1,14 +0,0 @@
1
- require 'appraisal'
2
- require 'bundler/setup'
3
- require 'bundler/gem_tasks'
4
-
5
- require 'rspec/core/rake_task'
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task :default do
9
- if ENV['BUNDLE_GEMFILE'] == File.expand_path('Gemfile')
10
- exec 'rake appraisal:all'
11
- else
12
- Rake::Task['spec'].invoke
13
- end
14
- end
@@ -1,27 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'active_record_views/version'
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = 'activerecord_views'
8
- gem.version = ActiveRecordViews::VERSION
9
- gem.authors = ['Jason Weathered']
10
- gem.email = ['jason@jasoncodes.com']
11
- gem.summary = %q{Automatic database view creation for ActiveRecord}
12
- gem.homepage = 'http://github.com/jasoncodes/activerecord_views'
13
- gem.license = 'MIT'
14
-
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ['lib']
19
-
20
- gem.add_dependency 'activerecord', ['>= 5.2', '< 7.1']
21
-
22
- gem.add_development_dependency 'appraisal'
23
- gem.add_development_dependency 'rspec-rails', '>= 2.14'
24
- gem.add_development_dependency 'combustion', '>= 0.5.1'
25
- gem.add_development_dependency 'pg'
26
- gem.add_development_dependency 'warning'
27
- end
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "~> 5.2.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "~> 6.0.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "~> 6.1.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "~> 7.0.0"
6
-
7
- gemspec path: "../"
@@ -1,106 +0,0 @@
1
- Rake::Task['db:migrate'].enhance do
2
- unless ActiveRecordViews::Extension.create_enabled
3
- Rails.application.eager_load!
4
- ActiveRecordViews::Extension.process_create_queue!
5
- ActiveRecordViews.drop_unregistered_views!
6
- end
7
- end
8
-
9
- schema_rake_task = Gem::Version.new(Rails.version) >= Gem::Version.new("6.1") ? 'db:schema:dump' : 'db:structure:dump'
10
-
11
- Rake::Task[schema_rake_task].enhance do
12
- table_exists = ActiveRecord::Base.connection.data_source_exists?('active_record_views')
13
-
14
- if schema_rake_task == 'db:structure:dump'
15
- ActiveRecord::Base.schema_format = :sql
16
- end
17
-
18
- schema_format = if ActiveRecord.respond_to?(:schema_format)
19
- ActiveRecord.schema_format
20
- else
21
- ActiveRecord::Base.schema_format
22
- end
23
-
24
- if table_exists && schema_format == :sql
25
- tasks = ActiveRecord::Tasks::DatabaseTasks
26
-
27
- config = if ActiveRecord::Base.configurations.respond_to?(:configs_for)
28
- if Rails.version.start_with?('6.0.')
29
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: 'primary').config
30
- else
31
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'primary')
32
- end
33
- else
34
- tasks.current_config
35
- end
36
- adapter = if config.respond_to?(:adapter)
37
- config.adapter
38
- else
39
- config.fetch('adapter')
40
- end
41
- database = if config.respond_to?(:database)
42
- config.database
43
- else
44
- config.fetch('database')
45
- end
46
-
47
- filename = case
48
- when tasks.respond_to?(:schema_dump_path)
49
- tasks.schema_dump_path(config)
50
- when tasks.respond_to?(:dump_filename)
51
- tasks.dump_filename('primary')
52
- else
53
- tasks.schema_file
54
- end
55
-
56
- pg_tasks = tasks.send(:class_for_adapter, adapter).new(config)
57
- psql_env = if pg_tasks.respond_to?(:psql_env, true)
58
- pg_tasks.send(:psql_env)
59
- else
60
- pg_tasks.send(:set_psql_env)
61
- {}
62
- end
63
-
64
- begin
65
- active_record_views_dump = Tempfile.open("active_record_views_dump.sql")
66
- require 'shellwords'
67
- system(psql_env, "pg_dump --data-only --no-owner --table=active_record_views #{Shellwords.escape database} >> #{Shellwords.escape active_record_views_dump.path}")
68
- raise 'active_record_views metadata dump failed' unless $?.success?
69
-
70
- pg_tasks.send(:remove_sql_header_comments, active_record_views_dump.path)
71
-
72
- active_record_views_dump_content = active_record_views_dump.read
73
-
74
- # Substitute out any timestamps that were dumped from the active_record_views table
75
- #
76
- # Before:
77
- #
78
- # COPY public.active_record_views (name, class_name, checksum, options, refreshed_at) FROM stdin;
79
- # test_view TestView 42364a017b73ef516a0eca9827e6fa00623257ee {"dependencies":[]} 2021-10-26 02:49:12.247494
80
- # \.
81
- #
82
- # After:
83
- #
84
- # COPY public.active_record_views (name, class_name, checksum, options, refreshed_at) FROM stdin;
85
- # test_view TestView 42364a017b73ef516a0eca9827e6fa00623257ee {"dependencies":[]} \N
86
- # \.
87
- if active_record_views_dump_content !~ /^COPY public.active_record_views \(.+, refreshed_at\) FROM stdin;$/
88
- raise 'refreshed_at is not final column'
89
- end
90
- active_record_views_dump_content.gsub!(/\t\d\d\d\d-\d\d-\d\d.*$/, "\t\\N")
91
-
92
- active_record_views_dump_content = active_record_views_dump_content
93
- .lines
94
- .chunk { |line| line.include?("\t") }
95
- .flat_map { |is_data, lines| is_data ? lines.sort : lines }
96
- .join
97
-
98
- File.open filename, 'a' do |io|
99
- io.puts active_record_views_dump_content
100
- end
101
- ensure
102
- active_record_views_dump.close
103
- active_record_views_dump.unlink
104
- end
105
- end
106
- end
@@ -1,112 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecordViews::ChecksumCache do
4
- let(:connection) { ActiveRecord::Base.connection }
5
-
6
- describe 'initialisation' do
7
- def metadata_table_exists?
8
- connection.data_source_exists?('active_record_views')
9
- end
10
-
11
- context 'no existing table' do
12
- it 'creates the table' do
13
- expect(ActiveRecord::Base.connection).to receive(:execute).with(/\ACREATE TABLE active_record_views/).once.and_call_original
14
-
15
- expect(metadata_table_exists?).to eq false
16
- ActiveRecordViews::ChecksumCache.new(connection)
17
- expect(metadata_table_exists?).to eq true
18
-
19
- expect(connection.column_exists?('active_record_views', 'class_name')).to eq true
20
- expect(connection.column_exists?('active_record_views', 'options')).to eq true
21
- end
22
- end
23
-
24
- context 'existing table with current structure' do
25
- before do
26
- ActiveRecordViews::ChecksumCache.new(connection)
27
- expect(metadata_table_exists?).to eq true
28
- end
29
-
30
- it 'does not recreate the table' do
31
- expect(ActiveRecord::Base.connection).to receive(:execute).never
32
-
33
- ActiveRecordViews::ChecksumCache.new(connection)
34
- end
35
- end
36
-
37
- context 'existing table without class name' do
38
- before do
39
- connection.execute 'CREATE TABLE active_record_views(name text PRIMARY KEY, checksum text NOT NULL);'
40
-
41
- connection.execute 'CREATE VIEW test_view AS SELECT 42 AS id;'
42
- connection.execute "INSERT INTO active_record_views VALUES ('test_view', 'dummy');"
43
-
44
- connection.execute 'CREATE VIEW other_view AS SELECT 123 AS id;'
45
- end
46
-
47
- it 'drops existing managed views recreates the table' do
48
- expect(connection.column_exists?('active_record_views', 'class_name')).to eq false
49
- expect(ActiveRecordViews.view_exists?(connection, 'test_view')).to eq true
50
- expect(ActiveRecordViews.view_exists?(connection, 'other_view')).to eq true
51
-
52
- sql_statements.clear
53
-
54
- ActiveRecordViews::ChecksumCache.new(connection)
55
-
56
- expect(sql_statements.grep_v(/^\s*SELECT/)).to match [
57
- 'BEGIN',
58
- 'DROP VIEW IF EXISTS test_view CASCADE;',
59
- 'DROP TABLE active_record_views;',
60
- /^CREATE TABLE active_record_views/,
61
- 'COMMIT',
62
- ]
63
-
64
- expect(connection.column_exists?('active_record_views', 'class_name')).to eq true
65
- expect(ActiveRecordViews.view_exists?(connection, 'test_view')).to eq false
66
- expect(ActiveRecordViews.view_exists?(connection, 'other_view')).to eq true
67
- end
68
- end
69
-
70
- context 'existing table without options or refreshed at timestamp' do
71
- before do
72
- connection.execute 'CREATE TABLE active_record_views(name text PRIMARY KEY, class_name text NOT NULL UNIQUE, checksum text NOT NULL);'
73
-
74
- connection.execute 'CREATE VIEW test_view AS SELECT 42 AS id;'
75
- connection.execute "INSERT INTO active_record_views VALUES ('test_view', 'dummy', 'Dummy');"
76
- end
77
-
78
- it 'upgrades the table without losing data' do
79
- expect(connection.column_exists?('active_record_views', 'options')).to eq false
80
- expect(connection.column_exists?('active_record_views', 'refreshed_at')).to eq false
81
- expect(ActiveRecordViews.view_exists?(connection, 'test_view')).to eq true
82
-
83
- expect(ActiveRecord::Base.connection).to receive(:execute).with("ALTER TABLE active_record_views ADD COLUMN options json NOT NULL DEFAULT '{}';").once.and_call_original
84
- expect(ActiveRecord::Base.connection).to receive(:execute).with("ALTER TABLE active_record_views ADD COLUMN refreshed_at timestamp;").once.and_call_original
85
-
86
- ActiveRecordViews::ChecksumCache.new(connection)
87
-
88
- expect(connection.column_exists?('active_record_views', 'options')).to eq true
89
- expect(connection.column_exists?('active_record_views', 'refreshed_at')).to eq true
90
- expect(ActiveRecordViews.view_exists?(connection, 'test_view')).to eq true
91
- end
92
- end
93
- end
94
-
95
- describe 'options serialization' do
96
- let(:dummy_data) { {class_name: 'Test', checksum: '12345'} }
97
- it 'errors if setting with non-symbol keys' do
98
- cache = ActiveRecordViews::ChecksumCache.new(connection)
99
- expect {
100
- cache.set 'test', dummy_data.merge(options: {'blah' => 123})
101
- }.to raise_error ArgumentError, 'option keys must be symbols'
102
- end
103
-
104
- it 'retrieves hash with symbolized keys and preserves value types' do
105
- options = {foo: 'hi', bar: 123, baz: true}
106
-
107
- cache = ActiveRecordViews::ChecksumCache.new(connection)
108
- cache.set 'test', dummy_data.merge(options: options)
109
- expect(cache.get('test')[:options]).to eq options
110
- end
111
- end
112
- end