Permalink
Browse files

Modify identity map interface

  • Loading branch information...
1 parent def9e9b commit 0ff6d9725267e94e60c9b7ebdca129704429a635 @sferik committed Jul 18, 2012
Showing with 42 additions and 42 deletions.
  1. +17 −23 etc/sqlite_identity_map.rb
  2. +13 −5 lib/twitter/base.rb
  3. +1 −1 lib/twitter/default.rb
  4. +4 −4 lib/twitter/identity.rb
  5. +6 −8 lib/twitter/identity_map.rb
  6. +1 −1 spec/twitter/base_spec.rb
View
@@ -8,40 +8,34 @@ def initialize
@database = Database.new(":memory:")
end
- # @param klass
- # @param key
+ # @param id
# @return [Object]
- def fetch(klass, key)
- table = table_from_class(klass)
- create_table(table)
- statement = @database.prepare("SELECT object FROM #{table} WHERE key = :key")
- row = statement.execute!(:key => key).first
+ def fetch(id)
+ create_table
+ @select ||= @database.prepare("SELECT object FROM identity_map WHERE id = :id")
+ row = @select.execute!(:id => id).first
Marshal.load(row.first) unless row.nil?
end
- # @param key
+ # @param id
# @param object
# @return [Object]
- def store(key, object)
- table = table_from_class(object.class)
- create_table(table)
- statement = @database.prepare("INSERT INTO #{table}(key, object) VALUES (:key, :object)")
- statement.execute(:key => key, :object => Blob.new(Marshal.dump(object)))
+ def store(id, object)
+ create_table
+ @insert ||= @database.prepare("INSERT INTO identity_map(id, object) VALUES (:id, :object)")
+ @insert.execute(:id => id, :object => Blob.new(Marshal.dump(object)))
object
+ rescue SQLite3::ConstraintException
+ @delete ||= @database.prepare("DELETE FROM identity_map WHERE id = :id")
+ @delete.execute(:id => id)
+ retry
end
private
- # @params klass [Class]
- # @return [String]
- def table_from_class(klass)
- klass.to_s.downcase.gsub("::", "__")
- end
-
- # @param table [Class]
- def create_table(table)
- @database.execute("CREATE TABLE IF NOT EXISTS #{table}(key VARCHAR NOT NULl, object BLOB)")
- @database.execute("CREATE UNIQUE INDEX IF NOT EXISTS #{table}_unique_key ON #{table}(key)")
+ def create_table
+ @database.execute("CREATE TABLE IF NOT EXISTS identity_map(id VARCHAR NOT NULl, object BLOB)")
+ @database.execute("CREATE UNIQUE INDEX IF NOT EXISTS index_identity_map_on_id ON identity_map(id)")
end
end
View
@@ -19,13 +19,21 @@ def self.attr_reader(*attrs)
end
end
+ # return [Twitter::IdentityMap]
+ def self.identity_map
+ return unless Twitter.identity_map
+ @identity_map = Twitter.identity_map.new if @identity_map_class != Twitter.identity_map
+ @identity_map_class = Twitter.identity_map
+ @identity_map
+ end
+
# Retrieves an object from the identity map.
#
# @param attrs [Hash]
# @return [Twitter::Base]
def self.fetch(attrs)
- return unless Twitter.identity_map
- if object = Twitter.identity_map.fetch(self, Marshal.dump(attrs))
+ return unless identity_map
+ if object = identity_map.fetch(Marshal.dump(attrs))
return object
end
return yield if block_given?
@@ -37,8 +45,8 @@ def self.fetch(attrs)
# @param attrs [Hash]
# @return [Twitter::Base]
def self.store(object)
- return object unless Twitter.identity_map
- Twitter.identity_map.store(Marshal.dump(object.attrs), object)
+ return object unless identity_map
+ identity_map.store(Marshal.dump(object.attrs), object)
end
# Returns a new object based on the response hash
@@ -55,7 +63,7 @@ def self.from_response(response={})
# @param attrs [Hash]
# @return [Twitter::Base]
def self.fetch_or_new(attrs={})
- return self.new(attrs) unless Twitter.identity_map
+ return self.new(attrs) unless identity_map
self.fetch(attrs) do
object = self.new(attrs)
View
@@ -22,7 +22,7 @@ module Default
:ssl => {:verify => false},
:timeout => 10,
} unless defined? CONNECTION_OPTIONS
- IDENTITY_MAP = Twitter::IdentityMap.new unless defined? IDENTITY_MAP
+ IDENTITY_MAP = Twitter::IdentityMap unless defined? IDENTITY_MAP
MIDDLEWARE = Faraday::Builder.new(
&Proc.new do |builder|
builder.use Twitter::Request::MultipartWithFile # Convert file uploads to Faraday::UploadIO objects
View
@@ -4,10 +4,10 @@ module Twitter
class Identity < Base
def self.fetch(attrs)
- return unless Twitter.identity_map
+ return unless identity_map
id = attrs[:id]
- if id && object = Twitter.identity_map.fetch(self, id)
+ if id && object = identity_map.fetch(id)
return object.update(attrs)
end
@@ -20,8 +20,8 @@ def self.fetch(attrs)
# @param attrs [Hash]
# @return [Twitter::Identity]
def self.store(object)
- return object unless Twitter.identity_map
- Twitter.identity_map.store(object.id, object)
+ return object unless identity_map
+ identity_map.store(object.id, object)
end
# Initializes a new object
@@ -4,19 +4,17 @@ module Twitter
# See: http://www.martinfowler.com/eaaCatalog/identityMap.html
class IdentityMap < Hash
- # @param klass
- # @param key
+ # @param id
# @return [Object]
- def fetch(klass, key)
- self[klass] && self[klass][key]
+ def fetch(id)
+ self[id]
end
- # @param key
+ # @param id
# @param object
# @return [Object]
- def store(key, object)
- self[object.class] ||= {}
- self[object.class][key] = object
+ def store(id, object)
+ self[id] = object
end
end
@@ -71,7 +71,7 @@
Twitter.identity_map = false
end
after(:all) do
- Twitter.identity_map = Twitter::IdentityMap.new
+ Twitter.identity_map = Twitter::IdentityMap
end
describe '.fetch' do

0 comments on commit 0ff6d97

Please sign in to comment.