driver was sending hard limits where it should've sent soft, and vice-versa. fix and add tests for this

This commit is contained in:
Mike Dirolf 2009-09-30 10:49:08 -04:00
parent 95238b0a29
commit de6fef357b
6 changed files with 91 additions and 61 deletions

View File

@ -335,6 +335,9 @@ Kyle Banker, banker on github
Michael Bernstein, mrb on github Michael Bernstein, mrb on github
* #sort method for Cursor instances * #sort method for Cursor instances
Paulo Ahahgon, pahagon on github
* removed hard limit
= License = License
Copyright 2008-2009 10gen Inc. Copyright 2008-2009 10gen Inc.

View File

@ -173,7 +173,6 @@ module Mongo
# Collection#find for details. # Collection#find for details.
def close def close
@db.send_to_db(KillCursorsMessage.new(@cursor_id)) if @cursor_id @db.send_to_db(KillCursorsMessage.new(@cursor_id)) if @cursor_id
@cache = []
@cursor_id = 0 @cursor_id = 0
@closed = true @closed = true
end end
@ -207,8 +206,15 @@ module Mongo
@result_flags = header_buf.get_int @result_flags = header_buf.get_int
@cursor_id = header_buf.get_long @cursor_id = header_buf.get_long
@starting_from = header_buf.get_int @starting_from = header_buf.get_int
@n_returned = header_buf.get_int @n_remaining = header_buf.get_int
@n_remaining = @n_returned if @n_received
@n_received += @n_remaining
else
@n_received = @n_remaining
end
if @query.number_to_return > 0 and @n_received >= @query.number_to_return
close()
end
end end
def num_remaining def num_remaining
@ -267,7 +273,7 @@ module Mongo
end end
def to_s def to_s
"DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from, n_returned=#@n_returned)" "DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from)"
end end
def check_modifiable def check_modifiable

View File

@ -525,8 +525,6 @@ module Mongo
# DB commands need to be ordered, so selector must be an OrderedHash # DB commands need to be ordered, so selector must be an OrderedHash
# (or a Hash with only one element). What DB commands really need is # (or a Hash with only one element). What DB commands really need is
# that the "command" key be first. # that the "command" key be first.
#
# Do not call this. Intended for driver use only.
def db_command(selector, use_admin_db=false) def db_command(selector, use_admin_db=false)
if !selector.kind_of?(OrderedHash) if !selector.kind_of?(OrderedHash)
if !selector.kind_of?(Hash) || selector.keys.length > 1 if !selector.kind_of?(Hash) || selector.keys.length > 1
@ -535,7 +533,7 @@ module Mongo
end end
q = Query.new(selector) q = Query.new(selector)
q.number_to_return = 1 q.number_to_return = -1
query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q, use_admin_db).next_object query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q, use_admin_db).next_object
end end

View File

@ -31,7 +31,7 @@ module Mongo
write_int(0) write_int(0)
write_string("#{db_name}.#{collection_name}") write_string("#{db_name}.#{collection_name}")
write_int(query.number_to_skip) write_int(query.number_to_skip)
write_int(-query.number_to_return) # Negative means hard limit write_int(query.number_to_return)
sel = query.selector sel = query.selector
if query.contains_special_fields if query.contains_special_fields
sel = OrderedHash.new sel = OrderedHash.new

View File

@ -216,6 +216,39 @@ class TestCollection < Test::Unit::TestCase
assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
end end
def test_large_limit
2000.times do |i|
@@test.insert("x" => i, "y" => "mongomongo" * 1000)
end
assert_equal 2000, @@test.count
i = 0
y = 0
@@test.find({}, :limit => 1900).each do |doc|
i += 1
y += doc["x"]
end
assert_equal 1900, i
assert_equal 1804050, y
end
def test_small_limit
@@test.insert("x" => "hello world")
@@test.insert("x" => "goodbye world")
assert_equal 2, @@test.count
x = 0
@@test.find({}, :limit => 1).each do |doc|
x += 1
assert_equal "hello world", doc["x"]
end
assert_equal 1, x
end
def test_group_with_scope def test_group_with_scope
@@test.save("a" => 1) @@test.save("a" => 1)
@@test.save("b" => 1) @@test.save("b" => 1)

View File

@ -167,69 +167,59 @@ class CursorTest < Test::Unit::TestCase
end end
def test_refill_via_get_more def test_refill_via_get_more
begin assert_equal 1, @@coll.count
assert_equal 1, @@coll.count 1000.times { |i|
1000.times { |i| assert_equal 1 + i, @@coll.count
assert_equal 1 + i, @@coll.count @@coll.insert('a' => i)
@@coll.insert('a' => i) }
}
assert_equal 1001, @@coll.count assert_equal 1001, @@coll.count
count = 0 count = 0
@@coll.find.each { |obj| @@coll.find.each { |obj|
count += obj['a'] count += obj['a']
} }
assert_equal 1001, @@coll.count assert_equal 1001, @@coll.count
# do the same thing again for debugging # do the same thing again for debugging
assert_equal 1001, @@coll.count assert_equal 1001, @@coll.count
count2 = 0 count2 = 0
@@coll.find.each { |obj| @@coll.find.each { |obj|
count2 += obj['a'] count2 += obj['a']
} }
assert_equal 1001, @@coll.count assert_equal 1001, @@coll.count
assert_equal count, count2 assert_equal count, count2
assert_equal 499501, count assert_equal 499501, count
rescue Test::Unit::AssertionFailedError => ex
p @@db.collection_names
Process.exit 1
end
end end
def test_refill_via_get_more_alt_coll def test_refill_via_get_more_alt_coll
begin coll = @@db.collection('test-alt-coll')
coll = @@db.collection('test-alt-coll') coll.clear
coll.clear coll.insert('a' => 1) # collection not created until it's used
coll.insert('a' => 1) # collection not created until it's used assert_equal 1, coll.count
assert_equal 1, coll.count
1000.times { |i| 1000.times { |i|
assert_equal 1 + i, coll.count assert_equal 1 + i, coll.count
coll.insert('a' => i) coll.insert('a' => i)
} }
assert_equal 1001, coll.count assert_equal 1001, coll.count
count = 0 count = 0
coll.find.each { |obj| coll.find.each { |obj|
count += obj['a'] count += obj['a']
} }
assert_equal 1001, coll.count assert_equal 1001, coll.count
# do the same thing again for debugging # do the same thing again for debugging
assert_equal 1001, coll.count assert_equal 1001, coll.count
count2 = 0 count2 = 0
coll.find.each { |obj| coll.find.each { |obj|
count2 += obj['a'] count2 += obj['a']
} }
assert_equal 1001, coll.count assert_equal 1001, coll.count
assert_equal count, count2 assert_equal count, count2
assert_equal 499501, count assert_equal 499501, count
rescue Test::Unit::AssertionFailedError => ex
p @@db.collection_names
Process.exit 1
end
end end
def test_close_after_query_sent def test_close_after_query_sent