rcache 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +4 -0
- data/lib/rcache.rb +1 -0
- data/lib/rcache/calculations.rb +25 -0
- data/lib/rcache/query_cache.rb +25 -10
- data/lib/rcache/relation.rb +5 -4
- data/lib/rcache/version.rb +2 -1
- data/test/rcache_test.rb +13 -3
- metadata +25 -48
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 93ff360d64d82e9276cf2e81e752b8f9eb1b56da
|
4
|
+
data.tar.gz: 4282167769d0177286b5f63b1f0cc655a1593210
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bad8a84b940d6ebc72ffdc51336f3d05a628734b5ab7306760cb9f43fd3b09914d47ee0af34d1643bbfa421f8b76dc24719adfeaddc28b7cfbcb1aa4974dfdda
|
7
|
+
data.tar.gz: 7b5ce5f3dc2405c965be7308bf6c8f1c4936c89c6381d3d8098fe3b8260ea79c66e570dee1194e2b6a8bfa5f30d270b565444ce388ba774b5f0e258270d0d0a5
|
data/README.md
CHANGED
@@ -35,6 +35,10 @@ Cache find result for 60 seconds:
|
|
35
35
|
|
36
36
|
Client.rcache.find(2)
|
37
37
|
|
38
|
+
Cache count results:
|
39
|
+
|
40
|
+
Client.rcache.count
|
41
|
+
|
38
42
|
Cache where results with includes for 10 seconds and not show cached queries in log:
|
39
43
|
|
40
44
|
Event.limit(2).includes(:thumbnails, :type => :variable).rcache(:expires_in => 10.seconds, :log_cached_queries => false)
|
data/lib/rcache.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Calculations
|
3
|
+
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
|
4
|
+
# Postgresql doesn't like ORDER BY when there are no GROUP BY
|
5
|
+
relation = reorder(nil)
|
6
|
+
|
7
|
+
if operation == "count" && (relation.limit_value || relation.offset_value)
|
8
|
+
# Shortcut when limit is zero.
|
9
|
+
return 0 if relation.limit_value == 0
|
10
|
+
|
11
|
+
query_builder = build_count_subquery(relation, column_name, distinct)
|
12
|
+
else
|
13
|
+
column = aggregate_column(column_name)
|
14
|
+
|
15
|
+
select_value = operation_over_aggregate_column(column, operation, distinct)
|
16
|
+
|
17
|
+
relation.select_values = [select_value]
|
18
|
+
|
19
|
+
query_builder = relation.arel
|
20
|
+
end
|
21
|
+
query_builder.rcache_value = relation.rcache_value
|
22
|
+
type_cast_calculated_value(@klass.connection.select_value(query_builder), column_for(column_name), operation)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/rcache/query_cache.rb
CHANGED
@@ -5,6 +5,7 @@ module ActiveRecord
|
|
5
5
|
if (arel.rcache_value rescue false) && !locked?(arel) && (arel.rcache_value[:expires_in] || Rcache.expires_in).to_i > 0
|
6
6
|
sql = to_sql(arel, binds)
|
7
7
|
redis_cache_sql(arel.rcache_value, sql, binds) { super(sql, name, binds) }
|
8
|
+
.collect { |row| row.dup }
|
8
9
|
elsif @query_cache_enabled && !locked?(arel)
|
9
10
|
sql = to_sql(arel, binds)
|
10
11
|
cache_sql(sql, binds) { super(sql, name, binds) }
|
@@ -13,6 +14,16 @@ module ActiveRecord
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
17
|
+
def select_value(arel, name = nil)
|
18
|
+
binds = []
|
19
|
+
if (arel.rcache_value rescue false) && !locked?(arel) && (arel.rcache_value[:expires_in] || Rcache.expires_in).to_i > 0
|
20
|
+
sql = to_sql(arel, binds)
|
21
|
+
redis_cache_sql(arel.rcache_value, sql, binds) { super(sql, name) }
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
16
27
|
private
|
17
28
|
|
18
29
|
def redis_cache_sql(rcache_value, sql, binds)
|
@@ -20,24 +31,28 @@ module ActiveRecord
|
|
20
31
|
instance_variable_set("@#{attr}", rcache_value.has_key?(attr) ? rcache_value[attr] : Rcache.send(attr))
|
21
32
|
end
|
22
33
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
# return from memory
|
35
|
+
if @query_cache_enabled && @query_cache[sql].key?(binds)
|
36
|
+
ActiveSupport::Notifications.instrument("sql.active_record", :sql => sql, :binds => binds, :name => "CACHE", :connection_id => object_id) if @log_cached_queries
|
37
|
+
@query_cache[sql][binds]
|
38
|
+
# write to memory from redis and return
|
39
|
+
else
|
40
|
+
res = @redis.get(redis_cache_key(sql, binds, @key_prefix))
|
41
|
+
if res
|
42
|
+
begin
|
43
|
+
res = JSON.parse(res)
|
44
|
+
rescue JSON::ParserError
|
45
|
+
end
|
30
46
|
ActiveSupport::Notifications.instrument("sql.active_record", :sql => sql, :binds => binds, :name => "REDIS", :connection_id => object_id) if @log_cached_queries
|
31
47
|
@query_cache[sql][binds] = res
|
32
|
-
# write to memory and redis from db and return
|
33
48
|
else
|
49
|
+
# write to memory and redis from db and return
|
34
50
|
res = yield
|
35
51
|
@query_cache[sql][binds] = res
|
36
52
|
@redis.setex(redis_cache_key(sql, binds, @key_prefix), @expires_in, res.to_json)
|
37
53
|
res
|
38
54
|
end
|
39
|
-
|
40
|
-
result.collect { |row| row.dup }
|
55
|
+
end
|
41
56
|
end
|
42
57
|
|
43
58
|
def redis_cache_key(sql, binds, key_prefix)
|
data/lib/rcache/relation.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
class Relation
|
3
|
+
SINGLE_VALUE_METHODS.push(:rcache)
|
3
4
|
attr_accessor :rcache_value
|
4
5
|
|
5
6
|
def exec_queries
|
6
7
|
return @records if loaded?
|
7
|
-
|
8
|
+
|
8
9
|
default_scoped = with_default_scope
|
9
|
-
|
10
|
+
|
10
11
|
arel.rcache_value = rcache_value
|
11
12
|
|
12
13
|
if default_scoped.equal?(self)
|
@@ -17,14 +18,14 @@ module ActiveRecord
|
|
17
18
|
eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
|
18
19
|
end
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
preload = @preload_values
|
22
23
|
preload += @includes_values unless eager_loading?
|
23
24
|
preload.each do |associations|
|
24
25
|
# this line distincts only
|
25
26
|
ActiveRecord::Associations::Preloader.new(@records, associations, :rcache_value => rcache_value).run
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
# @readonly_value is true only if set explicitly. @implicit_readonly is true if there
|
29
30
|
# are JOINS and no explicit SELECT.
|
30
31
|
readonly = @readonly_value.nil? ? @implicit_readonly : @readonly_value
|
data/lib/rcache/version.rb
CHANGED
data/test/rcache_test.rb
CHANGED
@@ -12,7 +12,11 @@ class RcacheTest < Test::Unit::TestCase
|
|
12
12
|
assert Client.includes(:events => :quotes).first.events.map(&:quotes).flatten.any?
|
13
13
|
ActiveRecord::Base.connection.execute('delete from quotes')
|
14
14
|
assert Client.includes(:events => :quotes).first.events.map(&:quotes).flatten.empty?
|
15
|
-
|
15
|
+
|
16
|
+
assert Client.first.events.count > 0
|
17
|
+
ActiveRecord::Base.connection.execute('delete from events')
|
18
|
+
assert Client.first.events.count == 0
|
19
|
+
|
16
20
|
assert Client.first.present?
|
17
21
|
ActiveRecord::Base.connection.execute('delete from clients')
|
18
22
|
assert Client.first.nil?
|
@@ -26,7 +30,13 @@ class RcacheTest < Test::Unit::TestCase
|
|
26
30
|
assert Client.rcache.includes(:events => :quotes).first.events.map(&:quotes).flatten.any?
|
27
31
|
teardown_redis
|
28
32
|
assert Client.rcache.includes(:events => :quotes).first.events.map(&:quotes).flatten.empty?
|
29
|
-
|
33
|
+
|
34
|
+
assert Client.first.events.rcache.count > 0
|
35
|
+
ActiveRecord::Base.connection.execute('delete from events')
|
36
|
+
assert Client.first.events.rcache.count > 0
|
37
|
+
teardown_redis
|
38
|
+
assert Client.first.events.rcache.count == 0
|
39
|
+
|
30
40
|
assert Client.rcache.first.present?
|
31
41
|
ActiveRecord::Base.connection.execute('delete from clients')
|
32
42
|
assert Client.rcache.first.present?
|
@@ -35,7 +45,7 @@ class RcacheTest < Test::Unit::TestCase
|
|
35
45
|
end
|
36
46
|
end
|
37
47
|
|
38
|
-
teardown do
|
48
|
+
teardown do
|
39
49
|
teardown_db
|
40
50
|
teardown_redis
|
41
51
|
end
|
metadata
CHANGED
@@ -1,142 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rcache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.7
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- novikov
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2016-03-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: json
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '3.2'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '3.2'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: redis
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- - ~>
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '1.3'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '1.3'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: sqlite3
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - ">="
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rake
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - ">="
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - ">="
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: test-unit
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - ">="
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: shoulda-context
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- -
|
115
|
+
- - ">="
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: '0'
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- -
|
122
|
+
- - ">="
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0'
|
142
125
|
description: ActiveRecord redis query cache
|
@@ -146,7 +129,7 @@ executables: []
|
|
146
129
|
extensions: []
|
147
130
|
extra_rdoc_files: []
|
148
131
|
files:
|
149
|
-
- .gitignore
|
132
|
+
- ".gitignore"
|
150
133
|
- Gemfile
|
151
134
|
- LICENSE.txt
|
152
135
|
- README.md
|
@@ -155,6 +138,7 @@ files:
|
|
155
138
|
- lib/rcache.rb
|
156
139
|
- lib/rcache/arel.rb
|
157
140
|
- lib/rcache/association.rb
|
141
|
+
- lib/rcache/calculations.rb
|
158
142
|
- lib/rcache/preloader.rb
|
159
143
|
- lib/rcache/query_cache.rb
|
160
144
|
- lib/rcache/query_methods.rb
|
@@ -170,33 +154,26 @@ files:
|
|
170
154
|
homepage: ''
|
171
155
|
licenses:
|
172
156
|
- MIT
|
157
|
+
metadata: {}
|
173
158
|
post_install_message:
|
174
159
|
rdoc_options: []
|
175
160
|
require_paths:
|
176
161
|
- lib
|
177
162
|
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
-
none: false
|
179
163
|
requirements:
|
180
|
-
- -
|
164
|
+
- - ">="
|
181
165
|
- !ruby/object:Gem::Version
|
182
166
|
version: '0'
|
183
|
-
segments:
|
184
|
-
- 0
|
185
|
-
hash: -2852935033633211742
|
186
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
-
none: false
|
188
168
|
requirements:
|
189
|
-
- -
|
169
|
+
- - ">="
|
190
170
|
- !ruby/object:Gem::Version
|
191
171
|
version: '0'
|
192
|
-
segments:
|
193
|
-
- 0
|
194
|
-
hash: -2852935033633211742
|
195
172
|
requirements: []
|
196
173
|
rubyforge_project:
|
197
|
-
rubygems_version:
|
174
|
+
rubygems_version: 2.2.2
|
198
175
|
signing_key:
|
199
|
-
specification_version:
|
176
|
+
specification_version: 4
|
200
177
|
summary: ActiveRecord redis query cache
|
201
178
|
test_files:
|
202
179
|
- test/models/client.rb
|