ar_cache 1.5.0 → 2.0.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 +4 -4
- data/CHANGELOG.md +0 -41
- data/Gemfile.common +2 -0
- data/Gemfile.lock +81 -77
- data/README.md +4 -4
- data/README.zh-CN.md +165 -0
- data/ar_cache.gemspec +1 -0
- data/lib/ar_cache.rb +31 -16
- data/lib/ar_cache/active_record/associations/association.rb +1 -1
- data/lib/ar_cache/active_record/associations/has_one_through_association.rb +2 -3
- data/lib/ar_cache/active_record/associations/singular_association.rb +1 -1
- data/lib/ar_cache/active_record/connection_adapters/abstract/database_statements.rb +20 -15
- data/lib/ar_cache/active_record/connection_adapters/abstract/transaction.rb +37 -32
- data/lib/ar_cache/active_record/core.rb +5 -4
- data/lib/ar_cache/active_record/insert_all.rb +1 -4
- data/lib/ar_cache/active_record/model_schema.rb +1 -7
- data/lib/ar_cache/active_record/persistence.rb +4 -5
- data/lib/ar_cache/active_record/relation.rb +7 -8
- data/lib/ar_cache/configuration.rb +34 -41
- data/lib/ar_cache/marshal.rb +29 -27
- data/lib/ar_cache/mock_table.rb +4 -4
- data/lib/ar_cache/query.rb +21 -12
- data/lib/ar_cache/table.rb +44 -50
- data/lib/ar_cache/version.rb +1 -1
- data/lib/ar_cache/where_clause.rb +34 -25
- data/lib/generators/ar_cache/install_generator.rb +0 -7
- data/lib/generators/ar_cache/templates/configuration.rb +20 -24
- metadata +23 -5
- data/lib/ar_cache/record.rb +0 -52
- data/lib/ar_cache/store.rb +0 -38
- data/lib/generators/ar_cache/templates/migrate/create_ar_cache_records.rb.tt +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4d25cbd1abb845a90dbd29d50d1dfb5b622e454e6c0bfe4a1ae65b4eddb818f
|
4
|
+
data.tar.gz: 821f3036d2df0db1f143a3212cffacf306ac30aa2335385defde6b41edf5f46d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0a9706501fa606ee7cf02931bdbfc5efd3e2668fb5b51c55b971d616233b43595363b30ccf279d500df64789268398c140870c8683b7e79e8b70717ebd2983a
|
7
|
+
data.tar.gz: 46e0a6c9a76401dec6d2f3c11f52e4e9a3e0d1b975c827df7eca05f0068612d78755238db00c5f170ab30523c5aee15eb6556b3956599490d0a812d4f8d917d5
|
data/CHANGELOG.md
CHANGED
@@ -1,44 +1,3 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
3
|
## main
|
4
|
-
|
5
|
-
## 1.5.0 (2021-03-22 UTC)
|
6
|
-
|
7
|
-
[Compare [#7cc9ec8..10f9eea](https://github.com/OuYangJinTing/ar_cache/compare/7cc9ec8..10f9eea)]:
|
8
|
-
|
9
|
-
- Fix `has_one thtough:` strict loading error.
|
10
|
-
- Fix `#detect_wrong_key`, should check `nil` value match.
|
11
|
-
- Rename `ArCache::Configuration#index_column_max_size` => `ArCache::Configuration#column_length`
|
12
|
-
|
13
|
-
## 1.4.0 (2021-03-15 UTC)
|
14
|
-
|
15
|
-
[Compare [#3ff0bb8..7cc9ec8](https://github.com/OuYangJinTing/ar_cache/compare/3ff0bb8..7cc9ec8)]:
|
16
|
-
|
17
|
-
- Remove `ArCache::Table` `ignored_columns` configuration.
|
18
|
-
- Fix `ActiveRecord` call `#select` write to cache data is incomplete.
|
19
|
-
|
20
|
-
## 1.3.0 (2021-03-13 UTC)
|
21
|
-
|
22
|
-
[Compare [#4328f38..4ec14e9](https://github.com/OuYangJinTing/ar_cache/compare/4328f38..4ec14e9)]:
|
23
|
-
|
24
|
-
- Optimize association cache, only cacheable association use ArCache query now.
|
25
|
-
|
26
|
-
## 1.2.0 (2021-03-12 UTC)
|
27
|
-
|
28
|
-
[Compare [#eb27f99..c830907](https://github.com/OuYangJinTing/ar_cache/compare/eb27f99..c830907)]:
|
29
|
-
|
30
|
-
- Remove methods: `ArCache::MockTable#enabled?`, `ArCache::MockTable#select_enabled?`, `ArCache::Table.enabled?`, `ArCache::Table.select_enabled?`, `ActiveRecord::Relation#skip_ar_cache`.
|
31
|
-
- Rename methods: `ArCache#skip_cache? => ArCache#skip?`, `ArCache#skip_cache => ArCache#skip`, `ArCache#pre_expire? => ArCache#expire?`, `ArCache#pre_expire => ArCache#expire`.
|
32
|
-
- Now, `ArCache#skip` method only skip read cache, but still try delete cache.
|
33
|
-
|
34
|
-
## 1.1.0 (2021-03-10 UTC)
|
35
|
-
|
36
|
-
[Compare [#a15d5f5..ce5444c](https://github.com/OuYangJinTing/ar_cache/compare/a15d5f5...ce5444c)]:
|
37
|
-
|
38
|
-
- Fully automatic delete cache when call delete_all/update_all method.
|
39
|
-
- Optimize has_one(through:) cache implementation.
|
40
|
-
- ActiveRecord::Relation#reload and ActiveRecord::Associations::Association#reload should skip read cache if associated target is already loaded.
|
41
|
-
|
42
|
-
## 1.0.0 (2021-03-02 UTC)
|
43
|
-
|
44
|
-
- Initial version.
|
data/Gemfile.common
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,66 +1,67 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ar_cache (
|
4
|
+
ar_cache (2.0.0)
|
5
5
|
activerecord (>= 6.1, < 7)
|
6
|
+
oj (>= 3, < 4)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
10
|
-
actioncable (6.1.3)
|
11
|
-
actionpack (= 6.1.3)
|
12
|
-
activesupport (= 6.1.3)
|
11
|
+
actioncable (6.1.3.2)
|
12
|
+
actionpack (= 6.1.3.2)
|
13
|
+
activesupport (= 6.1.3.2)
|
13
14
|
nio4r (~> 2.0)
|
14
15
|
websocket-driver (>= 0.6.1)
|
15
|
-
actionmailbox (6.1.3)
|
16
|
-
actionpack (= 6.1.3)
|
17
|
-
activejob (= 6.1.3)
|
18
|
-
activerecord (= 6.1.3)
|
19
|
-
activestorage (= 6.1.3)
|
20
|
-
activesupport (= 6.1.3)
|
16
|
+
actionmailbox (6.1.3.2)
|
17
|
+
actionpack (= 6.1.3.2)
|
18
|
+
activejob (= 6.1.3.2)
|
19
|
+
activerecord (= 6.1.3.2)
|
20
|
+
activestorage (= 6.1.3.2)
|
21
|
+
activesupport (= 6.1.3.2)
|
21
22
|
mail (>= 2.7.1)
|
22
|
-
actionmailer (6.1.3)
|
23
|
-
actionpack (= 6.1.3)
|
24
|
-
actionview (= 6.1.3)
|
25
|
-
activejob (= 6.1.3)
|
26
|
-
activesupport (= 6.1.3)
|
23
|
+
actionmailer (6.1.3.2)
|
24
|
+
actionpack (= 6.1.3.2)
|
25
|
+
actionview (= 6.1.3.2)
|
26
|
+
activejob (= 6.1.3.2)
|
27
|
+
activesupport (= 6.1.3.2)
|
27
28
|
mail (~> 2.5, >= 2.5.4)
|
28
29
|
rails-dom-testing (~> 2.0)
|
29
|
-
actionpack (6.1.3)
|
30
|
-
actionview (= 6.1.3)
|
31
|
-
activesupport (= 6.1.3)
|
30
|
+
actionpack (6.1.3.2)
|
31
|
+
actionview (= 6.1.3.2)
|
32
|
+
activesupport (= 6.1.3.2)
|
32
33
|
rack (~> 2.0, >= 2.0.9)
|
33
34
|
rack-test (>= 0.6.3)
|
34
35
|
rails-dom-testing (~> 2.0)
|
35
36
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
36
|
-
actiontext (6.1.3)
|
37
|
-
actionpack (= 6.1.3)
|
38
|
-
activerecord (= 6.1.3)
|
39
|
-
activestorage (= 6.1.3)
|
40
|
-
activesupport (= 6.1.3)
|
37
|
+
actiontext (6.1.3.2)
|
38
|
+
actionpack (= 6.1.3.2)
|
39
|
+
activerecord (= 6.1.3.2)
|
40
|
+
activestorage (= 6.1.3.2)
|
41
|
+
activesupport (= 6.1.3.2)
|
41
42
|
nokogiri (>= 1.8.5)
|
42
|
-
actionview (6.1.3)
|
43
|
-
activesupport (= 6.1.3)
|
43
|
+
actionview (6.1.3.2)
|
44
|
+
activesupport (= 6.1.3.2)
|
44
45
|
builder (~> 3.1)
|
45
46
|
erubi (~> 1.4)
|
46
47
|
rails-dom-testing (~> 2.0)
|
47
48
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
48
|
-
activejob (6.1.3)
|
49
|
-
activesupport (= 6.1.3)
|
49
|
+
activejob (6.1.3.2)
|
50
|
+
activesupport (= 6.1.3.2)
|
50
51
|
globalid (>= 0.3.6)
|
51
|
-
activemodel (6.1.3)
|
52
|
-
activesupport (= 6.1.3)
|
53
|
-
activerecord (6.1.3)
|
54
|
-
activemodel (= 6.1.3)
|
55
|
-
activesupport (= 6.1.3)
|
56
|
-
activestorage (6.1.3)
|
57
|
-
actionpack (= 6.1.3)
|
58
|
-
activejob (= 6.1.3)
|
59
|
-
activerecord (= 6.1.3)
|
60
|
-
activesupport (= 6.1.3)
|
61
|
-
marcel (~> 0.
|
62
|
-
|
63
|
-
activesupport (6.1.3)
|
52
|
+
activemodel (6.1.3.2)
|
53
|
+
activesupport (= 6.1.3.2)
|
54
|
+
activerecord (6.1.3.2)
|
55
|
+
activemodel (= 6.1.3.2)
|
56
|
+
activesupport (= 6.1.3.2)
|
57
|
+
activestorage (6.1.3.2)
|
58
|
+
actionpack (= 6.1.3.2)
|
59
|
+
activejob (= 6.1.3.2)
|
60
|
+
activerecord (= 6.1.3.2)
|
61
|
+
activesupport (= 6.1.3.2)
|
62
|
+
marcel (~> 1.0.0)
|
63
|
+
mini_mime (~> 1.0.2)
|
64
|
+
activesupport (6.1.3.2)
|
64
65
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
65
66
|
i18n (>= 1.6, < 2)
|
66
67
|
minitest (>= 5.1)
|
@@ -71,91 +72,92 @@ GEM
|
|
71
72
|
coderay (1.1.3)
|
72
73
|
concurrent-ruby (1.1.8)
|
73
74
|
crass (1.0.6)
|
75
|
+
dalli (2.7.11)
|
74
76
|
database_cleaner (2.0.1)
|
75
77
|
database_cleaner-active_record (~> 2.0.0)
|
76
|
-
database_cleaner-active_record (2.0.
|
78
|
+
database_cleaner-active_record (2.0.1)
|
77
79
|
activerecord (>= 5.a)
|
78
80
|
database_cleaner-core (~> 2.0.0)
|
79
81
|
database_cleaner-core (2.0.1)
|
80
82
|
erubi (1.10.0)
|
81
83
|
globalid (0.4.2)
|
82
84
|
activesupport (>= 4.2.0)
|
83
|
-
i18n (1.8.
|
85
|
+
i18n (1.8.10)
|
84
86
|
concurrent-ruby (~> 1.0)
|
85
|
-
loofah (2.9.
|
87
|
+
loofah (2.9.1)
|
86
88
|
crass (~> 1.0.2)
|
87
89
|
nokogiri (>= 1.5.9)
|
88
90
|
mail (2.7.1)
|
89
91
|
mini_mime (>= 0.1.1)
|
90
|
-
marcel (0.
|
91
|
-
mimemagic (~> 0.3.2)
|
92
|
+
marcel (1.0.1)
|
92
93
|
method_source (1.0.0)
|
93
|
-
|
94
|
-
mini_mime (1.0.2)
|
94
|
+
mini_mime (1.0.3)
|
95
95
|
minitest (5.14.4)
|
96
96
|
nio4r (2.5.7)
|
97
|
-
nokogiri (1.11.
|
97
|
+
nokogiri (1.11.6-x86_64-linux)
|
98
98
|
racc (~> 1.4)
|
99
|
+
oj (3.11.5)
|
99
100
|
parallel (1.20.1)
|
100
|
-
parser (3.0.
|
101
|
+
parser (3.0.1.1)
|
101
102
|
ast (~> 2.4.1)
|
102
|
-
pry (0.14.
|
103
|
+
pry (0.14.1)
|
103
104
|
coderay (~> 1.1)
|
104
105
|
method_source (~> 1.0)
|
105
106
|
racc (1.5.2)
|
106
107
|
rack (2.2.3)
|
107
108
|
rack-test (1.1.0)
|
108
109
|
rack (>= 1.0, < 3)
|
109
|
-
rails (6.1.3)
|
110
|
-
actioncable (= 6.1.3)
|
111
|
-
actionmailbox (= 6.1.3)
|
112
|
-
actionmailer (= 6.1.3)
|
113
|
-
actionpack (= 6.1.3)
|
114
|
-
actiontext (= 6.1.3)
|
115
|
-
actionview (= 6.1.3)
|
116
|
-
activejob (= 6.1.3)
|
117
|
-
activemodel (= 6.1.3)
|
118
|
-
activerecord (= 6.1.3)
|
119
|
-
activestorage (= 6.1.3)
|
120
|
-
activesupport (= 6.1.3)
|
110
|
+
rails (6.1.3.2)
|
111
|
+
actioncable (= 6.1.3.2)
|
112
|
+
actionmailbox (= 6.1.3.2)
|
113
|
+
actionmailer (= 6.1.3.2)
|
114
|
+
actionpack (= 6.1.3.2)
|
115
|
+
actiontext (= 6.1.3.2)
|
116
|
+
actionview (= 6.1.3.2)
|
117
|
+
activejob (= 6.1.3.2)
|
118
|
+
activemodel (= 6.1.3.2)
|
119
|
+
activerecord (= 6.1.3.2)
|
120
|
+
activestorage (= 6.1.3.2)
|
121
|
+
activesupport (= 6.1.3.2)
|
121
122
|
bundler (>= 1.15.0)
|
122
|
-
railties (= 6.1.3)
|
123
|
+
railties (= 6.1.3.2)
|
123
124
|
sprockets-rails (>= 2.0.0)
|
124
125
|
rails-dom-testing (2.0.3)
|
125
126
|
activesupport (>= 4.2.0)
|
126
127
|
nokogiri (>= 1.6)
|
127
128
|
rails-html-sanitizer (1.3.0)
|
128
129
|
loofah (~> 2.3)
|
129
|
-
railties (6.1.3)
|
130
|
-
actionpack (= 6.1.3)
|
131
|
-
activesupport (= 6.1.3)
|
130
|
+
railties (6.1.3.2)
|
131
|
+
actionpack (= 6.1.3.2)
|
132
|
+
activesupport (= 6.1.3.2)
|
132
133
|
method_source
|
133
134
|
rake (>= 0.8.7)
|
134
135
|
thor (~> 1.0)
|
135
136
|
rainbow (3.0.0)
|
136
137
|
rake (13.0.3)
|
138
|
+
redis (4.2.5)
|
137
139
|
regexp_parser (2.1.1)
|
138
|
-
rexml (3.2.
|
139
|
-
rubocop (1.
|
140
|
+
rexml (3.2.5)
|
141
|
+
rubocop (1.15.0)
|
140
142
|
parallel (~> 1.10)
|
141
143
|
parser (>= 3.0.0.0)
|
142
144
|
rainbow (>= 2.2.2, < 4.0)
|
143
145
|
regexp_parser (>= 1.8, < 3.0)
|
144
146
|
rexml
|
145
|
-
rubocop-ast (>= 1.
|
147
|
+
rubocop-ast (>= 1.5.0, < 2.0)
|
146
148
|
ruby-progressbar (~> 1.7)
|
147
149
|
unicode-display_width (>= 1.4.0, < 3.0)
|
148
|
-
rubocop-ast (1.
|
149
|
-
parser (>=
|
150
|
-
rubocop-minitest (0.
|
150
|
+
rubocop-ast (1.6.0)
|
151
|
+
parser (>= 3.0.1.1)
|
152
|
+
rubocop-minitest (0.12.1)
|
151
153
|
rubocop (>= 0.90, < 2.0)
|
152
|
-
rubocop-performance (1.
|
153
|
-
rubocop (>=
|
154
|
+
rubocop-performance (1.11.3)
|
155
|
+
rubocop (>= 1.7.0, < 2.0)
|
154
156
|
rubocop-ast (>= 0.4.0)
|
155
|
-
rubocop-rails (2.
|
157
|
+
rubocop-rails (2.10.1)
|
156
158
|
activesupport (>= 4.2.0)
|
157
159
|
rack (>= 1.1)
|
158
|
-
rubocop (>=
|
160
|
+
rubocop (>= 1.7.0, < 2.0)
|
159
161
|
rubocop-rake (0.5.1)
|
160
162
|
rubocop
|
161
163
|
ruby-progressbar (1.11.0)
|
@@ -171,7 +173,7 @@ GEM
|
|
171
173
|
tzinfo (2.0.4)
|
172
174
|
concurrent-ruby (~> 1.0)
|
173
175
|
unicode-display_width (2.0.0)
|
174
|
-
websocket-driver (0.7.
|
176
|
+
websocket-driver (0.7.4)
|
175
177
|
websocket-extensions (>= 0.1.0)
|
176
178
|
websocket-extensions (0.1.5)
|
177
179
|
zeitwerk (2.4.2)
|
@@ -181,11 +183,13 @@ PLATFORMS
|
|
181
183
|
|
182
184
|
DEPENDENCIES
|
183
185
|
ar_cache!
|
186
|
+
dalli
|
184
187
|
database_cleaner
|
185
188
|
minitest
|
186
189
|
pry
|
187
190
|
rails
|
188
191
|
rake
|
192
|
+
redis
|
189
193
|
rubocop
|
190
194
|
rubocop-minitest
|
191
195
|
rubocop-performance
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# ArCache
|
1
|
+
# ArCache (This is outdated, please see [中文文档](README.zh-CN.md))
|
2
2
|
|
3
3
|

|
4
4
|
[](https://badge.fury.io/rb/ar_cache)
|
@@ -16,7 +16,7 @@ then query the database and write the result to the cache.
|
|
16
16
|
- `Read cache`: Automatically intercept ActiveRecord queries, then try to fetch data from cache.
|
17
17
|
- `Write cache`: If the query is cacheable and the cached data is not exists, it will be automatically written to the cache after the query.
|
18
18
|
- `Expire cache`: Automatically expire cache after updated/modified data.
|
19
|
-
- `Iterative cache`: The cache version will be updated after table fields
|
19
|
+
- `Iterative cache`: The cache version will be updated after table fields or `ArCache` switch changed.
|
20
20
|
- `Shared cache`: The cache is not only used with ActiveRecord, you can easily use it in other places.([see examples](examples))
|
21
21
|
|
22
22
|
## Installation
|
@@ -55,11 +55,11 @@ rake db:migrate
|
|
55
55
|
|
56
56
|
Skip cache:
|
57
57
|
|
58
|
-
- `ArCache#
|
58
|
+
- `ArCache#skip_cache`, eg:
|
59
59
|
|
60
60
|
```ruby
|
61
61
|
# All queries in the block will not use the cache.
|
62
|
-
ArCache.
|
62
|
+
ArCache.skip_cache { User.find(1) }
|
63
63
|
```
|
64
64
|
|
65
65
|
- `ActiveRecord::Persistence#reload`, eg:
|
data/README.zh-CN.md
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# ArCache
|
2
|
+
|
3
|
+

|
4
|
+
[](https://badge.fury.io/rb/ar_cache)
|
5
|
+
|
6
|
+
`ArCache` 是一个现代的 `ActiveRecord` 查询缓存库,它受 [`cache-money`](https://github.com/ngmoco/cache-money) 和 [`second_level_cache`](https://github.com/hooopo/second_level_cache) 的启发而创作。
|
7
|
+
当 `ActiveRecord` 实例化查询条件命中唯一索引时,`ArCache` 会拦截此次查询,尝试从缓存中获取结果;如果缓存缺失,
|
8
|
+
将在 `ActiveRecord` 查询完成后自动填充缓存。
|
9
|
+
`ArCache` 会自动维护缓存的正确性。
|
10
|
+
|
11
|
+
## 特点
|
12
|
+
|
13
|
+
- **低影响**:如果项目里数据库操作的相关代码符合 `ActiveRecord` 风格的话,那么你可以直接引入 `ArCache`,无需修改任何代码。([详细](#警告))
|
14
|
+
- **读缓存**:当实例化查询的条件命中唯一索引时,`ArCache` 会尝试从缓存中获取结果返回。
|
15
|
+
- **写缓存**:当读缓存操作没有获取到结果时,`ArCache` 会在 `ActiveRecord` 查询操作结束后,写入缓存。
|
16
|
+
- **删缓存**:在更新或删除数据后,`ArCache` 会自动移除对应的缓存。
|
17
|
+
- **迭代缓存**:当表结构发生改变后,`ArCache` 会更新这个表对应的缓存版本。
|
18
|
+
- **共享缓存**:`ArCache` 里面缓存是完整表字段与数据的哈希结果的 `json` 序列化字符串(仅当使用 `redis/memcached` 作为存储器时),因此缓存的使用是没有局限的。([实例](examples))
|
19
|
+
|
20
|
+
## 安装
|
21
|
+
|
22
|
+
向项目的 `Gemfile` 文件里增加一行内容:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'ar_cache'
|
26
|
+
```
|
27
|
+
|
28
|
+
之后,执行:
|
29
|
+
|
30
|
+
```shell
|
31
|
+
bundle install
|
32
|
+
```
|
33
|
+
|
34
|
+
## 初始化配置文件
|
35
|
+
|
36
|
+
如果是 `rails` 项目,直接执行命令:
|
37
|
+
|
38
|
+
```shell
|
39
|
+
rails generate ar_cache:install
|
40
|
+
```
|
41
|
+
|
42
|
+
不是,则将 [configuration.rb](lib/generators/ar_cache/templates/configuration.rb) 文件手动复制到项目对应的目录。
|
43
|
+
|
44
|
+
## 配置项
|
45
|
+
|
46
|
+
关于配置项的说明,请直接查看 [configuration.rb](lib/generators/ar_cache/templates/configuration.rb) 文件.
|
47
|
+
|
48
|
+
## 用法
|
49
|
+
|
50
|
+
只需要了解如何删除缓存和跳过缓存即可。
|
51
|
+
|
52
|
+
删除缓存:
|
53
|
+
|
54
|
+
- `ArCache::Table#delete`, 例如:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
User.ar_cache_table.delete(id...)
|
58
|
+
User.first.ar_cache_table.delete(id...)
|
59
|
+
```
|
60
|
+
|
61
|
+
跳过缓存:
|
62
|
+
|
63
|
+
- `ArCache#skip_cache`, 例如:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
ArCache.skip_cache do
|
67
|
+
# 块里面的全部查询将跳过缓存
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
- `ActiveRecord::Persistence#reload`, 例如:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
User.find(1).reload
|
75
|
+
```
|
76
|
+
|
77
|
+
- `ActiveRecord::Relation#reload`, 例如:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
# 当 relation 已加载查询后,再调用 reload 方法时,将跳过缓存
|
81
|
+
User.where(id: 1).load.reload
|
82
|
+
```
|
83
|
+
|
84
|
+
- `ActiveRecord::Associations::Association#reload`, 例如:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
# 当关联对象已加载查询后,再调用 reload 方法时,将跳过缓存
|
88
|
+
user.association(:account).load_target.reload
|
89
|
+
```
|
90
|
+
|
91
|
+
## 可读缓存的查询
|
92
|
+
|
93
|
+
必须满足下列全部条件:
|
94
|
+
|
95
|
+
- 使用哈希作为查询条件
|
96
|
+
- 查询条件包含唯一索引
|
97
|
+
- 没有事务存在,或者事务里面没有查询表的更新或删除操作(后续会尝试解除这个限制)
|
98
|
+
- 没有调用过 `select` 方法,或者 `select` 字段都是表字段
|
99
|
+
- 没有调用过 `order/order!` 方法,或者 `order` 字段只有一个,并且该字段是表字段
|
100
|
+
- 没有调用过 `limit/limit!` 方法,或者查询条件只能命中一个结果
|
101
|
+
- 没有调用过 `skip_query_cache!` 方法
|
102
|
+
- 没有调用过 `lock/lock!` 方法
|
103
|
+
- 没有调用过 `distinct/distinct!` 方法
|
104
|
+
- 没有调用过 `group/group!` 方法
|
105
|
+
- 没有调用过 `joins/joins!` 方法
|
106
|
+
- 没有调用过 `left_outer_joins/left_outer_joins!` 方法
|
107
|
+
- 没有调用过 `offset/offset!` 方法
|
108
|
+
- 没有调用过 `eager_load/eager_load!` 方法
|
109
|
+
- 没有调用过 `references/references!` 方法
|
110
|
+
- 没有调用过 `from/from!` 方法
|
111
|
+
- ...
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
User.find(1) # 主键查询是可读缓存的
|
115
|
+
User.where(email: 'foobar@gmail.com') # 唯一索引查询是可读缓存的
|
116
|
+
User.where(id: [1, 2]) # 唯一索引有多个值的情况,依然是可读缓存的
|
117
|
+
User.where(name: 'foobar', status: :active) # 联合字段的唯一索引查询是可读缓存的
|
118
|
+
User.includes(:account).where(id: [1, 2]) # ActiveRecord 的预加载是可读缓存的(仅当为 has_one 关联时)
|
119
|
+
User.first.account # ActiveRecord 的关联对象是可读缓存的(仅当为 has_one 关联时)
|
120
|
+
```
|
121
|
+
|
122
|
+
注意: `has_many` 的关联缓存,目前是不支持的,后续会尝试支持,但希望不大。
|
123
|
+
|
124
|
+
## 缓存迭代
|
125
|
+
|
126
|
+
`ArCache` 的缓存是以表为层级的,当触发缓存迭代后,这个表的全部缓存都会失效,导致一种类似缓存雪崩的情况,请特别注意。
|
127
|
+
下述的这些情况会导致缓存迭代:
|
128
|
+
|
129
|
+
- 表结构发生变化
|
130
|
+
- 激活/禁用 `ArCache`
|
131
|
+
- 使用 `ActiveRecord::Persistence::ClassMethods#upsert_all` 方法
|
132
|
+
|
133
|
+
## 注意事项
|
134
|
+
|
135
|
+
- `ArCache` 的缓存清除操作,是在事务提交或 `sql` 操作结束后开始的,这意味是可能出现脏读的(后续会尝试解决)。
|
136
|
+
- `ArCache` 缓存数据是完整的表行数据,因此当 `sql` 包含 `select` 字段,并且缓存缺失时,`ArCache` 会将其改成 `select *`,但最终实例化的对象依旧符合预期。
|
137
|
+
- 当使用跳过 `ActiveReord` 的回调方法,更新/删除数据时,`ArCache` 可能会多执行一条 `select primary_key` 的 `sql`,因为清除缓存需要 `primary_key` 数据。
|
138
|
+
|
139
|
+
## 警告
|
140
|
+
|
141
|
+
下述的这些情况都是严禁发生的行为,这些行为会导致 `ArCache` 的缓存正确性。
|
142
|
+
PS:`ActiveRecord` 使用者,不应该写出这些代码。
|
143
|
+
|
144
|
+
- 直接使用 `execute` 方法 更新/删除 数据。
|
145
|
+
- 直接使用比 `execute` 更底层方式,更新/删除 数据。
|
146
|
+
- 跳过 `ActiveRecord` 直接 更新/删除 数据。(后续会提供数据库触发器来解除这个限制)
|
147
|
+
|
148
|
+
如果这些行为无法避免的话,请按照上述[删除缓存](#用法)的方法,手动删除受影响的缓存数据,或者干脆直接禁止对应表的 `ArCache` 功能。
|
149
|
+
|
150
|
+
## 其它类似的库
|
151
|
+
|
152
|
+
这里还有一些其它的 `gem`,也提供了 `ActiveRecord` 的查询缓存功能。
|
153
|
+
|
154
|
+
- [identity_cache](https://github.com/Shopify/identity_cache)
|
155
|
+
- [second_level_cache](https://github.com/hooopo/second_level_cache)
|
156
|
+
- [cache-money](https://github.com/ngmoco/cache-money)
|
157
|
+
|
158
|
+
`ArCache` 跟他们存在一些下述的差异:
|
159
|
+
|
160
|
+
- `ArCache` 不依赖 `ActiveRecord` 的 `commit` 回调,所以你可以无所顾虑的直接使用跳过回调的方法。
|
161
|
+
- `ArCache` 的缓存是 `json` 序列化,不是 `Marshal` 序列化,所以缓存的使用是没有局限的。(仅当使用 `redis/memcached` 作为存储器时)
|
162
|
+
- `ArCache` 自动代理了标准的 `ActiveRecord` 实例化查询请求,所以不需要额外学习怎么使用缓存。
|
163
|
+
- `ArCache` 缓存是懒写入的,因此新创建的数据,不会直接写入缓存。
|
164
|
+
- `ArCache` 不会热更新缓存,因此数据被更新后,缓存就没有了。
|
165
|
+
- ...
|