second_level_cache 2.3.3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +29 -22
- data/Gemfile +4 -2
- data/README.md +7 -1
- data/Rakefile +6 -4
- data/lib/second_level_cache.rb +7 -5
- data/lib/second_level_cache/active_record.rb +15 -10
- data/lib/second_level_cache/active_record/base.rb +2 -0
- data/lib/second_level_cache/active_record/belongs_to_association.rb +2 -0
- data/lib/second_level_cache/active_record/core.rb +2 -0
- data/lib/second_level_cache/active_record/fetch_by_uniq_key.rb +5 -3
- data/lib/second_level_cache/active_record/finder_methods.rb +3 -1
- data/lib/second_level_cache/active_record/has_one_association.rb +2 -0
- data/lib/second_level_cache/active_record/persistence.rb +2 -0
- data/lib/second_level_cache/active_record/preloader.rb +7 -4
- data/lib/second_level_cache/config.rb +3 -1
- data/lib/second_level_cache/mixin.rb +3 -1
- data/lib/second_level_cache/record_marshal.rb +2 -0
- data/lib/second_level_cache/record_relation.rb +2 -0
- data/lib/second_level_cache/version.rb +1 -1
- data/second_level_cache.gemspec +4 -4
- data/test/active_record_test_case_helper.rb +7 -5
- data/test/base_test.rb +6 -4
- data/test/belongs_to_association_test.rb +4 -2
- data/test/enum_attr_test.rb +6 -4
- data/test/fetch_by_uniq_key_test.rb +15 -13
- data/test/finder_methods_test.rb +6 -4
- data/test/has_one_association_test.rb +10 -8
- data/test/model/account.rb +2 -0
- data/test/model/animal.rb +2 -0
- data/test/model/book.rb +2 -0
- data/test/model/image.rb +2 -0
- data/test/model/order.rb +2 -0
- data/test/model/order_item.rb +2 -0
- data/test/model/post.rb +2 -0
- data/test/model/topic.rb +2 -0
- data/test/model/user.rb +6 -4
- data/test/persistence_test.rb +12 -10
- data/test/polymorphic_association_test.rb +4 -2
- data/test/preloader_non_integer_test.rb +17 -14
- data/test/preloader_test.rb +13 -10
- data/test/record_marshal_test.rb +17 -15
- data/test/require_test.rb +7 -5
- data/test/second_level_cache_test.rb +5 -3
- data/test/single_table_inheritance_test.rb +3 -1
- data/test/test_helper.rb +19 -17
- metadata +19 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d4a105d17a40787d4a614e3870220cc480befc73713872f7d427f009d36c7eea
|
4
|
+
data.tar.gz: 1488f0f970f62dc8605d4a669b2b8b9e0b88cc1eb9e7f26961ab2611983b1f41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f240c1fb0e9388e873e8fb40506dca51f12c867447ef091d5d88adb828f1a6d53a151be1aab047028172df4c298a4a691fdc3792d1e3df14c53d6c024557c73c
|
7
|
+
data.tar.gz: 44d71c5531ef6c704303b9e02173b439feff1a0884120b3bd56e07c96a6482baba8218ba1e42201f1ca0a06a1e344440390b0944e5833266e1d04bf6fc7ea79a
|
data/CHANGELOG.md
CHANGED
@@ -1,56 +1,63 @@
|
|
1
|
+
2.4.0
|
2
|
+
---------
|
3
|
+
|
4
|
+
- Fix for support Rails 5.2;
|
5
|
+
- Now second_level_cache 2.4.x has required Rails > 5.2;
|
6
|
+
- Enable `frozen_string_literal = true`;
|
7
|
+
|
1
8
|
2.3.1
|
2
|
-
|
9
|
+
-------
|
3
10
|
|
4
11
|
- Fix some cases will raise "uninitialized constant SecondLevelCache::Mixin" error. (#66)
|
5
12
|
|
6
13
|
2.3.0
|
7
|
-
|
14
|
+
-------
|
8
15
|
|
9
16
|
* Use Model schema digest as cache_version, so you don't need set `:version` option now. (#60)
|
10
17
|
* Fix `store` serialize option (#62)
|
11
18
|
* Remove `acts_as_cached` method now! Please use `second_level_cache`. (#59)
|
12
19
|
|
13
20
|
2.2.7
|
14
|
-
|
21
|
+
-------
|
15
22
|
|
16
23
|
* Use `second_level_cache` instead of `acts_as_cached` method to setup in model. (#56)
|
17
24
|
|
18
25
|
2.2.6
|
19
|
-
|
26
|
+
-------
|
20
27
|
|
21
28
|
* Fix warning in Ruby 2.4.0. (#54)
|
22
29
|
|
23
30
|
2.2.5
|
24
|
-
|
31
|
+
-------
|
25
32
|
|
26
33
|
* Flush cache when belongs_to keys are changed; (#51)
|
27
34
|
* Fix #52 in ActiveRecord 5.0.1, `records_for` API has changed, it's want an `ActiveRecord::Relation` instance to include a `load` method, but second_level_cached returned an Array. (#53)
|
28
35
|
* Fix Rails 5.0.1 `@second_level_cache_enabled` not define warning.
|
29
36
|
|
30
37
|
2.2.4
|
31
|
-
|
38
|
+
-------
|
32
39
|
|
33
40
|
* Fix update conflict in same thread or request context for Cache object. (#49)
|
34
41
|
|
35
42
|
2.2.3
|
36
|
-
|
43
|
+
-------
|
37
44
|
|
38
45
|
* Fix issue with Rails enums. (#43)
|
39
46
|
* Fix to update cache on `update_columns`, `update_attribute`. (#43)
|
40
47
|
|
41
48
|
2.2.2
|
42
|
-
|
49
|
+
-------
|
43
50
|
|
44
51
|
* Add `where(id: n).first`, `where(id: n).last` hit cache support. This improve will avoid some gems query database, for example: [devise](https://github.com/plataformatec/devise) `current_user` method.
|
45
52
|
|
46
53
|
2.2.1
|
47
|
-
|
54
|
+
-------
|
48
55
|
|
49
56
|
* ActiveRecord 5 ready! Do not support ActiveRecord 4 and lower versions now (use second_level_cache 2.1.x).
|
50
57
|
* Requirement Ruby 2.3+.
|
51
58
|
|
52
59
|
2.0.0
|
53
|
-
|
60
|
+
-------
|
54
61
|
|
55
62
|
* ActiveRecord 4 ready!
|
56
63
|
* read multi support for preloading. `Article.includes(:user).limit(5).to_a` will fetch all articles' users from cache preferentially.
|
@@ -58,65 +65,65 @@
|
|
58
65
|
* remove support for find_by_xx which will be removed in Rails 4.1
|
59
66
|
|
60
67
|
1.6.2
|
61
|
-
|
68
|
+
-------
|
62
69
|
|
63
70
|
* [can disable/enable fetch_by_uinq_key method]
|
64
71
|
* [Fix Bug: serialized attribute columns marshal issue #11]
|
65
72
|
|
66
73
|
1.6.1
|
67
|
-
|
74
|
+
-------
|
68
75
|
|
69
76
|
* [Fix bug: undefined method `select_all_column?' for []:ActiveRecord::Relation] by sishen
|
70
77
|
|
71
78
|
1.6.0
|
72
|
-
|
79
|
+
-------
|
73
80
|
|
74
81
|
* [write through cache]
|
75
82
|
* [disable SecondLevelCache for spicial model]
|
76
83
|
* [only cache `SELECT *` query]
|
77
84
|
|
78
85
|
1.5.1
|
79
|
-
|
86
|
+
-------
|
80
87
|
|
81
88
|
* [use new marshal machanism to avoid clear assocation cache manually]
|
82
89
|
|
83
90
|
1.5.0
|
84
|
-
|
91
|
+
-------
|
85
92
|
|
86
93
|
* [add cache version to quick clear cache for special model]
|
87
94
|
|
88
95
|
1.4.1
|
89
|
-
|
96
|
+
-------
|
90
97
|
|
91
98
|
* [fix errors when belongs_to association return nil]
|
92
99
|
|
93
100
|
1.4.0
|
94
|
-
|
101
|
+
-------
|
95
102
|
|
96
103
|
* [cache has one assciation]
|
97
104
|
|
98
105
|
1.3.2
|
99
|
-
|
106
|
+
-------
|
100
107
|
|
101
108
|
* [fix has one assciation issue]
|
102
109
|
|
103
110
|
1.3.1
|
104
|
-
|
111
|
+
-------
|
105
112
|
|
106
113
|
* [clean cache after update_column/increment!/decrement!]
|
107
114
|
|
108
115
|
1.3.0
|
109
|
-
|
116
|
+
-------
|
110
117
|
|
111
118
|
* [clean cache after touch]
|
112
119
|
|
113
120
|
1.2.1
|
114
|
-
|
121
|
+
-------
|
115
122
|
|
116
123
|
* [fix polymorphic association bug]
|
117
124
|
|
118
125
|
1.2.0
|
119
|
-
|
126
|
+
-------
|
120
127
|
|
121
128
|
* [clear cache after update_counters](https://github.com/csdn-dev/second_level_cache/commit/240dde81199124092e0e8ad0500c167ac146e301)
|
122
129
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,13 @@ Write-Through: As objects are created, updated, and deleted, all of the caches a
|
|
16
16
|
|
17
17
|
In your gem file:
|
18
18
|
|
19
|
-
ActiveRecord 5:
|
19
|
+
ActiveRecord 5.2:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'second_level_cache', '~> 2.4.0'
|
23
|
+
```
|
24
|
+
|
25
|
+
ActiveRecord 5.0.x, 5.1.x:
|
20
26
|
|
21
27
|
```ruby
|
22
28
|
gem 'second_level_cache', '~> 2.3.0'
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
-
|
3
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
require "rake/testtask"
|
4
6
|
|
5
7
|
task default: :test
|
6
8
|
|
7
9
|
Rake::TestTask.new do |t|
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
10
|
+
t.libs << "lib" << "test"
|
11
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
12
|
end
|
data/lib/second_level_cache.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/all"
|
4
|
+
require "second_level_cache/config"
|
5
|
+
require "second_level_cache/record_marshal"
|
6
|
+
require "second_level_cache/record_relation"
|
7
|
+
require "second_level_cache/active_record"
|
6
8
|
|
7
9
|
module SecondLevelCache
|
8
10
|
def self.configure
|
@@ -1,12 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "second_level_cache/mixin"
|
4
|
+
require "second_level_cache/active_record/base"
|
5
|
+
require "second_level_cache/active_record/core"
|
6
|
+
require "second_level_cache/active_record/fetch_by_uniq_key"
|
7
|
+
require "second_level_cache/active_record/finder_methods"
|
8
|
+
require "second_level_cache/active_record/persistence"
|
9
|
+
require "second_level_cache/active_record/belongs_to_association"
|
10
|
+
require "second_level_cache/active_record/has_one_association"
|
11
|
+
require "second_level_cache/active_record/preloader"
|
10
12
|
|
11
13
|
# http://api.rubyonrails.org/classes/ActiveSupport/LazyLoadHooks.html
|
12
14
|
# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
|
@@ -18,5 +20,8 @@ ActiveSupport.on_load(:active_record) do
|
|
18
20
|
|
19
21
|
ActiveRecord::Associations::BelongsToAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::BelongsToAssociation)
|
20
22
|
ActiveRecord::Associations::HasOneAssociation.send(:prepend, SecondLevelCache::ActiveRecord::Associations::HasOneAssociation)
|
21
|
-
|
23
|
+
|
24
|
+
# Rails 5.2 has removed ActiveRecord::Associations::Preloader::BelongsTo
|
25
|
+
# https://github.com/rails/rails/pull/31079
|
26
|
+
ActiveRecord::Associations::Preloader::Association.send(:prepend, SecondLevelCache::ActiveRecord::Associations::Preloader::BelongsTo)
|
22
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SecondLevelCache
|
2
4
|
module ActiveRecord
|
3
5
|
module FetchByUniqKey
|
@@ -7,7 +9,7 @@ module SecondLevelCache
|
|
7
9
|
if obj_id
|
8
10
|
begin
|
9
11
|
return find(obj_id)
|
10
|
-
rescue
|
12
|
+
rescue StandardError
|
11
13
|
return nil
|
12
14
|
end
|
13
15
|
end
|
@@ -41,10 +43,10 @@ module SecondLevelCache
|
|
41
43
|
def cache_uniq_key(where_values)
|
42
44
|
keys = where_values.collect do |k, v|
|
43
45
|
v = Digest::MD5.hexdigest(v) if v && v.size >= 32
|
44
|
-
[k, v].join(
|
46
|
+
[k, v].join("_")
|
45
47
|
end
|
46
48
|
|
47
|
-
ext_key = keys.join(
|
49
|
+
ext_key = keys.join(",")
|
48
50
|
"uniq_key_#{name}_#{ext_key}"
|
49
51
|
end
|
50
52
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SecondLevelCache
|
2
4
|
module ActiveRecord
|
3
5
|
module FinderMethods
|
@@ -54,7 +56,7 @@ module SecondLevelCache
|
|
54
56
|
end
|
55
57
|
|
56
58
|
record = super(limit)
|
57
|
-
record
|
59
|
+
record&.write_second_level_cache
|
58
60
|
record
|
59
61
|
end
|
60
62
|
|
@@ -1,17 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SecondLevelCache
|
2
4
|
module ActiveRecord
|
3
5
|
module Associations
|
4
6
|
class Preloader
|
5
7
|
module BelongsTo
|
6
|
-
def records_for(ids)
|
7
|
-
return super(ids) unless
|
8
|
+
def records_for(ids, &block)
|
9
|
+
return super(ids, &block) unless reflection.is_a?(::ActiveRecord::Reflection::BelongsToReflection)
|
10
|
+
return super(ids, &block) unless klass.second_level_cache_enabled?
|
8
11
|
|
9
12
|
map_cache_keys = ids.map { |id| klass.second_level_cache_key(id) }
|
10
13
|
records_from_cache = ::SecondLevelCache.cache_store.read_multi(*map_cache_keys)
|
11
14
|
# NOTICE
|
12
15
|
# Rails.cache.read_multi return hash that has keys only hitted.
|
13
16
|
# eg. Rails.cache.read_multi(1,2,3) => {2 => hit_value, 3 => hit_value}
|
14
|
-
hitted_ids = records_from_cache.map { |key, _| key.split(
|
17
|
+
hitted_ids = records_from_cache.map { |key, _| key.split("/")[2] }
|
15
18
|
missed_ids = ids.map(&:to_s) - hitted_ids
|
16
19
|
|
17
20
|
::SecondLevelCache.logger.info "missed ids -> #{missed_ids.join(',')} | hitted ids -> #{hitted_ids.join(',')}"
|
@@ -22,7 +25,7 @@ module SecondLevelCache
|
|
22
25
|
return SecondLevelCache::RecordRelation.new(record_marshals)
|
23
26
|
end
|
24
27
|
|
25
|
-
records_from_db = super(missed_ids)
|
28
|
+
records_from_db = super(missed_ids, &block)
|
26
29
|
records_from_db.map do |r|
|
27
30
|
write_cache(r)
|
28
31
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SecondLevelCache
|
2
4
|
module Mixin
|
3
5
|
extend ActiveSupport::Concern
|
@@ -39,7 +41,7 @@ module SecondLevelCache
|
|
39
41
|
return @cache_version if defined? @cache_version
|
40
42
|
# This line is copy from:
|
41
43
|
# https://github.com/rails/rails/blob/f9a5f48/activerecord/lib/active_record/core.rb#L236
|
42
|
-
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } *
|
44
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
43
45
|
model_schema_digest = Digest::MD5.hexdigest(attr_list)
|
44
46
|
@cache_version = "#{second_level_cache_options[:version]}/#{model_schema_digest}"
|
45
47
|
end
|
data/second_level_cache.gemspec
CHANGED
@@ -30,12 +30,12 @@ Gem::Specification.new do |gem|
|
|
30
30
|
gem.require_paths = ['lib']
|
31
31
|
gem.version = SecondLevelCache::VERSION
|
32
32
|
|
33
|
-
gem.add_runtime_dependency 'activesupport', ['>= 5.0.
|
34
|
-
gem.add_runtime_dependency 'activerecord', ['>= 5.0.
|
33
|
+
gem.add_runtime_dependency 'activesupport', ['>= 5.2.0.rc', '< 6']
|
34
|
+
gem.add_runtime_dependency 'activerecord', ['>= 5.2.0.rc', '< 6']
|
35
35
|
|
36
36
|
gem.add_development_dependency 'sqlite3'
|
37
37
|
gem.add_development_dependency 'rake'
|
38
38
|
gem.add_development_dependency 'pry'
|
39
|
-
gem.add_development_dependency 'database_cleaner'
|
40
|
-
gem.add_development_dependency 'rubocop'
|
39
|
+
gem.add_development_dependency 'database_cleaner'
|
40
|
+
gem.add_development_dependency 'rubocop', "~> 0.52.0"
|
41
41
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/test_case"
|
2
4
|
|
3
5
|
module ActiveRecordTestCaseHelper
|
4
6
|
def teardown
|
@@ -48,7 +50,7 @@ module ActiveRecordTestCaseHelper
|
|
48
50
|
x = yield
|
49
51
|
the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
|
50
52
|
if num == :any
|
51
|
-
assert_operator the_log.size, :>=, 1,
|
53
|
+
assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
|
52
54
|
else
|
53
55
|
mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.empty? ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
|
54
56
|
assert_equal num, the_log.size, mesg
|
@@ -110,13 +112,13 @@ module ActiveRecordTestCaseHelper
|
|
110
112
|
|
111
113
|
# FIXME: this seems bad. we should probably have a better way to indicate
|
112
114
|
# the query was cached
|
113
|
-
return if
|
115
|
+
return if values[:name] == "CACHE"
|
114
116
|
|
115
117
|
self.class.log_all << sql
|
116
|
-
self.class.log << sql unless ignore
|
118
|
+
self.class.log << sql unless ignore.match?(sql)
|
117
119
|
end
|
118
120
|
|
119
|
-
ActiveSupport::Notifications.subscribe(
|
121
|
+
ActiveSupport::Notifications.subscribe("sql.active_record", SQLCounter.new)
|
120
122
|
end
|
121
123
|
end
|
122
124
|
|