lib/lookup_by/cache.rb in lookup_by-0.1.2 vs lib/lookup_by/cache.rb in lookup_by-0.1.3
- old
+ new
@@ -1,150 +1,149 @@
module LookupBy
class Cache
- attr_reader :klass, :primary_key
- attr_reader :cache, :stats
- attr_reader :field, :order, :type, :limit, :find, :write, :normalize
+ attr_reader :cache, :field, :stats
+ attr_accessor :testing
- attr_accessor :enabled
-
def initialize(klass, options = {})
@klass = klass
@primary_key = klass.primary_key
@field = options[:field].to_sym
@cache = {}
- @order = options[:order] || field
+ @order = options[:order] || @field
@read = options[:find]
@write = options[:find_or_create]
@normalize = options[:normalize]
+ @testing = false
@enabled = true
@stats = { db: Hash.new(0), cache: Hash.new(0) }
- raise ArgumentError, %Q(unknown attribute "#{field}" for <#{klass}>) unless klass.column_names.include?(field.to_s)
+ raise ArgumentError, %Q(unknown attribute "#{@field}" for <#{klass}>) unless klass.column_names.include?(@field.to_s)
case options[:cache]
when true
- @type = :all
- @read ||= false
+ @type = :all
+ @read ||= false
when ::Fixnum
raise ArgumentError, "`#{@klass}.lookup_by :#{@field}` options[:find] must be true when caching N" if @read == false
@type = :lru
@limit = options[:cache]
@cache = Rails.configuration.allow_concurrency ? Caching::SafeLRU.new(@limit) : Caching::LRU.new(@limit)
@read = true
@write ||= false
- @enabled = false if Rails.env.test? && write?
+ @testing = true if Rails.env.test? && @write
else
@read = true
end
end
def reload
- return unless cache_all?
+ return unless @type == :all
clear
- ::ActiveRecord::Base.connection.send :log, "", "#{klass.name} Load Cache All" do
- klass.order(order).each do |i|
- cache[i.id] = i
+ ::ActiveRecord::Base.connection.send :log, "", "#{@klass.name} Load Cache All" do
+ @klass.order(@order).each do |i|
+ @cache[i.id] = i
end
end
end
def clear
- cache.clear if cache?
+ @cache.clear
end
def create!(*args, &block)
- created = klass.create!(*args, &block)
- cache[created.id] = created if cache?
+ created = @klass.create!(*args, &block)
+ @cache[created.id] = created if cache?
created
end
def fetch(value)
increment :cache, :get
- value = clean(value) if normalize?
+ value = normalize(value) if @normalize && !value.is_a?(Fixnum)
found = cache_read(value) if cache?
- found ||= db_read(value) if read_through?
+ found ||= db_read(value) if @read
+ found ||= db_read(value) if not @enabled
- cache[found.id] = found if found && cache?
+ @cache[found.id] = found if found && cache?
- found ||= db_write(value) if write?
+ found ||= db_write(value) if @write
found
end
def has_cache?
- !!type
+ @type && @enabled
end
def read_through?
@read
end
- private
+ def enabled?
+ @enabled
+ end
- def clean(value)
- return value if value.is_a? Fixnum
+ def disabled?
+ !@enabled
+ end
- klass.new(field => value).send(field)
+ def enable!
+ @enabled = true
+ reload
end
+ def disable!
+ @enabled = false
+ clear
+ end
+
+ private
+
+ def normalize(value)
+ @klass.new(@field => value).send(@field)
+ end
+
def cache_read(value)
if value.is_a? Fixnum
- found = cache[value]
+ found = @cache[value]
else
- found = cache.values.detect { |o| o.send(field) == value }
+ found = @cache.values.detect { |o| o.send(@field) == value }
end
increment :cache, found ? :hit : :miss
found
end
def db_read(value)
increment :db, :get
- found = klass.where(column_for(value) => value).first
+ found = @klass.where(column_for(value) => value).first
increment :db, found ? :hit : :miss
found
end
# TODO: Handle race condition on create! failure
def db_write(value)
column = column_for(value)
- found = klass.create!(column => value) if column != primary_key
+ found = @klass.create!(column => value) if column != @primary_key
found
end
def column_for(value)
- value.is_a?(Fixnum) ? primary_key : field
+ value.is_a?(Fixnum) ? @primary_key : @field
end
- def enabled?
- enabled
- end
-
- def cache_all?
- type == :all
- end
-
def cache?
- !!type && enabled?
- end
-
- def write?
- !!write
- end
-
- def normalize?
- !!normalize
+ @type && @enabled && !@testing
end
def increment(type, stat)
@stats[type][stat] += 1
end