activerecord_views 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/active_record_views/database_tasks.rb +91 -0
- data/lib/active_record_views/railtie.rb +0 -4
- data/lib/active_record_views/version.rb +1 -1
- data/lib/active_record_views.rb +2 -0
- metadata +8 -62
- data/.gitignore +0 -8
- data/.rspec +0 -2
- data/.tool-versions +0 -1
- data/Appraisals +0 -15
- data/Gemfile +0 -3
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -14
- data/activerecord_views.gemspec +0 -27
- data/gemfiles/rails5_2.gemfile +0 -7
- data/gemfiles/rails6_0.gemfile +0 -7
- data/gemfiles/rails6_1.gemfile +0 -7
- data/gemfiles/rails7_0.gemfile +0 -7
- data/lib/tasks/active_record_views.rake +0 -106
- data/spec/active_record_views_checksum_cache_spec.rb +0 -112
- data/spec/active_record_views_extension_spec.rb +0 -459
- data/spec/active_record_views_spec.rb +0 -344
- data/spec/internal/Rakefile +0 -24
- data/spec/internal/app/models/dependency_a.rb +0 -3
- data/spec/internal/app/models/dependency_b.rb +0 -3
- data/spec/internal/app/models/dependency_c.rb +0 -3
- data/spec/internal/app/models/erb_test_model.rb +0 -7
- data/spec/internal/app/models/erb_test_model.sql.erb +0 -1
- data/spec/internal/app/models/external_file_test_model.rb +0 -3
- data/spec/internal/app/models/external_file_test_model.sql +0 -1
- data/spec/internal/app/models/heredoc_test_model.rb +0 -5
- data/spec/internal/app/models/modified_a.rb +0 -3
- data/spec/internal/app/models/modified_b.rb +0 -3
- data/spec/internal/app/models/namespace/test_model.rb +0 -3
- data/spec/internal/app/models/namespace/test_model.sql +0 -1
- data/spec/internal/config/database.yml +0 -9
- data/spec/internal/config/routes.rb +0 -3
- data/spec/spec_helper.rb +0 -130
- data/spec/support/silence_warnings.rb +0 -6
- data/spec/tasks_spec.rb +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 483aba6d404f5f766bf6cc234b8c2b8a6675b6a5302f260a362673e95c56d41c
|
4
|
+
data.tar.gz: d95085556edf79f561de0bd9adffdcac7b60ba0e68c8a497140c1584bd0c7e64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 260b637a4b39f22777a9151af3fe4f3305a34dfefd3dfd8410952f2a2a6b3c3a5d9252acb95d7a0fda674469eaf8aa8824576beec0f032ece1b8ca8b3f518e6e
|
7
|
+
data.tar.gz: 69ffc4688582c19b51e842afd5969168da26beccafafd0703d660226b4c3cd3faa1bdf6e0d37206e67decb77725a4f6abb11554e315cac5806b7ce12d7a3a7ee
|
@@ -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
|
data/lib/active_record_views.rb
CHANGED
@@ -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.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Weathered
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-06 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: '
|
19
|
+
version: '6.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '7.
|
22
|
+
version: '7.2'
|
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: '
|
29
|
+
version: '6.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '7.
|
32
|
+
version: '7.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: appraisal
|
35
35
|
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
|
@@ -173,25 +140,4 @@ rubygems_version: 3.1.6
|
|
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
data/.rspec
DELETED
data/.tool-versions
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby 2.7.7
|
data/Appraisals
DELETED
data/Gemfile
DELETED
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
|
data/activerecord_views.gemspec
DELETED
@@ -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
|
data/gemfiles/rails5_2.gemfile
DELETED
data/gemfiles/rails6_0.gemfile
DELETED
data/gemfiles/rails6_1.gemfile
DELETED
data/gemfiles/rails7_0.gemfile
DELETED
@@ -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
|