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:
parent
95238b0a29
commit
de6fef357b
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue