lib/arid_cache/store.rb in arid_cache-0.1.0 vs lib/arid_cache/store.rb in arid_cache-0.1.1
- old
+ new
@@ -1,58 +1,84 @@
module AridCache
class Store < Hash
- Struct.new('Item', :cache_key, :proc, :klass, :opts)
+ extend ActiveSupport::Memoizable
- def query(key, opts, object, &block)
- return store(object, key, Proc.new, opts) if block_given? # store a proc
+ # AridCache::Store::Blueprint
+ #
+ # Stores options and blocks that are used to generate results for finds
+ # and counts.
+ Blueprint = Struct.new(:key, :klass, :proc, :opts) do
- if has?(object, key)
- AridCache.cache.fetch(find(object, key), opts)
- elsif key =~ /(.*)_count$/
- if has?(object, $1)
- AridCache.cache.fetch_count(find(object, $1))
- elsif object.respond_to?(key)
- AridCache.cache.fetch_count(find_or_create(object, key))
- elsif object.respond_to?($1)
- AridCache.cache.fetch_count(find_or_create(object, $1))
+ def initialize(key, klass, proc=nil, opts={})
+ self.key = key
+ self.klass = klass
+ self.proc = proc
+ self.opts = opts
+ end
+
+ def klass=(value) # store the base class of *value*
+ self['klass'] = value.is_a?(Class) ? value.name : value.class.name
+ end
+
+ def klass
+ self['klass'].constantize unless self['klass'].nil?
+ end
+
+ def opts=(value)
+ self['opts'] = value.symbolize_keys! unless !value.respond_to?(:symbolize_keys)
+ end
+
+ def opts
+ self['opts'] || {}
+ end
+
+ def proc(object=nil)
+ if self['proc'].nil? && !object.nil?
+ self['proc'] = key
else
- raise ArgumentError.new("#{object} doesn't respond to #{key} or #{$1}! Cannot dynamically create query to get the count.")
- end
- else
- if object.respond_to?(key)
- AridCache.cache.fetch(find_or_create(object, key), opts)
- else
- raise ArgumentError.new("#{object} doesn't respond to #{key}! Cannot dynamically create query.")
+ self['proc']
end
- end
+ end
end
- # Store a proc
- def store(object, key, proc, opts)
- cache_key = object.arid_cache_key(key)
- self[cache_key] = Struct::Item.new(cache_key, proc, (object.is_a?(Class) ? object : object.class), opts.symbolize_keys!)
+ def has?(object, key)
+ self.include?(object_store_key(object, key))
end
+ # Empty the proc store
+ def delete!
+ delete_if { true }
+ end
+
+ def self.instance
+ @@singleton_instance ||= self.new
+ end
+
def find(object, key)
- self[object.arid_cache_key(key)]
+ self[object_store_key(object, key)]
end
- # Find or dynamically create a proc
+ def add(object, key, proc, opts)
+ store_key = object_store_key(object, key)
+ self[store_key] = AridCache::Store::Blueprint.new(key, object, proc, opts)
+ end
+
def find_or_create(object, key)
- cache_key = object.arid_cache_key(key)
- if include?(cache_key)
- self[cache_key]
+ store_key = object_store_key(object, key)
+ if self.include?(store_key)
+ self[store_key]
else
- self[cache_key] = Struct::Item.new(cache_key, Proc.new { object.send(key) }, (object.is_a?(Class) ? object : object.class))
+ self[store_key] = AridCache::Store::Blueprint.new(key, object)
end
end
- def has?(object, key)
- self.include?(object.arid_cache_key(key))
+ protected
+
+ def initialize
end
- # Empty the proc store
- def delete!
- delete_if { true }
- end
+ def object_store_key(object, key)
+ (object.is_a?(Class) ? object.name.downcase : object.class.name.pluralize.downcase) + '-' + key.to_s
+ end
+ memoize :object_store_key
end
end
\ No newline at end of file