Skip to content

Commit

Permalink
Removing moneta and going with simplest thing for now. Adding more th…
Browse files Browse the repository at this point in the history
…orough tests for loading from database for single id.
  • Loading branch information
jnunemaker committed Jan 11, 2010
1 parent 3974a40 commit bebd72f
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 49 deletions.
2 changes: 0 additions & 2 deletions lib/mongo_mapper.rb
Expand Up @@ -8,13 +8,11 @@
gem 'activesupport', '>= 2.3'
gem 'mongo', '0.18.2'
gem 'jnunemaker-validatable', '1.8.1'
gem 'moneta', '0.6.0'
end

require 'active_support'
require 'mongo'
require 'validatable'
require 'moneta'

module MongoMapper
# generic MM error
Expand Down
30 changes: 11 additions & 19 deletions lib/mongo_mapper/plugins/identity_map.rb
@@ -1,25 +1,23 @@
require 'moneta/memory'

module MongoMapper
module Plugins
module IdentityMap
module ClassMethods
def identity_map
Thread.current[:mongo_mapper_identity_map]
Thread.current[:mongo_mapper_identity_map] ||= {}
end

def identity_map=(v)
Thread.current[:mongo_mapper_identity_map] = v
end

def identity_map_key(id)
"#{self}:#{id}"
end

def find_one(options={})
criteria, options = to_finder_options(options)
key = identity_map_key(criteria[:_id])

if document = identity_map[key]
document
else
Expand All @@ -30,38 +28,32 @@ def find_one(options={})
def load(attrs)
id = attrs[:_id] || attrs[:id] || attrs['_id'] || attrs['id']
key = identity_map_key(id)

if document = identity_map[key]
document
else

unless document = identity_map[key]
document = super
identity_map[document.identity_map_key] = document
end

document
end
end

module InstanceMethods
def self.included(model)
model.identity_map ||= Moneta::Memory.new
end

def identity_map_key
@identity_map_key ||= self.class.identity_map_key(_id)
end

def identity_map
self.class.identity_map
end

def save
if result = super
identity_map.store(identity_map_key, self)
identity_map[identity_map_key] = self
end
result
end

def delete
identity_map.delete(identity_map_key)
super
Expand Down
81 changes: 53 additions & 28 deletions test/functional/test_identity_map.rb
Expand Up @@ -13,61 +13,86 @@ def assert_not_in_map(resource)

context "Document" do
setup do
@person_class = Doc('Person') do
key :name, String
end
@person_class = Doc('Person') { key :name, String }
@person_class.identity_map = {}

@post_class = Doc('Post') do
key :title, String
end
@post_class = Doc('Post') { key :title, String }
@post_class.identity_map = {}
end

should "have an identity map method" do
map = @person_class.identity_map
map.should be_instance_of(Moneta::Memory)
should "default identity map to hash" do
map = Doc().identity_map
map.should == {}
end

should "share identity map with other classes" do
map = @post_class.identity_map
map.object_id.should == @person_class.identity_map.object_id
end
should "have identity map key that is always unique" do

should "have identity map key that is always unique per document and class" do
person = @person_class.new
person.identity_map_key.should == "Person:#{person.id}"

post = @post_class.new
post.identity_map_key.should == "Post:#{post.id}"

person.identity_map_key.should_not == post.identity_map_key
end

should "add key to map when saved" do
person = @person_class.new
assert_not_in_map(person)
person.save.should be_true

mapped_person = person.identity_map[person.identity_map_key]
person.object_id.should == mapped_person.object_id
end

should "remove key from map when deleted" do
person = @person_class.create
person = @person_class.create(:name => 'Fred')

assert_in_map(person)
person.destroy
assert_not_in_map(person)
end

should "load object from identity map if exists" do
person = @person_class.create
assert_in_map(person)

Mongo::Collection.any_instance.expects(:find).never
Mongo::Collection.any_instance.expects(:find_one).never

found_person = @person_class.find(person.id)
found_person.object_id.should == person.object_id
context "find with one id" do
context "for object not in map" do
setup do
@person = @person_class.create(:name => 'Fred')
@person_class.identity_map.clear
end

should "query the database" do
Mongo::Collection.any_instance.expects(:find_one).once
@person_class.find(@person.id)
end

should "add object to map" do
assert_not_in_map(@person)
found_person = @person_class.find(@person.id)
assert_in_map(found_person)
end
end

context "for object in map" do
setup do
@person = @person_class.create(:name => 'Fred')
end

should "not query database" do
Mongo::Collection.any_instance.expects(:find).never
Mongo::Collection.any_instance.expects(:find_one).never
@person_class.find(@person.id)
end

should "return exact object" do
assert_in_map(@person)
found_person = @person_class.find(@person.id)
found_person.object_id.should == @person.object_id
end
end
end
end
end

0 comments on commit bebd72f

Please sign in to comment.