counter-cache 0.1.0 → 0.2.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/README.md +14 -0
- data/gemfiles/activerecord_3.gemfile.lock +4 -1
- data/gemfiles/activerecord_4.0.gemfile.lock +4 -1
- data/gemfiles/activerecord_4.1.gemfile.lock +4 -1
- data/lib/counter/cache/counters/buffer_counter/enqueuer.rb +8 -6
- data/lib/counter/cache/counters/buffer_counter/saver.rb +1 -0
- data/lib/counter/cache/options_parser.rb +4 -0
- data/lib/counter/cache/version.rb +1 -1
- data/spec/lib/counter/cache/buffer_counter/enqueuer_spec.rb +83 -29
- data/spec/lib/counter/cache/buffer_counter/saver_spec.rb +20 -5
- data/spec/lib/counter/cache/options_parser_spec.rb +7 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cac236244f5fa2812dc3ba95405240ff016fce4
|
4
|
+
data.tar.gz: e2281ca37f31cc531cb2bba1aa1f9ec3438ca5d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38f9a282a897f6790147ea80dd9198db5bf27fb39aeec1339916480297a02182d1e11066304ef674339103070f0d6bc874f0d3ef0f3f1d19bcff59389e339941
|
7
|
+
data.tar.gz: afc080f77508a700108aa7ea37687a5c509633efd2048c693b60a3fa2894f52e5b6b2ebd358e0ebd7578d6006b5ac7ec81474ad13d45c724824600ce3290c422
|
data/README.md
CHANGED
@@ -98,6 +98,19 @@ Counter caches are configured on the models from the perspective of the child mo
|
|
98
98
|
|
99
99
|
#### Basic Counter with recalculation:
|
100
100
|
|
101
|
+
```ruby
|
102
|
+
class Post
|
103
|
+
include Counter::Cache
|
104
|
+
|
105
|
+
counter_cache_on column: :posts_count, # users.posts_count
|
106
|
+
relation: :user,
|
107
|
+
relation_class_name: "User",
|
108
|
+
method: :calculate_posts_count # This is a method on the user.
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
#### To allow a timestamp to be updated:
|
113
|
+
|
101
114
|
```ruby
|
102
115
|
class Post
|
103
116
|
include Counter::Cache
|
@@ -106,6 +119,7 @@ class Post
|
|
106
119
|
relation: :user,
|
107
120
|
relation_class_name: "User",
|
108
121
|
method: :calculate_posts_count, # This is a method on the user.
|
122
|
+
touch_column: :posts_updated_at
|
109
123
|
end
|
110
124
|
```
|
111
125
|
|
@@ -11,14 +11,16 @@ module Counter
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def create_and_enqueue(delay, cached)
|
14
|
+
parameters = { relation_class_name: relation_class,
|
15
|
+
relation_id: relation_id,
|
16
|
+
column: options.column,
|
17
|
+
method: options.method,
|
18
|
+
cache: cached,
|
19
|
+
counter: counter_class_name }
|
20
|
+
parameters[:touch_column] = options.touch_column unless options.touch_column.nil?
|
14
21
|
options.worker_adapter.enqueue(delay,
|
15
22
|
source_object_class_name,
|
16
|
-
|
17
|
-
relation_id: relation_id,
|
18
|
-
column: options.column,
|
19
|
-
method: options.method,
|
20
|
-
cache: cached,
|
21
|
-
counter: counter_class_name })
|
23
|
+
parameters)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -2,52 +2,106 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Counter::Cache::Counters::BufferCounter::Enqueuer do
|
4
4
|
let(:worker_adapter) { double }
|
5
|
-
let(:options) { double(worker_adapter: worker_adapter,
|
6
|
-
wait: 10,
|
7
|
-
column: "boo",
|
8
|
-
method: "calculate_boo",
|
9
|
-
cached?: true,
|
10
|
-
recalculation?: false,
|
11
|
-
recalculation_delay: 20) }
|
12
5
|
|
13
6
|
let(:source_object_class_name) { "BooUser" }
|
14
7
|
let(:relation_id) { 1 }
|
15
8
|
let(:relation_type) { "Boo" }
|
16
9
|
|
17
|
-
let(:enqueuer) { Counter::Cache::Counters::BufferCounter::Enqueuer.new(options, source_object_class_name, relation_id, relation_type, "SuperCounter") }
|
18
|
-
|
19
10
|
describe '#enqueue' do
|
20
|
-
|
21
|
-
expect(worker_adapter).to receive(:enqueue).with(10,
|
22
|
-
"BooUser",
|
23
|
-
{ relation_class_name: "Boo",
|
24
|
-
relation_id: 1,
|
25
|
-
column: "boo",
|
26
|
-
method: "calculate_boo",
|
27
|
-
cache: true,
|
28
|
-
counter: "SuperCounter" })
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'when recalculation is true' do
|
11
|
+
context "without touch column" do
|
32
12
|
before do
|
33
|
-
|
34
|
-
|
13
|
+
@options = double(worker_adapter: worker_adapter,
|
14
|
+
wait: 10,
|
15
|
+
column: "boo",
|
16
|
+
method: "calculate_boo",
|
17
|
+
cached?: true,
|
18
|
+
recalculation?: false,
|
19
|
+
recalculation_delay: 20)
|
20
|
+
|
21
|
+
@enqueuer = Counter::Cache::Counters::BufferCounter::Enqueuer.new(@options, source_object_class_name, relation_id, relation_type, "SuperCounter")
|
35
22
|
|
36
|
-
|
37
|
-
expect(worker_adapter).to receive(:enqueue).with(20,
|
23
|
+
expect(worker_adapter).to receive(:enqueue).with(10,
|
38
24
|
"BooUser",
|
39
25
|
{ relation_class_name: "Boo",
|
40
26
|
relation_id: 1,
|
41
27
|
column: "boo",
|
42
28
|
method: "calculate_boo",
|
43
|
-
cache:
|
29
|
+
cache: true,
|
44
30
|
counter: "SuperCounter" })
|
45
|
-
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'when recalculation is true' do
|
34
|
+
before do
|
35
|
+
expect(@options).to receive(:recalculation?).and_return(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "enqueues two jobs" do
|
39
|
+
expect(@options).to receive(:touch_column).twice
|
40
|
+
expect(worker_adapter).to receive(:enqueue).with(20,
|
41
|
+
"BooUser",
|
42
|
+
{ relation_class_name: "Boo",
|
43
|
+
relation_id: 1,
|
44
|
+
column: "boo",
|
45
|
+
method: "calculate_boo",
|
46
|
+
cache: false,
|
47
|
+
counter: "SuperCounter" })
|
48
|
+
@enqueuer.enqueue!(double)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'enqueues one job' do
|
53
|
+
expect(@options).to receive(:touch_column)
|
54
|
+
@enqueuer.enqueue!(double)
|
46
55
|
end
|
47
56
|
end
|
48
57
|
|
49
|
-
|
50
|
-
|
58
|
+
context "with touch column" do
|
59
|
+
before(:each) do
|
60
|
+
@options = double(worker_adapter: worker_adapter,
|
61
|
+
wait: 10,
|
62
|
+
column: "boo",
|
63
|
+
touch_column: "boo_updated_at",
|
64
|
+
method: "calculate_boo",
|
65
|
+
cached?: true,
|
66
|
+
recalculation?: false,
|
67
|
+
recalculation_delay: 20)
|
68
|
+
@enqueuer = Counter::Cache::Counters::BufferCounter::Enqueuer.new(@options, source_object_class_name, relation_id, relation_type, "SuperCounter")
|
69
|
+
|
70
|
+
expect(worker_adapter).to receive(:enqueue).with(10,
|
71
|
+
"BooUser",
|
72
|
+
{ relation_class_name: "Boo",
|
73
|
+
relation_id: 1,
|
74
|
+
column: "boo",
|
75
|
+
touch_column: "boo_updated_at",
|
76
|
+
method: "calculate_boo",
|
77
|
+
cache: true,
|
78
|
+
counter: "SuperCounter" })
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'when recalculation is true' do
|
82
|
+
before do
|
83
|
+
expect(@options).to receive(:recalculation?).and_return(true)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "enqueues two jobs" do
|
87
|
+
expect(@options).to receive(:touch_column).exactly(4).times
|
88
|
+
expect(worker_adapter).to receive(:enqueue).with(20,
|
89
|
+
"BooUser",
|
90
|
+
{ relation_class_name: "Boo",
|
91
|
+
relation_id: 1,
|
92
|
+
column: "boo",
|
93
|
+
touch_column: "boo_updated_at",
|
94
|
+
method: "calculate_boo",
|
95
|
+
cache: false,
|
96
|
+
counter: "SuperCounter" })
|
97
|
+
@enqueuer.enqueue!(double)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'enqueues one job' do
|
102
|
+
expect(@options).to receive(:touch_column)
|
103
|
+
@enqueuer.enqueue!(double)
|
104
|
+
end
|
51
105
|
end
|
52
106
|
end
|
53
107
|
end
|
@@ -4,7 +4,7 @@ RSpec.describe Counter::Cache::Counters::BufferCounter::Saver do
|
|
4
4
|
class Boo
|
5
5
|
end
|
6
6
|
|
7
|
-
let(:relation_object) { double(boo_count: 2) }
|
7
|
+
let(:relation_object) { double(boo_count: 2, boo_updated_at: DateTime.now) }
|
8
8
|
let(:options) { double(relation_class_name: "Boo", relation_id: 1, column: "boo_count", method: nil, source_object_class_name: Boo) }
|
9
9
|
let(:saver) { Counter::Cache::Counters::BufferCounter::Saver.new(options) }
|
10
10
|
|
@@ -21,6 +21,7 @@ RSpec.describe Counter::Cache::Counters::BufferCounter::Saver do
|
|
21
21
|
|
22
22
|
before do
|
23
23
|
allow(options).to receive(:cached?).and_return(true)
|
24
|
+
allow(options).to receive(:touch_column).and_return(nil)
|
24
25
|
expect(relation_object).to receive(:boo_count=).with(4)
|
25
26
|
expect(relation_object).to receive(:save!)
|
26
27
|
expect(counting_store).to receive(:del)
|
@@ -41,15 +42,29 @@ RSpec.describe Counter::Cache::Counters::BufferCounter::Saver do
|
|
41
42
|
expect(counting_store).to receive(:del)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
context "with touch column" do
|
46
|
+
it 'saves the value' do
|
47
|
+
allow(options).to receive(:touch_column).and_return(:boo_updated_at)
|
48
|
+
expect(relation_object).to receive(:boo_count=).with(4)
|
49
|
+
expect(relation_object).to receive(:boo_updated_at=).with(DateTime.now)
|
50
|
+
expect(relation_object).to receive(:save!)
|
51
|
+
saver.save!
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "without touch column" do
|
56
|
+
it 'saves the value' do
|
57
|
+
allow(options).to receive(:touch_column).and_return(nil)
|
58
|
+
expect(relation_object).to receive(:boo_count=).with(4)
|
59
|
+
expect(relation_object).to receive(:save!)
|
60
|
+
saver.save!
|
61
|
+
end
|
48
62
|
end
|
49
63
|
end
|
50
64
|
|
51
65
|
describe 'when cached? is false' do
|
52
66
|
before do
|
67
|
+
allow(options).to receive(:touch_column).and_return(nil)
|
53
68
|
allow(options).to receive(:cached?).and_return(false)
|
54
69
|
end
|
55
70
|
|
@@ -34,6 +34,13 @@ RSpec.describe Counter::Cache::OptionsParser do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
describe "#touch_column" do
|
38
|
+
let(:options) { { touch_column: "touch_column_name" } }
|
39
|
+
it "returns option if set" do
|
40
|
+
expect(parser.touch_column).to eq("touch_column_name")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
37
44
|
describe "#method" do
|
38
45
|
let(:options) { { method: "method" } }
|
39
46
|
it "returns option if set" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: counter-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Henry & Matt Camuto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -207,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
207
|
version: '0'
|
208
208
|
requirements: []
|
209
209
|
rubyforge_project:
|
210
|
-
rubygems_version: 2.2.
|
210
|
+
rubygems_version: 2.2.3
|
211
211
|
signing_key:
|
212
212
|
specification_version: 4
|
213
213
|
summary: Counting is hard.
|