cached_resource 7.0.0 → 7.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 +4 -4
- data/.github/workflows/ruby.yml +2 -2
- data/FUNDING.json +7 -0
- data/README.md +7 -0
- data/lib/cached_resource/caching.rb +41 -20
- data/lib/cached_resource/version.rb +1 -1
- data/spec/cached_resource/caching_spec.rb +33 -46
- data/spec/spec_helper.rb +1 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0895f45566dd7c4ee2f394be6dda1c7a86aed9ad4e7c6a470d9a59d584c529c1'
|
4
|
+
data.tar.gz: 16106c7680c3cd6708b8171aa5db5f3993f3a77368685876e3e125b03e2d8e85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dbb4bc9fc1019dbf38dce7553b1ad15a964ca3699a461d551b892a26608b53ab0dbe4d8dbcce3878977f4b00debd88affa6494ad52d4fb2fb739a3ca6d239c3
|
7
|
+
data.tar.gz: 689a7edad73b7de5cff68c17d34135422d7166b1ae2745ae3be398cc77399e1ccd2d09a8423a3c7fda00f647216834e4b93c0a82287c39dd5ea5177d3fc7072f
|
data/.github/workflows/ruby.yml
CHANGED
@@ -15,7 +15,7 @@ permissions:
|
|
15
15
|
jobs:
|
16
16
|
test:
|
17
17
|
|
18
|
-
runs-on: ubuntu-
|
18
|
+
runs-on: ubuntu-20.04
|
19
19
|
|
20
20
|
strategy:
|
21
21
|
matrix:
|
@@ -106,4 +106,4 @@ jobs:
|
|
106
106
|
TEST_RAILS_VERSION: ${{ matrix.rails-version }}
|
107
107
|
DEBUG: true
|
108
108
|
- name: Run tests
|
109
|
-
run: bundle exec rake
|
109
|
+
run: bundle exec rake
|
data/FUNDING.json
ADDED
data/README.md
CHANGED
@@ -25,6 +25,13 @@ CachedResource is designed to be framework agnostic, but will hook into Rails fo
|
|
25
25
|
| 💎 3.1 | | | | ✅ | ✅ | ✅ |
|
26
26
|
| 💎 3.2 | | | | ✅ | ✅ | ✅ |
|
27
27
|
|
28
|
+
## Limitations
|
29
|
+
|
30
|
+
The following are limitations for ActiveResource/Rails versions
|
31
|
+
|
32
|
+
| ActiveSupport Version | Limitation |
|
33
|
+
|---------------------- | ----------------------------------------------------------------------- |
|
34
|
+
| 🛤️ 4.X | You cannot chain calls. Ie `Thing.where(fn: 'foo').where(ln: 'bar')`. <br> However, you can still access `original_params` and the `resource_class` and replicate it with <br>`call1 = Thing.where(fn: 'foo')`<br>`call1.resource_class.where(call1.original_params.merge(ln: 'bar'))` |
|
28
35
|
|
29
36
|
## Configuration
|
30
37
|
|
@@ -37,13 +37,14 @@ module CachedResource
|
|
37
37
|
cache_read(key) || find_via_reload(key, *arguments)
|
38
38
|
end
|
39
39
|
|
40
|
-
# Re/send the request to fetch the resource
|
41
|
-
# for the request.
|
40
|
+
# Re/send the request to fetch the resource
|
42
41
|
def find_via_reload(key, *arguments)
|
43
42
|
object = find_without_cache(*arguments)
|
43
|
+
return object unless cached_resource.enabled
|
44
|
+
|
44
45
|
cache_collection_synchronize(object, *arguments) if cached_resource.collection_synchronize
|
45
46
|
return object if !cached_resource.cache_collections && is_any_collection?(*arguments)
|
46
|
-
cache_write(key, object)
|
47
|
+
cache_write(key, object, *arguments)
|
47
48
|
cache_read(key)
|
48
49
|
end
|
49
50
|
|
@@ -52,29 +53,29 @@ module CachedResource
|
|
52
53
|
# otherwise update an existing collection if possible.
|
53
54
|
def cache_collection_synchronize(object, *arguments)
|
54
55
|
if object.is_a? Enumerable
|
55
|
-
update_singles_cache(object)
|
56
|
+
update_singles_cache(object, *arguments)
|
56
57
|
# update the collection only if this is a subset of it
|
57
|
-
update_collection_cache(object) unless is_collection?(*arguments)
|
58
|
+
update_collection_cache(object, *arguments) unless is_collection?(*arguments)
|
58
59
|
else
|
59
|
-
update_collection_cache(object)
|
60
|
+
update_collection_cache(object, *arguments)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
64
|
# Update the cache of singles with an array of updates.
|
64
|
-
def update_singles_cache(updates)
|
65
|
+
def update_singles_cache(updates, *arguments)
|
65
66
|
updates = Array(updates)
|
66
|
-
updates.each { |object| cache_write(cache_key(object.send(primary_key)), object) }
|
67
|
+
updates.each { |object| cache_write(cache_key(object.send(primary_key)), object, *arguments) }
|
67
68
|
end
|
68
69
|
|
69
70
|
# Update the "mother" collection with an array of updates.
|
70
|
-
def update_collection_cache(updates)
|
71
|
+
def update_collection_cache(updates, *arguments)
|
71
72
|
updates = Array(updates)
|
72
73
|
collection = cache_read(cache_key(cached_resource.collection_arguments))
|
73
74
|
|
74
75
|
if collection && !updates.empty?
|
75
76
|
index = collection.inject({}) { |hash, object| hash[object.send(primary_key)] = object; hash }
|
76
77
|
updates.each { |object| index[object.send(primary_key)] = object }
|
77
|
-
cache_write(cache_key(cached_resource.collection_arguments), index.values)
|
78
|
+
cache_write(cache_key(cached_resource.collection_arguments), index.values, *arguments)
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
@@ -101,7 +102,10 @@ module CachedResource
|
|
101
102
|
if cache.is_a? Enumerable
|
102
103
|
restored = cache.map { |record| full_dup(record) }
|
103
104
|
next restored unless respond_to?(:collection_parser)
|
104
|
-
collection_parser.new(restored)
|
105
|
+
collection_parser.new(restored).tap do |parser|
|
106
|
+
parser.resource_class = self
|
107
|
+
parser.original_params = json['original_params']
|
108
|
+
end
|
105
109
|
else
|
106
110
|
full_dup(cache)
|
107
111
|
end
|
@@ -112,8 +116,12 @@ module CachedResource
|
|
112
116
|
end
|
113
117
|
|
114
118
|
# Write an entry to the cache for the given key and value.
|
115
|
-
def cache_write(key, object)
|
116
|
-
|
119
|
+
def cache_write(key, object, *arguments)
|
120
|
+
options = arguments[1] || {}
|
121
|
+
params = options[:params]
|
122
|
+
prefix_options, query_options = split_options(params)
|
123
|
+
|
124
|
+
result = cached_resource.cache.write(key, object_to_json(object, prefix_options, query_options), :race_condition_ttl => cached_resource.race_condition_ttl, :expires_in => cached_resource.generate_ttl)
|
117
125
|
result && cached_resource.logger.info("#{CachedResource::Configuration::LOGGER_PREFIX} WRITE #{key}")
|
118
126
|
result
|
119
127
|
end
|
@@ -150,21 +158,34 @@ module CachedResource
|
|
150
158
|
end
|
151
159
|
|
152
160
|
def json_to_object(json)
|
153
|
-
|
154
|
-
|
155
|
-
|
161
|
+
resource = json['resource']
|
162
|
+
if resource.is_a? Array
|
163
|
+
resource.map do |attrs|
|
164
|
+
self.new(attrs["object"], attrs["persistence"]).tap do |resource|
|
165
|
+
resource.prefix_options = json['prefix_options']
|
166
|
+
end
|
167
|
+
end
|
156
168
|
else
|
157
|
-
self.new(
|
169
|
+
self.new(resource["object"], resource["persistence"]).tap do |resource|
|
170
|
+
resource.prefix_options = json['prefix_options']
|
171
|
+
end
|
158
172
|
end
|
159
173
|
end
|
160
174
|
|
161
|
-
def object_to_json(object)
|
175
|
+
def object_to_json(object, prefix_options, query_options)
|
162
176
|
if object.is_a? Enumerable
|
163
|
-
|
177
|
+
{
|
178
|
+
:resource => object.map { |o| { :object => o, :persistence => o.persisted? } },
|
179
|
+
:prefix_options => prefix_options,
|
180
|
+
:original_params => query_options
|
181
|
+
}.to_json
|
164
182
|
elsif object.nil?
|
165
183
|
nil.to_json
|
166
184
|
else
|
167
|
-
{
|
185
|
+
{
|
186
|
+
:resource => { :object => object, :persistence => object.persisted? },
|
187
|
+
:prefix_options => prefix_options
|
188
|
+
}.to_json
|
168
189
|
end
|
169
190
|
end
|
170
191
|
end
|
@@ -18,6 +18,8 @@ describe CachedResource do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
@thing = {:thing => {:id => 1, :name => "Ada"}}
|
21
|
+
@thing_collection = [{:id => 1, :name => "Ada"}, {:id => 2, :name => "Ada", :major => 'CS'}]
|
22
|
+
@thing_collection2 = [{:id => 2, :name => "Ada", :major => 'CS'}]
|
21
23
|
@other_thing = {:thing => {:id => 1, :name => "Ari"}}
|
22
24
|
@thing2 = {:thing => {:id => 2, :name => "Joe"}}
|
23
25
|
@other_thing2 = {:thing => {:id => 2, :name => "Jeb"}}
|
@@ -215,13 +217,39 @@ describe CachedResource do
|
|
215
217
|
cached.should be_instance_of(ActiveResource::Collection)
|
216
218
|
end
|
217
219
|
|
218
|
-
it "should return
|
220
|
+
it "should return a chainable instance of the collection_parser" do
|
219
221
|
Thing.cached_resource.cache.clear
|
220
222
|
class CustomCollection < ActiveResource::Collection; end
|
221
223
|
Thing.collection_parser = CustomCollection
|
222
|
-
|
223
|
-
|
224
|
+
|
225
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
226
|
+
mock.get "/things.json?name=ada", {}, @thing_collection.to_json
|
227
|
+
mock.get "/things.json?major=CS&name=ada", {}, @thing_collection2.to_json
|
228
|
+
end
|
229
|
+
|
230
|
+
non_cached = Thing.where(name: 'ada')
|
231
|
+
non_cached.original_params.should == { 'name' => 'ada' }
|
232
|
+
non_cached.map(&:id).should == @thing_collection.map { |h| h[:id]}
|
233
|
+
|
234
|
+
cached = read_from_cache('thing/all/{:params=>{:name=>"ada"}}')
|
224
235
|
cached.should be_instance_of(CustomCollection)
|
236
|
+
cached.original_params.should == { 'name' => 'ada' }
|
237
|
+
cached.resource_class.should == Thing
|
238
|
+
cached.map(&:id).should == @thing_collection.map { |h| h[:id]}
|
239
|
+
|
240
|
+
if ActiveResource::VERSION::MAJOR < 5
|
241
|
+
non_cached = cached.resource_class.where(cached.original_params.merge(major: 'CS'))
|
242
|
+
else
|
243
|
+
non_cached = cached.where(major: 'CS')
|
244
|
+
end
|
245
|
+
|
246
|
+
non_cached.original_params.should == { 'name' => 'ada', 'major' => 'CS' }
|
247
|
+
non_cached.resource_class.should == Thing
|
248
|
+
non_cached.map(&:id).should == @thing_collection2.map { |h| h[:id]}
|
249
|
+
cached = read_from_cache('thing/all/{:params=>{"name"=>"ada",:major=>"cs"}}')
|
250
|
+
cached.original_params.should == { 'name' => 'ada', 'major' => 'CS' }
|
251
|
+
cached.resource_class.should == Thing
|
252
|
+
cached.map(&:id).should == @thing_collection2.map { |h| h[:id]}
|
225
253
|
end
|
226
254
|
else
|
227
255
|
it "should return an Array" do
|
@@ -505,14 +533,9 @@ describe CachedResource do
|
|
505
533
|
end
|
506
534
|
end
|
507
535
|
|
508
|
-
it "should cache a response" do
|
536
|
+
it "should not cache a response" do
|
509
537
|
result = Thing.find(1)
|
510
|
-
read_from_cache("thing/1").should
|
511
|
-
end
|
512
|
-
|
513
|
-
it "should cache a response for a string primary key" do
|
514
|
-
result = Thing.find("fded")
|
515
|
-
read_from_cache("thing/fded").should == result
|
538
|
+
read_from_cache("thing/1").should be_nil
|
516
539
|
end
|
517
540
|
|
518
541
|
it "should always remake the request" do
|
@@ -528,42 +551,6 @@ describe CachedResource do
|
|
528
551
|
Thing.find("fded")
|
529
552
|
ActiveResource::HttpMock.requests.length.should == 2
|
530
553
|
end
|
531
|
-
|
532
|
-
it "should rewrite the cache for each request" do
|
533
|
-
Thing.find(1)
|
534
|
-
old_result = read_from_cache("thing/1")
|
535
|
-
|
536
|
-
# change the response
|
537
|
-
ActiveResource::HttpMock.reset!
|
538
|
-
ActiveResource::HttpMock.respond_to do |mock|
|
539
|
-
mock.get "/things/1.json", {}, @other_thing_json
|
540
|
-
end
|
541
|
-
|
542
|
-
Thing.find(1)
|
543
|
-
new_result = read_from_cache("thing/1")
|
544
|
-
# since active resources are equal if and only if they
|
545
|
-
# are the same object or an instance of the same class,
|
546
|
-
# not new?, and have the same id.
|
547
|
-
new_result.name.should_not == old_result.name
|
548
|
-
end
|
549
|
-
|
550
|
-
it "should rewrite the cache for each request for a string primary key" do
|
551
|
-
Thing.find("fded")
|
552
|
-
old_result = read_from_cache("thing/fded")
|
553
|
-
|
554
|
-
# change the response
|
555
|
-
ActiveResource::HttpMock.reset!
|
556
|
-
ActiveResource::HttpMock.respond_to do |mock|
|
557
|
-
mock.get "/things/fded.json", {}, @other_string_thing_json
|
558
|
-
end
|
559
|
-
|
560
|
-
Thing.find("fded")
|
561
|
-
new_result = read_from_cache("thing/fded")
|
562
|
-
# since active resources are equal if and only if they
|
563
|
-
# are the same object or an instance of the same class,
|
564
|
-
# not new?, and have the same id.
|
565
|
-
new_result.name.should_not == old_result.name
|
566
|
-
end
|
567
554
|
end
|
568
555
|
|
569
556
|
describe "when cache_collections is disabled" do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cached_resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Morgan Brown
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeresource
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- ".github/workflows/ruby.yml"
|
90
90
|
- ".gitignore"
|
91
91
|
- ".rspec"
|
92
|
+
- FUNDING.json
|
92
93
|
- Gemfile
|
93
94
|
- LICENSE
|
94
95
|
- README.md
|
@@ -132,4 +133,8 @@ rubygems_version: 3.1.6
|
|
132
133
|
signing_key:
|
133
134
|
specification_version: 4
|
134
135
|
summary: Caching for ActiveResource
|
135
|
-
test_files:
|
136
|
+
test_files:
|
137
|
+
- spec/cached_resource/cached_resource_spec.rb
|
138
|
+
- spec/cached_resource/caching_spec.rb
|
139
|
+
- spec/cached_resource/configuration_spec.rb
|
140
|
+
- spec/spec_helper.rb
|