constant_table_saver 5.1.1 → 6.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bd0a0f0466a9358d62172e153ae85c8a88a0e9a9
4
- data.tar.gz: b6d62a665e5a4b179101924c320e3ca2dd773e35
2
+ SHA256:
3
+ metadata.gz: 3439491d2c0407e721feb9f068213d83278391d6fca8c93c29ca3fc147902c37
4
+ data.tar.gz: 2fa2009f42c977f20eedf9fa3e11e841249250afc388f49e23d1f172b75a0d11
5
5
  SHA512:
6
- metadata.gz: 350eef086260e755159c68fa837515eff1c50f79b90a6044fb3ecdc806b78955faa9ba5716e73ad0b92827e7bad2c3e11666a0914a872e7df086a195c9f7b205
7
- data.tar.gz: 0d9a1eed230c95df417727e8693da32e9168b8dd428a49aee3cbf6d08e73e650824c9d453878d01a7de2461e31ad4b40792c142bf3a6267b0bd3c548de3ad4c9
6
+ metadata.gz: 62723639d7273610e9210e411be9be75a1a50c52e995d54ed4d4a8933e127d29ce9ed30f3521a9ae4d97dc7f6b68b1ca0535a33c64afae9d4d36c1523f90da5f
7
+ data.tar.gz: 3f3a6ae939f87669cc844e83d586d5dd224356344bc5f7a5c9a19b7c00be76468d65c146d13c6614defa9b79001b6481331e2f22b37bd7cc8c2f222bc6abf108
@@ -0,0 +1,14 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ dist: bionic
6
+ rvm:
7
+ - 2.6
8
+ services:
9
+ - postgresql
10
+ - mysql
11
+ before_script:
12
+ - createdb -U postgres columns_on_demand_test
13
+ - mysqladmin -u root create columns_on_demand_test
14
+ script: ./test_all.sh
@@ -0,0 +1,49 @@
1
+ # this Dockerfile is used only to get a consistent environment in which to run the tests (test_all.rb),
2
+ # it has nothing to do with the actual gem that gets published.
3
+
4
+ # use an older version of ubuntu so that we get a version of postgresql so is supported by the older rails
5
+ # versions, or we won't be able to test out support for them.
6
+ FROM ubuntu:16.04
7
+
8
+ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
9
+ apt-get install -y software-properties-common && \
10
+ apt-add-repository ppa:brightbox/ruby-ng && \
11
+ DEBIAN_FRONTEND=noninteractive apt-get update && \
12
+ DEBIAN_FRONTEND=noninteractive apt-get upgrade -y && \
13
+ DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential git \
14
+ mysql-server libmysqlclient-dev postgresql-9.5 libpq-dev libsqlite3-dev \
15
+ ruby2.5 ruby2.5-dev && \
16
+ rm -f /etc/apt/apt.conf.d/20auto-upgrades && \
17
+ apt-get clean -y && \
18
+ rm -rf /var/cache/apt/archives/*
19
+
20
+ RUN ln -sf /usr/bin/ruby2.5 /usr/bin/ruby
21
+ RUN ln -sf /usr/bin/gem2.5 /usr/bin/gem
22
+ RUN gem install bundler -v 1.16.4 --no-ri --no-rdoc
23
+
24
+ # install a version of mysql2 that the older versions of rails are compatible with
25
+ RUN gem install mysql2 -v 0.4.10
26
+
27
+ WORKDIR /tmp
28
+ ADD Gemfile Gemfile
29
+ ADD constant_table_saver.gemspec constant_table_saver.gemspec
30
+ ADD lib/constant_table_saver/version.rb lib/constant_table_saver/version.rb
31
+ RUN bundle install -j 4
32
+
33
+ ADD . .
34
+ RUN echo 'starting postgresql' && \
35
+ service postgresql start && \
36
+ echo 'creating postgresql database' && \
37
+ su postgres -c 'createdb --encoding unicode --template template0 constant_table_saver_test' && \
38
+ echo 'creating postgresql user' && \
39
+ su postgres -c 'createuser --superuser root' && \
40
+ echo 'starting mysql' && \
41
+ mkdir -p /var/run/mysqld && \
42
+ chown mysql:mysql /var/run/mysqld && \
43
+ (/usr/sbin/mysqld --skip-grant-tables &) && \
44
+ echo 'waiting for mysql to start' && \
45
+ mysqladmin --wait=30 ping && \
46
+ echo 'creating mysql database' && \
47
+ mysqladmin create constant_table_saver_test && \
48
+ echo 'running tests' && \
49
+ ./test_all.rb
data/Gemfile CHANGED
@@ -10,6 +10,9 @@ gemspec
10
10
  # Git. Remember to move these dependencies to your gemspec before releasing
11
11
  # your gem to rubygems.org.
12
12
 
13
- # To use debugger
14
- # gem 'ruby-debug19', :require => 'ruby-debug'
15
- # gem 'ruby-debug'
13
+ gem 'rails', ENV['RAILS_VERSION']
14
+
15
+ # see notes in the gemspec
16
+ if ENV['RAILS_VERSION'] =~ /^5\.0/
17
+ gem "sqlite3", "~> 1.3.6"
18
+ end
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Will Bryant, Sekuda Ltd
1
+ Copyright (c) 2010-2018 Will Bryant, Sekuda Ltd
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -11,9 +11,7 @@ named after the name field you specify.
11
11
  Compatibility
12
12
  =============
13
13
 
14
- Currently tested against Rails 5.1 (5.1.0beta2) and 5.0 (up to 5.0.2) and 4.2 (up to 4.2.7), on Ruby 2.3.4.
15
-
16
- For earlier versions of Rails, use an older version of the gem.
14
+ Currently tested against Rails 6.1.0.rc1, 6.0.3.4, 5.2.4.4, 5.1.7, and 5.0.7.2, with older gem versions compatible with earlier Rails versions.
17
15
 
18
16
 
19
17
  Example
@@ -82,4 +80,9 @@ Means you will also have methods returning those records:
82
80
  Optionally, you can specify a `:name_prefix` and/or `:name_suffix`.
83
81
 
84
82
 
85
- Copyright (c) 2010-2017 Will Bryant, Sekuda Ltd, released under the MIT license
83
+ Thanks
84
+ ======
85
+
86
+ * Marc Shaw (@marcshaw)
87
+
88
+ Copyright (c) 2010-2018 Will Bryant, Sekuda Ltd, released under the MIT license
data/Rakefile CHANGED
@@ -13,4 +13,5 @@ Rake::TestTask.new(:test) do |t|
13
13
  t.libs << 'test'
14
14
  t.pattern = 'test/*_test.rb'
15
15
  t.verbose = true
16
+ t.warning = false
16
17
  end
@@ -11,16 +11,7 @@ cached (and frozen) records for all find calls.
11
11
 
12
12
  Optionally, creates class-level methods you can use to grab the records,
13
13
  named after the name field you specify.
14
-
15
-
16
- Compatibility
17
- =============
18
-
19
- Currently tested against Rails 5.1 (5.1.0beta2) and 5.0 (up to 5.0.2) and 4.2 (up to 4.2.7), on Ruby 2.3.4.
20
-
21
- For earlier versions of Rails, use an older version of the gem.
22
14
  EOF
23
- gem.has_rdoc = false
24
15
  gem.author = "Will Bryant"
25
16
  gem.email = "will.bryant@gmail.com"
26
17
  gem.homepage = "http://github.com/willbryant/constant_table_saver"
@@ -33,5 +24,8 @@ EOF
33
24
 
34
25
  gem.add_dependency "activerecord"
35
26
  gem.add_development_dependency "rake"
36
- gem.add_development_dependency "sqlite3"
27
+ gem.add_development_dependency "mysql2" # you probably want 0.4.10 if testing with old versions of rails, but this gem doesn't care
28
+ gem.add_development_dependency "pg" # you probably want 0.21.0 if testing with old versions of rails, but this gem doesn't care
29
+ gem.add_development_dependency "sqlite3" # you probably want 1.3.6 if testing with old versions of rails, but this gem doesn't care
30
+ gem.add_development_dependency "byebug"
37
31
  end
@@ -12,8 +12,10 @@ module ConstantTableSaver
12
12
 
13
13
  if ActiveRecord::VERSION::MAJOR == 4
14
14
  extend ActiveRecord4ClassMethods
15
- else
15
+ elsif ActiveRecord::VERSION::MAJOR == 5 && (ActiveRecord::VERSION::MINOR == 0 || ActiveRecord::VERSION::MINOR == 1)
16
16
  extend ActiveRecord5ClassMethods
17
+ else
18
+ extend ActiveRecord52ClassMethods
17
19
  end
18
20
  extend ClassMethods
19
21
  extend NameClassMethods if constant_table_options[:name]
@@ -52,16 +54,6 @@ module ConstantTableSaver
52
54
  @cached_records = @cached_records_by_id = @constant_record_methods = @cached_blank_scope = @find_by_sql = nil
53
55
  end
54
56
 
55
- def _to_sql_with_binds(sql, binds)
56
- if sql.respond_to?(:to_sql)
57
- # an arel object
58
- connection.to_sql(sql, binds)
59
- else
60
- # a plain string
61
- sql
62
- end
63
- end
64
-
65
57
  def relation
66
58
  super.tap do |s|
67
59
  class << s
@@ -77,10 +69,46 @@ module ConstantTableSaver
77
69
  end
78
70
  end
79
71
 
72
+ module ActiveRecord52ClassMethods
73
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
74
+ @cached_records ||= super(relation.to_sql, &nil).each(&:freeze).freeze
75
+
76
+ # to_sql_and_binds returns [sql, binds] prior to 6.1, and [sql, binds, preparable] on 6.1. we take the [0..1] slice
77
+ # to ignore the preparable flag, which is useful metadata for adapters but not required for us to match statements.
78
+ @cached_results ||= @cached_records.each_with_object({
79
+ # matches .all queries:
80
+ to_sql_and_binds(relation)[0..1] => @cached_records,
81
+
82
+ # matches .first queries:
83
+ to_sql_and_binds(relation.order(relation.table[primary_key].asc).limit(1).arel)[0..1] => [@cached_records.first].compact,
84
+
85
+ # matches .last queries:
86
+ to_sql_and_binds(relation.order(relation.table[primary_key].desc).limit(1).arel)[0..1] => [@cached_records.last].compact,
87
+ }) do |record, results|
88
+ results[to_sql_and_binds(relation.where(relation.table[primary_key].eq(relation.predicate_builder.build_bind_attribute(primary_key, record.id))).limit(1).arel)[0..1]] = [record]
89
+ end.freeze
90
+
91
+ sql_and_binds = to_sql_and_binds(sql, binds)[0..1]
92
+ sql_and_binds = [sql_and_binds.first, []] unless connection.prepared_statements
93
+
94
+ if results = @cached_results[sql_and_binds]
95
+ results
96
+ else
97
+ super(sql, binds, preparable: preparable, &block)
98
+ end
99
+ end
100
+
101
+ private
102
+ def to_sql_and_binds(sql, binds = [])
103
+ sql = sql.arel if sql.respond_to?(:arel)
104
+ connection.send(:to_sql_and_binds, sql, binds)
105
+ end
106
+ end
107
+
80
108
  module ActiveRecord5ClassMethods
81
109
  def find_by_sql(sql, binds = [], preparable: nil, &block)
82
110
  @find_by_sql ||= {
83
- :all => all.to_sql,
111
+ :all => relation.to_sql,
84
112
  :id => relation.where(relation.table[primary_key].eq(Arel::Nodes::BindParam.new)).limit(1).arel,
85
113
  :first => relation.order(relation.table[primary_key].asc).limit(1).arel,
86
114
  :last => relation.order(relation.table[primary_key].desc).limit(1).arel,
@@ -114,12 +142,22 @@ module ConstantTableSaver
114
142
 
115
143
  super(sql, binds, preparable: preparable, &block)
116
144
  end
145
+
146
+ def _to_sql_with_binds(sql, binds)
147
+ if sql.respond_to?(:to_sql)
148
+ # an arel object
149
+ connection.to_sql(sql, binds)
150
+ else
151
+ # a plain string
152
+ sql
153
+ end
154
+ end
117
155
  end
118
156
 
119
157
  module ActiveRecord4ClassMethods
120
158
  def find_by_sql(sql, binds = [])
121
159
  @find_by_sql ||= {
122
- :all => all.to_sql,
160
+ :all => relation.to_sql,
123
161
  :id => relation.where(relation.table[primary_key].eq(connection.substitute_at(columns_hash[primary_key], 0))).limit(1).
124
162
  tap {|r| r.bind_values += [[columns_hash[primary_key], :undefined]]}. # work around AR 4.1.9-4.1.x (but not 4.2.x) calling nil.first if there's no bind_values
125
163
  arel,
@@ -148,6 +186,16 @@ module ConstantTableSaver
148
186
 
149
187
  super
150
188
  end
189
+
190
+ def _to_sql_with_binds(sql, binds)
191
+ if sql.respond_to?(:to_sql)
192
+ # an arel object
193
+ connection.to_sql(sql, binds)
194
+ else
195
+ # a plain string
196
+ sql
197
+ end
198
+ end
151
199
  end
152
200
 
153
201
  module NameClassMethods
@@ -1,3 +1,3 @@
1
1
  module ConstantTableSaver
2
- VERSION = '5.1.1'
2
+ VERSION = '6.1.0'
3
3
  end
@@ -8,12 +8,18 @@ end
8
8
  class ConstantPie < ActiveRecord::Base
9
9
  set_table_name "pies"
10
10
  constant_table
11
+
12
+ has_one :ingredient, class_name: "IngredientForConstantPie", foreign_key: 'pie_id'
11
13
 
12
14
  scope :filled_with_unicorn, -> { where(:filling => 'unicorn') }
13
15
 
14
16
  def self.with_unicorn_filling_scope
15
17
  with_scope(:find => {:conditions => {:filling => 'unicorn'}}) { yield }
16
18
  end
19
+
20
+ def self.retrieve_pies
21
+ all.map { |x| x }
22
+ end
17
23
  end
18
24
 
19
25
  class ConstantNamedPie < ActiveRecord::Base
@@ -148,6 +154,7 @@ class ConstantTableSaverTest < ActiveSupport::TestCase
148
154
  @pies = StandardPie.select("id").all.to_a
149
155
  @pie = StandardPie.select("id").find(1)
150
156
  @second_pie = StandardPie.select("id").find(2)
157
+ ConstantPie.first
151
158
  assert_queries(3) do
152
159
  assert_equal @pies.collect(&:attributes), ConstantPie.select("id").all.collect(&:attributes)
153
160
  assert_equal @pie.attributes, ConstantPie.select("id").find(1).attributes
@@ -160,6 +167,26 @@ class ConstantTableSaverTest < ActiveSupport::TestCase
160
167
  end
161
168
  end
162
169
 
170
+ test "it doesn't cache find queries on scoped methods, even when no binds are set, if the records have been cached" do
171
+ ConstantPie.all.to_a
172
+ assert_queries(1) do
173
+ @pies = ConstantPie.where(:filling => ["Tasty beef steak"]).retrieve_pies
174
+ end
175
+ assert_equal 1, @pies.size
176
+ end
177
+
178
+ test "it doesn't cache find queries on scoped methods, even when no binds are set, if the records have not been cached" do
179
+ # these two lines are needed to fix random test order failures when nothing has hit the ConstantPie schema before
180
+ ConstantPie.all.to_a
181
+ ConstantPie.reset_constant_record_cache!
182
+
183
+ # retrieve_pies here is to test the behavior of scoped class methods:
184
+ @pies = ConstantPie.where(:filling => ["Tasty beef steak"]).retrieve_pies
185
+ assert_equal 1, @pies.size
186
+
187
+ assert_equal StandardPie.count, ConstantPie.all.to_a.size
188
+ end
189
+
163
190
  test "it passes the options preventing caching to the underlying query methods" do
164
191
  assert_nil ConstantPie.where(:filling => 'unicorn').first
165
192
  assert_equal [], ConstantPie.where(:filling => 'unicorn').all
@@ -209,4 +236,11 @@ class ConstantTableSaverTest < ActiveSupport::TestCase
209
236
  ConstantPie.find([max_id, max_id + 1])
210
237
  end
211
238
  end
239
+
240
+ test "it correctly loads when includes are used" do
241
+ IngredientForConstantPie.includes(:pie).find_by(:id => 3)
242
+ assert_queries(2) do
243
+ IngredientForConstantPie.includes(:pie).find_by(:id => 3)
244
+ end
245
+ end
212
246
  end
@@ -1,10 +1,6 @@
1
1
  sqlite3:
2
2
  adapter: sqlite3
3
3
  database: test/constant_table_saver.db
4
- mysql:
5
- adapter: mysql
6
- database: constant_table_saver_test
7
- username: root
8
4
  mysql2:
9
5
  adapter: mysql2
10
6
  database: constant_table_saver_test
@@ -11,7 +11,7 @@ require 'active_support'
11
11
  require 'active_support/test_case'
12
12
  require 'active_record'
13
13
  require 'active_record/fixtures'
14
- require 'byebug' rescue nil
14
+ require 'byebug'
15
15
 
16
16
  RAILS_ENV = ENV['RAILS_ENV'] ||= 'sqlite3'
17
17
 
@@ -2,12 +2,15 @@
2
2
 
3
3
  require 'yaml'
4
4
 
5
- rails_versions = ["4.2.0".."4.2.3", "4.1.07".."4.1.12", "4.0.13", "3.2.18"].flat_map {|spec| Array(spec).collect {|v| v.gsub /.0(\d)/, '.\\1'}}
5
+ rails_versions = ["6.1.0.rc1", "6.0.3.4 ", "5.2.4.4", "5.1.7", "5.0.7.2"].flat_map {|spec| Array(spec).collect {|v| v.gsub /.0(\d)/, '.\\1'}}
6
6
  rails_envs = YAML.load(File.read("test/database.yml")).keys
7
7
 
8
- rails_envs.each do |env|
9
- rails_versions.each do |version|
10
- puts "*"*40
11
- system "RAILS_ENV=#{env} RAILS_VERSION=#{version} rake" or exit(1)
8
+ rails_versions.each do |version|
9
+ puts "*"*40
10
+ system "RAILS_VERSION=#{version} bundle update" or exit(1)
11
+
12
+ rails_envs.each do |env|
13
+ puts "Rails #{version}, #{env}"
14
+ system "RAILS_ENV=#{env} bundle exec rake" or exit(2)
12
15
  end
13
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constant_table_saver
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.1
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Bryant
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-07 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: sqlite3
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -52,26 +80,34 @@ dependencies:
52
80
  - - ">="
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
55
97
  description: |
56
98
  Loads all records from the table on first use, and thereafter returns the
57
99
  cached (and frozen) records for all find calls.
58
100
 
59
101
  Optionally, creates class-level methods you can use to grab the records,
60
102
  named after the name field you specify.
61
-
62
-
63
- Compatibility
64
- =============
65
-
66
- Currently tested against Rails 5.1 (5.1.0beta2) and 5.0 (up to 5.0.2) and 4.2 (up to 4.2.7), on Ruby 2.3.4.
67
-
68
- For earlier versions of Rails, use an older version of the gem.
69
103
  email: will.bryant@gmail.com
70
104
  executables: []
71
105
  extensions: []
72
106
  extra_rdoc_files: []
73
107
  files:
74
108
  - ".gitignore"
109
+ - ".travis.yml"
110
+ - Dockerfile
75
111
  - Gemfile
76
112
  - MIT-LICENSE
77
113
  - README.md
@@ -92,7 +128,7 @@ homepage: http://github.com/willbryant/constant_table_saver
92
128
  licenses:
93
129
  - MIT
94
130
  metadata: {}
95
- post_install_message:
131
+ post_install_message:
96
132
  rdoc_options: []
97
133
  require_paths:
98
134
  - lib
@@ -107,9 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
143
  - !ruby/object:Gem::Version
108
144
  version: '0'
109
145
  requirements: []
110
- rubyforge_project:
111
- rubygems_version: 2.5.2
112
- signing_key:
146
+ rubygems_version: 3.0.3
147
+ signing_key:
113
148
  specification_version: 4
114
149
  summary: Caches the records from fixed tables, and provides convenience methods to
115
150
  get them.