ar_cache 1.5.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![Test Status](https://github.com/OuYangJinTing/ar_cache/workflows/CI/badge.svg)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/ar_cache.svg)](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
|
+
![Test Status](https://github.com/OuYangJinTing/ar_cache/workflows/CI/badge.svg)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/ar_cache.svg)](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
|
+
- ...
|