1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
module Geocoder
class Cache
def initialize(store, prefix)
@store = store
@prefix = prefix
end
##
# Read from the Cache.
#
def [](url)
interpret case
when store.respond_to?(:[])
store[key_for(url)]
when store.respond_to?(:get)
store.get key_for(url)
when store.respond_to?(:read)
store.read key_for(url)
end
end
##
# Write to the Cache.
#
def []=(url, value)
case
when store.respond_to?(:[]=)
store[key_for(url)] = value
when store.respond_to?(:set)
store.set key_for(url), value
when store.respond_to?(:write)
store.write key_for(url), value
end
end
##
# Delete cache entry for given URL,
# or pass <tt>:all</tt> to clear all URLs.
#
def expire(url)
if url == :all
if store.respond_to?(:keys)
urls.each{ |u| expire(u) }
else
raise(NoMethodError, "The Geocoder cache store must implement `#keys` for `expire(:all)` to work")
end
else
expire_single_url(url)
end
end
private # ----------------------------------------------------------------
def prefix; @prefix; end
def store; @store; end
##
# Cache key for a given URL.
#
def key_for(url)
[prefix, url].join
end
##
# Array of keys with the currently configured prefix
# that have non-nil values.
#
def keys
store.keys.select{ |k| k.match(/^#{prefix}/) and self[k] }
end
##
# Array of cached URLs.
#
def urls
keys.map{ |k| k[/^#{prefix}(.*)/, 1] }
end
##
# Clean up value before returning. Namely, convert empty string to nil.
# (Some key/value stores return empty string instead of nil.)
#
def interpret(value)
value == "" ? nil : value
end
def expire_single_url(url)
key = key_for(url)
store.respond_to?(:del) ? store.del(key) : store.delete(key)
end
end
end
|