Skip to content

Commit 6b2939f

Browse files
committed
RUBY-171 allow Cursor#to_a even after iterating; added Cursor#rewind; consistent Enumberable behavior for Cursor
1 parent 06602bd commit 6b2939f

File tree

3 files changed

+52
-31
lines changed

3 files changed

+52
-31
lines changed

lib/mongo/cursor.rb

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ def next_document
8181
doc
8282
end
8383

84+
# Reset this cursor on the server. Cursor options, such as the
85+
# query string and the values for skip and limit, are preserved.
86+
def rewind!
87+
close
88+
@cache.clear
89+
@cursor_id = nil
90+
@closed = false
91+
@query_run = false
92+
@n_received = nil
93+
true
94+
end
95+
8496
# Determine whether this cursor has any remaining results.
8597
#
8698
# @return [Boolean]
@@ -187,22 +199,18 @@ def each
187199

188200
# Receive all the documents from this cursor as an array of hashes.
189201
#
190-
# Note: use of this method is discouraged - in most cases, it's much more
202+
# Notes:
203+
#
204+
# If you've already started iterating over the cursor, the array returned
205+
# by this method contains only the remaining documents. See Cursor#rewind! if you
206+
# need to reset the cursor.
207+
#
208+
# Use of this method is discouraged - in most cases, it's much more
191209
# efficient to retrieve documents as you need them by iterating over the cursor.
192210
#
193211
# @return [Array] an array of documents.
194-
#
195-
# @raise [InvalidOperation] if this cursor has already been used or if
196-
# this method has already been called on the cursor.
197212
def to_a
198-
raise InvalidOperation, "can't call Cursor#to_a on a used cursor" if @query_run
199-
rows = []
200-
num_returned = 0
201-
while has_next? && (@limit <= 0 || num_returned < @limit)
202-
rows << next_document
203-
num_returned += 1
204-
end
205-
rows
213+
super
206214
end
207215

208216
# Get the explain plan for this cursor.

test/cursor_test.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,4 +396,36 @@ def test_cursor_invalid
396396
end
397397
end
398398

399+
def test_enumberables
400+
@@coll.remove
401+
100.times do |n|
402+
@@coll.insert({:a => n})
403+
end
404+
405+
assert_equal 100, @@coll.find.to_a.length
406+
assert_equal 100, @@coll.find.to_set.length
407+
408+
cursor = @@coll.find
409+
50.times { |n| cursor.next_document }
410+
assert_equal 50, cursor.to_a.length
411+
end
412+
413+
def test_rewind
414+
@@coll.remove
415+
100.times do |n|
416+
@@coll.insert({:a => n})
417+
end
418+
419+
cursor = @@coll.find
420+
cursor.to_a
421+
assert_equal [], cursor.map {|doc| doc }
422+
423+
cursor.rewind!
424+
assert_equal 100, cursor.map {|doc| doc }.length
425+
426+
cursor.rewind!
427+
5.times { cursor.next_document }
428+
cursor.rewind!
429+
assert_equal 100, cursor.map {|doc| doc }.length
430+
end
399431
end

test/db_api_test.rb

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -445,25 +445,6 @@ def test_strict_create_collection
445445
@@db.drop_collection('foobar')
446446
end
447447

448-
def test_to_a
449-
cursor = @@coll.find()
450-
rows = cursor.to_a
451-
452-
assert_raise InvalidOperation do
453-
cursor.to_a
454-
end
455-
456-
cursor.each { |doc| fail "should be no docs in each now" }
457-
end
458-
459-
def test_to_a_after_each
460-
cursor = @@coll.find
461-
cursor.each { |row| row }
462-
assert_raise InvalidOperation do
463-
cursor.to_a
464-
end
465-
end
466-
467448
def test_where
468449
@@coll.insert('a' => 2)
469450
@@coll.insert('a' => 3)

0 commit comments

Comments
 (0)