Added #limit and #offset methods for cursor objects

Signed-off-by: Mike Dirolf <mike@dirolf.com>
This commit is contained in:
Kyle Banker 2009-09-06 02:25:49 +08:00 committed by Mike Dirolf
parent c82a7e32af
commit c397758d1d
2 changed files with 106 additions and 0 deletions

View File

@ -74,6 +74,30 @@ module Mongo
raise OperationFailure, "Count failed: #{response['errmsg']}"
end
# Sets a limit on the number of results returned by the query.
# Returns a cursor object.
#
# Note: this method overrides any limit specified in the #find method.
def limit(number_to_return)
check_modifiable
raise ArgumentError, "limit requires an integer" unless number_to_return.is_a? Integer
@number_to_return = number_to_return
@query.number_to_return = number_to_return
return self
end
# Sets an offset on the query results. Returns a cursor object.
#
# Note: this method overrides any offset specified in the #find method.
def offset(number_to_skip)
check_modifiable
raise ArgumentError, "limit requires an integer" unless number_to_skip.is_a? Integer
@query.number_to_skip = number_to_skip
return self
end
# Iterate over each document in this cursor, yielding it to the given
# block.
#
@ -226,5 +250,11 @@ module Mongo
def to_s
"DBResponse(flags=#@result_flags, cursor_id=#@cursor_id, start=#@starting_from, n_returned=#@n_returned)"
end
def check_modifiable
if @query_run || @closed
raise InvalidOperation, "Cannot modify the query once it has been run or closed."
end
end
end
end

View File

@ -58,6 +58,82 @@ class CursorTest < Test::Unit::TestCase
assert_equal 0, @@db['acollectionthatdoesn'].count()
end
def test_limit
@@coll.clear
10.times do |i|
@@coll.save("x" => i)
end
assert_equal 10, @@coll.find().count()
results = @@coll.find().limit(5).to_a
assert_equal 5, results.length
end
def test_limit_exceptions
assert_raise ArgumentError do
cursor = @@coll.find().limit('not-an-integer')
end
cursor = @@coll.find()
firstResult = cursor.next_object()
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
cursor.limit(1)
end
cursor = @@coll.find()
cursor.close
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
cursor.limit(1)
end
end
def test_offset
@@coll.clear
10.times do |i|
@@coll.save("x" => i)
end
assert_equal 10, @@coll.find().count()
all_results = @@coll.find().to_a
offset_results = @@coll.find().offset(2).to_a
assert_equal 10, all_results.length
assert_equal 8, offset_results.length
assert_equal all_results.slice(2...10), offset_results
end
def test_offset_exceptions
assert_raise ArgumentError do
cursor = @@coll.find().offset('not-an-integer')
end
cursor = @@coll.find()
firstResult = cursor.next_object()
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
cursor.offset(1)
end
cursor = @@coll.find()
cursor.close
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
cursor.offset(1)
end
end
def test_limit_offset_chaining
@@coll.clear
10.times do |i|
@@coll.save("x" => i)
end
all_results = @@coll.find().to_a
limited_offset_results = @@coll.find().limit(5).offset(3).to_a
assert_equal all_results.slice(3...8), limited_offset_results
end
def test_close_no_query_sent
begin
cursor = @@coll.find('a' => 1)