mongo_mapper-unstable 2010.1.19 → 2010.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/mongo_mapper/document.rb +2 -1
- data/lib/mongo_mapper/plugins/identity_map.rb +25 -6
- data/test/functional/test_identity_map.rb +101 -34
- data/test/unit/test_finder_options.rb +4 -0
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2010.01.
|
1
|
+
2010.01.20
|
@@ -22,7 +22,6 @@ module MongoMapper
|
|
22
22
|
plugin Plugins::Serialization
|
23
23
|
plugin Plugins::Validations
|
24
24
|
plugin Plugins::Callbacks # for now callbacks needs to be after validations
|
25
|
-
plugin Plugins::IdentityMap
|
26
25
|
|
27
26
|
extend Plugins::Validations::DocumentMacros
|
28
27
|
end
|
@@ -277,6 +276,7 @@ module MongoMapper
|
|
277
276
|
end
|
278
277
|
end
|
279
278
|
|
279
|
+
# All query methods that load documents pass through find_one or find_many
|
280
280
|
def find_one(options={})
|
281
281
|
criteria, options = to_finder_options(options)
|
282
282
|
if doc = collection.find_one(criteria, options)
|
@@ -284,6 +284,7 @@ module MongoMapper
|
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
287
|
+
# All query methods that load documents pass through find_one or find_many
|
287
288
|
def find_many(options)
|
288
289
|
criteria, options = to_finder_options(options)
|
289
290
|
collection.find(criteria, options).to_a.map do |doc|
|
@@ -23,15 +23,27 @@ module MongoMapper
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def find_one(options={})
|
26
|
-
criteria, finder_options
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
criteria, finder_options = to_finder_options(options)
|
27
|
+
document_in_map = identity_map[identity_map_key(criteria[:_id])]
|
28
|
+
find_by_single_id = criteria.keys == [:_id]
|
29
|
+
find_by_single_id_with_sci = criteria.keys.to_set == [:_id, :_type].to_set
|
30
|
+
|
31
|
+
if find_by_single_id && document_in_map
|
32
|
+
document_in_map
|
33
|
+
elsif find_by_single_id_with_sci && document_in_map
|
34
|
+
document_in_map
|
30
35
|
else
|
31
|
-
|
36
|
+
super.tap do |document|
|
37
|
+
remove_documents_from_map(document) unless finder_options[:fields].nil?
|
38
|
+
end
|
32
39
|
end
|
40
|
+
end
|
33
41
|
|
34
|
-
|
42
|
+
def find_many(options)
|
43
|
+
criteria, finder_options = to_finder_options(options)
|
44
|
+
super.tap do |documents|
|
45
|
+
remove_documents_from_map(documents) unless finder_options[:fields].nil?
|
46
|
+
end
|
35
47
|
end
|
36
48
|
|
37
49
|
def load(attrs)
|
@@ -43,6 +55,13 @@ module MongoMapper
|
|
43
55
|
|
44
56
|
document
|
45
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def remove_documents_from_map(*documents)
|
61
|
+
documents.flatten.compact.each do |document|
|
62
|
+
identity_map.delete(identity_map_key(document._id))
|
63
|
+
end
|
64
|
+
end
|
46
65
|
end
|
47
66
|
|
48
67
|
module InstanceMethods
|
@@ -11,15 +11,28 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
11
11
|
resource.identity_map.keys.should_not include(resource.identity_map_key)
|
12
12
|
end
|
13
13
|
|
14
|
+
def expect_no_queries
|
15
|
+
Mongo::Collection.any_instance.expects(:find_one).never
|
16
|
+
Mongo::Collection.any_instance.expects(:find).never
|
17
|
+
end
|
18
|
+
|
19
|
+
def expects_one_query
|
20
|
+
Mongo::Collection.any_instance.expects(:find_one).once.returns({})
|
21
|
+
end
|
22
|
+
|
14
23
|
context "Document" do
|
15
24
|
setup do
|
16
25
|
@person_class = Doc('Person') do
|
17
26
|
set_collection_name 'people'
|
27
|
+
plugin MongoMapper::Plugins::IdentityMap
|
28
|
+
|
18
29
|
key :name, String
|
19
30
|
end
|
20
31
|
|
21
32
|
@post_class = Doc('Post') do
|
22
33
|
set_collection_name 'posts'
|
34
|
+
plugin MongoMapper::Plugins::IdentityMap
|
35
|
+
|
23
36
|
key :title, String
|
24
37
|
key :person_id, ObjectId
|
25
38
|
end
|
@@ -82,7 +95,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
82
95
|
|
83
96
|
should "remove object from identity and re-query" do
|
84
97
|
assert_in_map(@person)
|
85
|
-
|
98
|
+
expects_one_query
|
86
99
|
@person.reload
|
87
100
|
end
|
88
101
|
|
@@ -120,7 +133,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
120
133
|
end
|
121
134
|
|
122
135
|
should "query the database" do
|
123
|
-
|
136
|
+
expects_one_query
|
124
137
|
@person_class.find(@person.id)
|
125
138
|
end
|
126
139
|
|
@@ -129,6 +142,10 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
129
142
|
found_person = @person_class.find(@person.id)
|
130
143
|
assert_in_map(found_person)
|
131
144
|
end
|
145
|
+
|
146
|
+
should "return nil if not found " do
|
147
|
+
@person_class.find(1234).should be_nil
|
148
|
+
end
|
132
149
|
end
|
133
150
|
|
134
151
|
context "for object in map" do
|
@@ -137,8 +154,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
137
154
|
end
|
138
155
|
|
139
156
|
should "not query database" do
|
140
|
-
|
141
|
-
Mongo::Collection.any_instance.expects(:find_one).never
|
157
|
+
expect_no_queries
|
142
158
|
@person_class.find(@person.id)
|
143
159
|
end
|
144
160
|
|
@@ -147,7 +163,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
147
163
|
found_person = @person_class.find(@person.id)
|
148
164
|
found_person.object_id.should == @person.object_id
|
149
165
|
end
|
150
|
-
end
|
166
|
+
end
|
151
167
|
end
|
152
168
|
|
153
169
|
context "#find (with one id and options)" do
|
@@ -165,7 +181,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
165
181
|
# way to check if document matches criteria without querying.
|
166
182
|
should "query the database" do
|
167
183
|
assert_in_map(@post1)
|
168
|
-
|
184
|
+
expects_one_query
|
169
185
|
@person.posts.find(@post1.id)
|
170
186
|
end
|
171
187
|
|
@@ -174,6 +190,10 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
174
190
|
@person.posts.find(@post1.id)
|
175
191
|
assert_in_map(@post1)
|
176
192
|
end
|
193
|
+
|
194
|
+
should "return nil if not found " do
|
195
|
+
@person.posts.find(1234).should be_nil
|
196
|
+
end
|
177
197
|
end
|
178
198
|
|
179
199
|
context "#find (with multiple ids)" do
|
@@ -212,7 +232,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
212
232
|
end
|
213
233
|
|
214
234
|
should "query the database" do
|
215
|
-
|
235
|
+
expects_one_query
|
216
236
|
@person_class.first(:_id => @person.id)
|
217
237
|
end
|
218
238
|
|
@@ -221,6 +241,10 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
221
241
|
found_person = @person_class.first(:_id => @person.id)
|
222
242
|
assert_in_map(found_person)
|
223
243
|
end
|
244
|
+
|
245
|
+
should "return nil if not found" do
|
246
|
+
@person_class.first(:name => 'Bill').should be_nil
|
247
|
+
end
|
224
248
|
end
|
225
249
|
|
226
250
|
context "for object in map" do
|
@@ -229,8 +253,7 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
229
253
|
end
|
230
254
|
|
231
255
|
should "not query database" do
|
232
|
-
|
233
|
-
Mongo::Collection.any_instance.expects(:find_one).never
|
256
|
+
expect_no_queries
|
234
257
|
@person_class.first(:_id => @person.id)
|
235
258
|
end
|
236
259
|
|
@@ -281,57 +304,101 @@ class IdentityMapTest < Test::Unit::TestCase
|
|
281
304
|
end
|
282
305
|
end
|
283
306
|
|
307
|
+
context "querying and selecting certain fields" do
|
308
|
+
setup do
|
309
|
+
@person = @person_class.create(:name => 'Bill')
|
310
|
+
@person_class.identity_map.clear
|
311
|
+
end
|
312
|
+
|
313
|
+
should "not add to map" do
|
314
|
+
assert_not_in_map(@person)
|
315
|
+
@person_class.first(:_id => @person.id, :select => 'name').should == @person
|
316
|
+
@person_class.first(:_id => @person.id, 'fields' => ['name']).should == @person
|
317
|
+
@person_class.last(:_id => @person.id, :select => 'name', :order => 'name').should == @person
|
318
|
+
@person_class.find(@person.id, :select => 'name').should == @person
|
319
|
+
@person_class.all(:_id => @person.id, :select => 'name').should == [@person]
|
320
|
+
assert_not_in_map(@person)
|
321
|
+
end
|
322
|
+
|
323
|
+
should "return nil if not found" do
|
324
|
+
@person_class.find(1234, :select => 'name').should be_nil
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
284
328
|
context "single collection inheritance" do
|
285
329
|
setup do
|
286
|
-
class ::
|
330
|
+
class ::Item
|
287
331
|
include MongoMapper::Document
|
332
|
+
plugin MongoMapper::Plugins::IdentityMap
|
333
|
+
|
288
334
|
key :_type, String
|
289
|
-
key :
|
335
|
+
key :title, String
|
290
336
|
key :parent_id, ObjectId
|
291
337
|
|
292
|
-
belongs_to :parent, :class_name => '
|
293
|
-
one :child, :class_name => '
|
338
|
+
belongs_to :parent, :class_name => 'Item'
|
339
|
+
one :child, :class_name => 'Blog'
|
294
340
|
end
|
295
|
-
|
296
|
-
|
341
|
+
Item.collection.remove
|
342
|
+
Item.identity_map.clear
|
297
343
|
|
298
|
-
class ::
|
344
|
+
class ::Blog < ::Item; end
|
345
|
+
|
346
|
+
class ::BlogPost < ::Item
|
347
|
+
key :blog_id, ObjectId
|
348
|
+
belongs_to :blog
|
349
|
+
end
|
299
350
|
end
|
300
351
|
|
301
352
|
teardown do
|
302
|
-
Object.send :remove_const, '
|
303
|
-
Object.send :remove_const, '
|
353
|
+
Object.send :remove_const, 'Item' if defined?(::Item)
|
354
|
+
Object.send :remove_const, 'Blog' if defined?(::Blog)
|
355
|
+
Object.send :remove_const, 'BlogPost' if defined?(::BlogPost)
|
304
356
|
end
|
305
357
|
|
306
358
|
should "share the same identity map 4eva" do
|
307
|
-
|
308
|
-
assert_in_map(
|
309
|
-
|
310
|
-
|
359
|
+
blog = Blog.create(:title => 'Jill')
|
360
|
+
assert_in_map(blog)
|
361
|
+
Item.identity_map_key(blog).should == Blog.identity_map_key(blog)
|
362
|
+
Item.identity_map.object_id.should == Blog.identity_map.object_id
|
363
|
+
end
|
364
|
+
|
365
|
+
should "not query when finding by _id and _type" do
|
366
|
+
blog = Blog.create(:title => 'Blog')
|
367
|
+
post = BlogPost.create(:title => 'Mongo Rocks', :blog => blog)
|
368
|
+
Item.identity_map.clear
|
369
|
+
|
370
|
+
blog = Item.find(blog.id)
|
371
|
+
post = Item.find(post.id)
|
372
|
+
assert_in_map(blog)
|
373
|
+
assert_in_map(post)
|
374
|
+
|
375
|
+
expect_no_queries
|
376
|
+
post.blog
|
377
|
+
Blog.find(blog.id)
|
311
378
|
end
|
312
379
|
|
313
380
|
should "load from map when using parent collection inherited class" do
|
314
|
-
|
315
|
-
|
381
|
+
blog = Blog.create(:title => 'Jill')
|
382
|
+
Item.find(blog.id).object_id.should == blog.object_id
|
316
383
|
end
|
317
384
|
|
318
385
|
should "work correctly with belongs to proxy" do
|
319
|
-
|
320
|
-
assert_in_map(
|
386
|
+
root = Item.create(:title => 'Root')
|
387
|
+
assert_in_map(root)
|
321
388
|
|
322
|
-
|
323
|
-
assert_in_map(
|
324
|
-
|
389
|
+
blog = Blog.create(:title => 'Jill', :parent => root)
|
390
|
+
assert_in_map(blog)
|
391
|
+
root.object_id.should == blog.parent.object_id
|
325
392
|
end
|
326
393
|
|
327
394
|
should "work correctly with one proxy" do
|
328
|
-
|
329
|
-
assert_in_map(
|
395
|
+
blog = Blog.create(:title => 'Jill')
|
396
|
+
assert_in_map(blog)
|
330
397
|
|
331
|
-
|
332
|
-
assert_in_map(
|
398
|
+
root = Item.create(:title => 'Root', :child => blog)
|
399
|
+
assert_in_map(root)
|
333
400
|
|
334
|
-
|
401
|
+
root.child.object_id.should == blog.object_id
|
335
402
|
end
|
336
403
|
end
|
337
404
|
end
|
@@ -242,6 +242,10 @@ class FinderOptionsTest < Test::Unit::TestCase
|
|
242
242
|
should "also work as select" do
|
243
243
|
FinderOptions.new(Room, :select => %w(a b)).options[:fields].should == %w(a b)
|
244
244
|
end
|
245
|
+
|
246
|
+
should "also work with select as array of symbols" do
|
247
|
+
FinderOptions.new(Room, :select => [:a, :b]).options[:fields].should == [:a, :b]
|
248
|
+
end
|
245
249
|
end
|
246
250
|
|
247
251
|
context "Condition auto-detection" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo_mapper-unstable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2010.1.
|
4
|
+
version: 2010.1.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-20 00:00:00 -05:00
|
13
13
|
default_executable: mmconsole
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|