perry 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -1
- data/lib/perry/adapters/abstract_adapter.rb +189 -64
- data/lib/perry/adapters/bertrpc_adapter.rb +3 -2
- data/lib/perry/adapters/restful_http_adapter.rb +36 -11
- data/lib/perry/association.rb +43 -14
- data/lib/perry/base.rb +33 -17
- data/lib/perry/{cacheable → middlewares/cache_records}/entry.rb +7 -7
- data/lib/perry/middlewares/cache_records/scopes.rb +18 -0
- data/lib/perry/{cacheable → middlewares/cache_records}/store.rb +1 -1
- data/lib/perry/middlewares/cache_records.rb +67 -0
- data/lib/perry/middlewares/model_bridge.rb +66 -0
- data/lib/perry/middlewares.rb +8 -0
- data/lib/perry/persistence/response.rb +75 -0
- data/lib/perry/persistence.rb +40 -2
- data/lib/perry/processors/preload_associations.rb +61 -0
- data/lib/perry/processors.rb +5 -0
- data/lib/perry/relation/finder_methods.rb +8 -4
- data/lib/perry/relation/modifiers.rb +37 -0
- data/lib/perry/relation/query_methods.rb +19 -11
- data/lib/perry/relation.rb +9 -4
- data/lib/perry/version.rb +1 -1
- data/lib/perry.rb +5 -0
- metadata +31 -9
- data/lib/perry/association_preload.rb +0 -69
- data/lib/perry/cacheable.rb +0 -80
@@ -1,69 +0,0 @@
|
|
1
|
-
module Perry::AssociationPreload
|
2
|
-
module ClassMethods
|
3
|
-
|
4
|
-
def eager_load_associations(original_results, relation)
|
5
|
-
relation.includes_values.each do |association_id|
|
6
|
-
association = self.defined_associations[association_id.to_sym]
|
7
|
-
force_fresh = relation.fresh_value
|
8
|
-
|
9
|
-
unless association
|
10
|
-
raise(
|
11
|
-
Perry::AssociationNotFound,
|
12
|
-
"no such association (#{association_id})"
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
|
-
unless association.eager_loadable?
|
17
|
-
raise(
|
18
|
-
Perry::AssociationPreloadNotSupported,
|
19
|
-
"delayed execution options (block options) cannot be used for eager loaded associations"
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
options = association.options
|
24
|
-
|
25
|
-
case association.type
|
26
|
-
when :has_many, :has_one
|
27
|
-
fks = original_results.collect { |record| record.send(association.primary_key) }.compact
|
28
|
-
|
29
|
-
pre_records = association.target_klass.where(association.foreign_key => fks).all(:fresh => force_fresh)
|
30
|
-
|
31
|
-
original_results.each do |record|
|
32
|
-
pk = record.send(association.primary_key)
|
33
|
-
relevant_records = pre_records.select { |r| r.send(association.foreign_key) == pk }
|
34
|
-
|
35
|
-
relevant_records = if association.collection?
|
36
|
-
scope = association.scope(record).where(association.foreign_key => pk)
|
37
|
-
scope.records = relevant_records
|
38
|
-
scope
|
39
|
-
else
|
40
|
-
relevant_records.first
|
41
|
-
end
|
42
|
-
|
43
|
-
record.send("#{association.id}=", relevant_records)
|
44
|
-
end
|
45
|
-
|
46
|
-
when :belongs_to
|
47
|
-
fks = original_results.collect { |record| record.send(association.foreign_key) }.compact
|
48
|
-
|
49
|
-
pre_records = association.target_klass.where(association.primary_key => fks).all(:fresh => force_fresh)
|
50
|
-
|
51
|
-
original_results.each do |record|
|
52
|
-
fk = record.send(association.foreign_key)
|
53
|
-
relevant_records = pre_records.select { |r| r.send(association.primary_key) == fk }.first
|
54
|
-
record.send("#{association.id}=", relevant_records)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
module InstanceMethods
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.included(receiver)
|
66
|
-
receiver.extend ClassMethods
|
67
|
-
receiver.send :include, InstanceMethods
|
68
|
-
end
|
69
|
-
end
|
data/lib/perry/cacheable.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'perry/cacheable/store'
|
2
|
-
require 'perry/cacheable/entry'
|
3
|
-
require 'digest/md5'
|
4
|
-
|
5
|
-
module Perry::Cacheable
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
|
9
|
-
# TRP: Default to a 5 minute cache
|
10
|
-
DEFAULT_LONGEVITY = 5*60
|
11
|
-
@@cache_store = nil
|
12
|
-
|
13
|
-
def reset_cache_store(default_longevity=DEFAULT_LONGEVITY)
|
14
|
-
@@cache_store = Perry::Cacheable::Store.new(default_longevity)
|
15
|
-
end
|
16
|
-
|
17
|
-
def cache_store
|
18
|
-
@@cache_store
|
19
|
-
end
|
20
|
-
|
21
|
-
protected
|
22
|
-
|
23
|
-
def fetch_records_with_caching(relation)
|
24
|
-
options = relation.to_hash
|
25
|
-
key = Digest::MD5.hexdigest(self.to_s + options.to_a.sort { |a,b| a.to_s.first <=> b.to_s.first }.inspect)
|
26
|
-
cache_hit = self.cache_store.read(key)
|
27
|
-
get_fresh = options.delete(:fresh)
|
28
|
-
|
29
|
-
if cache_hit && !get_fresh
|
30
|
-
self.read_adapter.log(options, "CACHE #{self.name}")
|
31
|
-
cache_hit.each { |fv| fv.fresh = false.freeze }
|
32
|
-
cache_hit
|
33
|
-
else
|
34
|
-
fresh_value = fetch_records_without_caching(relation)
|
35
|
-
|
36
|
-
# TRP: Only store in cache if record count is below the cache_record_count_threshold (if it is set)
|
37
|
-
if !self.cache_record_count_threshold || fresh_value.size <= self.cache_record_count_threshold
|
38
|
-
self.cache_store.write(key, fresh_value, (self.cache_expires) ? fresh_value[0].send(self.cache_expires) : Time.now + DEFAULT_LONGEVITY) unless fresh_value.empty?
|
39
|
-
fresh_value.each { |fv| fv.fresh = true.freeze }
|
40
|
-
end
|
41
|
-
|
42
|
-
fresh_value
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def enable_caching(options)
|
47
|
-
reset_cache_store unless cache_store
|
48
|
-
self.cacheable = true
|
49
|
-
self.cache_expires = options[:expires]
|
50
|
-
self.cache_record_count_threshold = options[:record_count_threshold]
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
module InstanceMethods
|
56
|
-
|
57
|
-
def fresh?
|
58
|
-
@fresh
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.included(receiver)
|
64
|
-
receiver.class_inheritable_accessor :cache_expires, :cache_record_count_threshold
|
65
|
-
receiver.send :attr_accessor, :fresh
|
66
|
-
|
67
|
-
receiver.extend ClassMethods
|
68
|
-
receiver.send :include, InstanceMethods
|
69
|
-
|
70
|
-
# TRP: Remap calls for RPC through the caching mechanism
|
71
|
-
receiver.class_eval do
|
72
|
-
class << self
|
73
|
-
alias_method :fetch_records_without_caching, :fetch_records
|
74
|
-
alias_method :fetch_records, :fetch_records_with_caching
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|