record_cache 0.9.10 → 0.9.12
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.
- data/VERSION +1 -1
- data/lib/record_cache.rb +22 -2
- data/lib/record_cache/index.rb +35 -29
- data/record_cache.gemspec +18 -20
- data/test/test_helper.rb +2 -1
- metadata +69 -28
- data/.gitignore +0 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.12
|
data/lib/record_cache.rb
CHANGED
@@ -68,10 +68,22 @@ module RecordCache
|
|
68
68
|
opts = args.last
|
69
69
|
if opts.is_a?(Hash) and opts.keys == [:conditions]
|
70
70
|
# Try to match the SQL.
|
71
|
-
if opts[:conditions]
|
71
|
+
if opts[:conditions].kind_of?(Hash)
|
72
|
+
field = nil
|
73
|
+
value = nil
|
74
|
+
if opts[:conditions].keys.size == 1
|
75
|
+
opts[:conditions].each {|f,v| field, value = f,v}
|
76
|
+
end
|
77
|
+
elsif opts[:conditions] =~ /^(?:"?#{table_name}"?\.)?"?(\w+)"? = (?:(\d+)|'(\w+)')$/i
|
78
|
+
field, value = $1, ($3 || $2)
|
79
|
+
elsif opts[:conditions] =~ /^(?:"?#{table_name}"?\.)?"?(\w+)"? IN \(([\d,]*)\)$/i
|
72
80
|
field, value = $1, $2
|
81
|
+
value = value.split(',')
|
82
|
+
end
|
83
|
+
|
84
|
+
if field and value
|
73
85
|
index = cached_index("by_#{field}")
|
74
|
-
return index.find_by_field([value], self, args.first) if index
|
86
|
+
return index.find_by_field([value].flatten, self, args.first) if index
|
75
87
|
end
|
76
88
|
end
|
77
89
|
elsif not args.last.is_a?(Hash)
|
@@ -264,3 +276,11 @@ module RecordCache
|
|
264
276
|
end
|
265
277
|
|
266
278
|
ActiveRecord::Base.send(:extend, RecordCache::ActiveRecordExtension)
|
279
|
+
|
280
|
+
unless defined?(PGconn) and PGconn.respond_to?(:quote_ident)
|
281
|
+
class PGconn
|
282
|
+
def self.quote_ident(name)
|
283
|
+
%("#{name}")
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
data/lib/record_cache/index.rb
CHANGED
@@ -3,16 +3,16 @@ module RecordCache
|
|
3
3
|
include Deferrable
|
4
4
|
|
5
5
|
attr_reader :model_class, :index_field, :fields, :order_by, :limit, :expiry, :name, :prefix
|
6
|
-
|
6
|
+
|
7
7
|
NULL = 'NULL'
|
8
|
-
|
8
|
+
|
9
9
|
def initialize(opts)
|
10
10
|
raise ':by => index_field required for cache' if opts[:by].nil?
|
11
11
|
raise 'explicit name or prefix required with scope' if opts[:scope] and opts[:name].nil? and opts[:prefix].nil?
|
12
12
|
|
13
|
-
@auto_name = opts[:name].nil?
|
13
|
+
@auto_name = opts[:name].nil?
|
14
14
|
@write_ahead = opts[:write_ahead]
|
15
|
-
@cache = opts[:cache] || CACHE
|
15
|
+
@cache = opts[:cache].kind_of?(Symbol) ? Memcache.pool[opts[:cache]] : (opts[:cache] || CACHE)
|
16
16
|
@expiry = opts[:expiry]
|
17
17
|
@model_class = opts[:class]
|
18
18
|
@set_class = opts[:set_class] || "#{@model_class}Set"
|
@@ -41,7 +41,7 @@ module RecordCache
|
|
41
41
|
def full_record?
|
42
42
|
fields.empty?
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def includes_id?
|
46
46
|
full_record? or fields.include?('id')
|
47
47
|
end
|
@@ -53,11 +53,11 @@ module RecordCache
|
|
53
53
|
def namespace
|
54
54
|
"#{model_class.name}_#{model_class.version}_#{RecordCache.version}:#{name}" << ( full_record? ? '' : ":#{fields.join(',')}" )
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def fields_hash
|
58
58
|
if @fields_hash.nil?
|
59
59
|
if full_record?
|
60
|
-
@fields_hash ||= model_class.column_names.hash
|
60
|
+
@fields_hash ||= model_class.column_names.sort.hash
|
61
61
|
else
|
62
62
|
@fields_hash ||= fields.collect {|field| field.to_s}.hash
|
63
63
|
end
|
@@ -74,9 +74,9 @@ module RecordCache
|
|
74
74
|
return [] if expects_array
|
75
75
|
raise ActiveRecord::RecordNotFound, "Couldn't find #{model_class} without an ID"
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
records_by_id = get_records(ids)
|
79
|
-
|
79
|
+
|
80
80
|
models = ids.collect do |id|
|
81
81
|
records = records_by_id[id]
|
82
82
|
model = records.instantiate_first(model_class, full_record?) if records
|
@@ -91,14 +91,14 @@ module RecordCache
|
|
91
91
|
raise ActiveRecord::RecordNotFound, "Couldn't find #{model_class} with ID #{id}" unless model
|
92
92
|
model
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
if models.size == 1 and not expects_array
|
96
96
|
models.first
|
97
|
-
else
|
97
|
+
else
|
98
98
|
models
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
def find_by_field(keys, model_class, type)
|
103
103
|
keys = [keys] if not keys.kind_of?(Array)
|
104
104
|
keys = stringify(keys)
|
@@ -131,7 +131,7 @@ module RecordCache
|
|
131
131
|
raw_records
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
def field_lookup(keys, model_class, field, flag = nil)
|
136
136
|
keys = [*keys]
|
137
137
|
keys = stringify(keys)
|
@@ -158,8 +158,10 @@ module RecordCache
|
|
158
158
|
field_by_index
|
159
159
|
end
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
def invalidate(*keys)
|
163
|
+
return if model_class.record_cache_config[:disable_write]
|
164
|
+
|
163
165
|
keys = stringify(keys)
|
164
166
|
cache.in_namespace(namespace) do
|
165
167
|
keys.each do |key|
|
@@ -178,7 +180,7 @@ module RecordCache
|
|
178
180
|
def invalidate_from_conditions(conditions)
|
179
181
|
invalidate_from_conditions_lambda(conditions).call
|
180
182
|
end
|
181
|
-
|
183
|
+
|
182
184
|
def invalidate_model(model)
|
183
185
|
attribute = model.send(index_field)
|
184
186
|
attribute_was = model.attr_was(index_field)
|
@@ -202,7 +204,7 @@ module RecordCache
|
|
202
204
|
end
|
203
205
|
end
|
204
206
|
end
|
205
|
-
|
207
|
+
|
206
208
|
def scope_query
|
207
209
|
@scope_query[:type] ||= model_class.to_s if sub_class?
|
208
210
|
@scope_query
|
@@ -220,7 +222,7 @@ module RecordCache
|
|
220
222
|
def self.enable_db
|
221
223
|
@@disable_db = false
|
222
224
|
end
|
223
|
-
|
225
|
+
|
224
226
|
def find_method_name(type)
|
225
227
|
if name =~ /(^|_)by_/
|
226
228
|
if type == :first
|
@@ -239,7 +241,7 @@ module RecordCache
|
|
239
241
|
end
|
240
242
|
end
|
241
243
|
end
|
242
|
-
|
244
|
+
|
243
245
|
def cached_set(id)
|
244
246
|
# Used for debugging. Gives you the RecordCache::Set that is currently in the cache.
|
245
247
|
id = stringify([id]).first
|
@@ -253,7 +255,7 @@ module RecordCache
|
|
253
255
|
MAX_FETCH = 1000
|
254
256
|
def get_records(keys)
|
255
257
|
cache.in_namespace(namespace) do
|
256
|
-
opts = {
|
258
|
+
opts = {
|
257
259
|
:expiry => expiry,
|
258
260
|
:disable_write => model_class.record_cache_config[:disable_write],
|
259
261
|
:validation => lambda {|key, record_set| record_set and record_set.fields_hash == fields_hash},
|
@@ -298,9 +300,11 @@ module RecordCache
|
|
298
300
|
end
|
299
301
|
|
300
302
|
def remove_from_cache(model)
|
303
|
+
return if model_class.record_cache_config[:disable_write]
|
304
|
+
|
301
305
|
record = model.attributes
|
302
|
-
key = model.attr_was(index_field)
|
303
|
-
|
306
|
+
key = model.attr_was(index_field) || NULL
|
307
|
+
|
304
308
|
now_and_later do
|
305
309
|
cache.in_namespace(namespace) do
|
306
310
|
cache.with_lock(key) do
|
@@ -314,10 +318,12 @@ module RecordCache
|
|
314
318
|
end
|
315
319
|
|
316
320
|
def add_to_cache(model)
|
321
|
+
return if model_class.record_cache_config[:disable_write]
|
322
|
+
|
317
323
|
record = model_to_record(model)
|
318
324
|
return unless record
|
319
|
-
key = record[index_field]
|
320
|
-
|
325
|
+
key = record[index_field] || NULL
|
326
|
+
|
321
327
|
now_and_later do
|
322
328
|
cache.in_namespace(namespace) do
|
323
329
|
cache.with_lock(key) do
|
@@ -345,11 +351,11 @@ module RecordCache
|
|
345
351
|
end
|
346
352
|
@select_fields
|
347
353
|
end
|
348
|
-
|
354
|
+
|
349
355
|
def base_class?
|
350
356
|
@base_class ||= single_table_inheritance? and model_class == model_class.base_class
|
351
357
|
end
|
352
|
-
|
358
|
+
|
353
359
|
def sub_class?
|
354
360
|
@sub_class ||= single_table_inheritance? and model_class != model_class.base_class
|
355
361
|
end
|
@@ -361,20 +367,20 @@ module RecordCache
|
|
361
367
|
def quote_index_value(value)
|
362
368
|
model_class.quote_value(value, index_column)
|
363
369
|
end
|
364
|
-
|
370
|
+
|
365
371
|
def index_column
|
366
372
|
@index_column ||= model_class.columns_hash[index_field]
|
367
373
|
end
|
368
|
-
|
374
|
+
|
369
375
|
def table_name
|
370
376
|
model_class.table_name
|
371
377
|
end
|
372
|
-
|
378
|
+
|
373
379
|
def stringify(keys)
|
374
380
|
keys.compact! if disallow_null?
|
375
381
|
keys.collect {|key| key.nil? ? NULL : key.to_s}.uniq
|
376
382
|
end
|
377
|
-
|
383
|
+
|
378
384
|
def db
|
379
385
|
RecordCache.db(model_class)
|
380
386
|
end
|
data/record_cache.gemspec
CHANGED
@@ -1,50 +1,48 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{record_cache}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.12"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Justin Balthrop"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-03-21}
|
13
13
|
s.description = %q{Active Record caching and indexing in memcache}
|
14
14
|
s.email = %q{code@justinbalthrop.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
|
-
"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
"test/test_helper.rb"
|
20
|
+
"LICENSE",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/record_cache.rb",
|
25
|
+
"lib/record_cache/index.rb",
|
26
|
+
"lib/record_cache/scope.rb",
|
27
|
+
"lib/record_cache/set.rb",
|
28
|
+
"record_cache.gemspec",
|
29
|
+
"test/record_cache_test.rb",
|
30
|
+
"test/test_helper.rb"
|
32
31
|
]
|
33
32
|
s.homepage = %q{http://github.com/ninjudd/record_cache}
|
34
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
35
33
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version = %q{1.3.
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
37
35
|
s.summary = %q{Active Record caching and indexing in memcache. An alternative to cache_fu}
|
38
36
|
s.test_files = [
|
39
37
|
"test/record_cache_test.rb",
|
40
|
-
|
38
|
+
"test/test_helper.rb"
|
41
39
|
]
|
42
40
|
|
43
41
|
if s.respond_to? :specification_version then
|
44
42
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
43
|
s.specification_version = 3
|
46
44
|
|
47
|
-
if Gem::Version.new(Gem::
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
48
46
|
s.add_runtime_dependency(%q<after_commit>, [">= 1.0.0"])
|
49
47
|
s.add_runtime_dependency(%q<deferrable>, [">= 0.1.0"])
|
50
48
|
s.add_runtime_dependency(%q<memcache>, [">= 1.0.0"])
|
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'test/unit'
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'shoulda'
|
4
4
|
require 'mocha'
|
5
|
+
require 'pp'
|
5
6
|
|
6
7
|
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
|
7
8
|
['cache_version', 'model_set', 'memcache', 'deferrable'].each do |dir|
|
@@ -21,7 +22,7 @@ CACHE = Memcache.new(:servers => 'localhost')
|
|
21
22
|
ActiveRecord::Base.establish_connection(
|
22
23
|
:adapter => "postgresql",
|
23
24
|
:host => "localhost",
|
24
|
-
:username =>
|
25
|
+
:username => `whoami`.chomp,
|
25
26
|
:password => "",
|
26
27
|
:database => "test"
|
27
28
|
)
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: record_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 35
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 12
|
10
|
+
version: 0.9.12
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Justin Balthrop
|
@@ -9,59 +15,89 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-03-21 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: after_commit
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 0
|
23
34
|
version: 1.0.0
|
24
|
-
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: deferrable
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
43
|
- - ">="
|
32
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 27
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 1
|
49
|
+
- 0
|
33
50
|
version: 0.1.0
|
34
|
-
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
35
53
|
- !ruby/object:Gem::Dependency
|
36
54
|
name: memcache
|
37
|
-
|
38
|
-
|
39
|
-
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
40
58
|
requirements:
|
41
59
|
- - ">="
|
42
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 23
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 0
|
65
|
+
- 0
|
43
66
|
version: 1.0.0
|
44
|
-
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
45
69
|
- !ruby/object:Gem::Dependency
|
46
70
|
name: cache_version
|
47
|
-
|
48
|
-
|
49
|
-
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
50
74
|
requirements:
|
51
75
|
- - ">="
|
52
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 51
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
- 9
|
81
|
+
- 4
|
53
82
|
version: 0.9.4
|
54
|
-
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id004
|
55
85
|
- !ruby/object:Gem::Dependency
|
56
86
|
name: activerecord
|
57
|
-
|
58
|
-
|
59
|
-
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
60
90
|
requirements:
|
61
91
|
- - ">="
|
62
92
|
- !ruby/object:Gem::Version
|
93
|
+
hash: 15
|
94
|
+
segments:
|
95
|
+
- 2
|
96
|
+
- 0
|
97
|
+
- 0
|
63
98
|
version: 2.0.0
|
64
|
-
|
99
|
+
type: :runtime
|
100
|
+
version_requirements: *id005
|
65
101
|
description: Active Record caching and indexing in memcache
|
66
102
|
email: code@justinbalthrop.com
|
67
103
|
executables: []
|
@@ -72,7 +108,6 @@ extra_rdoc_files:
|
|
72
108
|
- LICENSE
|
73
109
|
- README.rdoc
|
74
110
|
files:
|
75
|
-
- .gitignore
|
76
111
|
- LICENSE
|
77
112
|
- README.rdoc
|
78
113
|
- Rakefile
|
@@ -89,26 +124,32 @@ homepage: http://github.com/ninjudd/record_cache
|
|
89
124
|
licenses: []
|
90
125
|
|
91
126
|
post_install_message:
|
92
|
-
rdoc_options:
|
93
|
-
|
127
|
+
rdoc_options: []
|
128
|
+
|
94
129
|
require_paths:
|
95
130
|
- lib
|
96
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
97
133
|
requirements:
|
98
134
|
- - ">="
|
99
135
|
- !ruby/object:Gem::Version
|
136
|
+
hash: 3
|
137
|
+
segments:
|
138
|
+
- 0
|
100
139
|
version: "0"
|
101
|
-
version:
|
102
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
103
142
|
requirements:
|
104
143
|
- - ">="
|
105
144
|
- !ruby/object:Gem::Version
|
145
|
+
hash: 3
|
146
|
+
segments:
|
147
|
+
- 0
|
106
148
|
version: "0"
|
107
|
-
version:
|
108
149
|
requirements: []
|
109
150
|
|
110
151
|
rubyforge_project:
|
111
|
-
rubygems_version: 1.3.
|
152
|
+
rubygems_version: 1.3.7
|
112
153
|
signing_key:
|
113
154
|
specification_version: 3
|
114
155
|
summary: Active Record caching and indexing in memcache. An alternative to cache_fu
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
pkg
|