diff --git a/lib/geocoder.rb b/lib/geocoder.rb index 22f141050179e738de4b47aed026a864aaaa4091..594f3df8cb35b4e567e92e82f290dfd61d2bcc32 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -1,5 +1,6 @@ require "geocoder/configuration" require "geocoder/calculations" +require "geocoder/cache" require "geocoder/railtie" require "geocoder/request" diff --git a/lib/geocoder/cache.rb b/lib/geocoder/cache.rb new file mode 100644 index 0000000000000000000000000000000000000000..82d47d09113323559c61b5c9ca1a78e9d0862d5e --- /dev/null +++ b/lib/geocoder/cache.rb @@ -0,0 +1,81 @@ +module Geocoder + + ## + # The working Cache object, or +nil+ if none configured. + # + def self.cache + if @cache.nil? and store = Geocoder::Configuration.cache + @cache = Cache.new(store, Geocoder::Configuration.cache_prefix) + end + @cache + end + + class Cache + + def initialize(store, prefix) + @store = store + @prefix = prefix + end + + ## + # Read from the Cache. + # + def [](url) + interpret store[key_for(url)] + end + + ## + # Write to the Cache. + # + def []=(url, value) + store[key_for(url)] = value + end + + ## + # Expire cache entry for given URL, + # or pass <tt>:all</tt> to expire everything. + # + def expire(url) + if url == :all + urls.each{ |u| expire(u) } + else + self[url] = nil + end + end + + + private # ---------------------------------------------------------------- + + attr_reader :prefix, :store + + ## + # 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 interpret(store[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 + end +end diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 65ff21281ef655b5186f5810e4b4a3cc5ff133a0..90c17a3098f2c8dff9430797df6fc86a3bf0f679 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -60,7 +60,7 @@ module Geocoder rescue TimeoutError warn "Geocoding API not responding fast enough " + "(see Geocoder::Configuration.timeout to set limit)." - end + end end ## @@ -82,13 +82,12 @@ module Geocoder # Fetches a raw search result (JSON string). # def fetch_raw_data(query, reverse = false) - url = query_url(query, reverse) - key = cache_key(url) timeout(Geocoder::Configuration.timeout) do - unless cache and (response = cache[key]) and response != "" + url = query_url(query, reverse) + unless cache and response = cache[url] response = Net::HTTP.get_response(URI.parse(url)).body if cache - cache[key] = response + cache[url] = response end end response @@ -96,24 +95,10 @@ module Geocoder end ## - # Cache key for a given URL. - # - def cache_key(url) - [cache_prefix, url].join - end - - ## - # The configured prefix for cache keys. - # - def cache_prefix - Geocoder::Configuration.cache_prefix || "geocoder:" - end - - ## - # The configured cache store. + # The working Cache object. # def cache - Geocoder::Configuration.cache + Geocoder.cache end ##