RUBY-147 check for CursorNotFound response flag
This commit is contained in:
parent
030c850669
commit
265f074f10
15
lib/mongo.rb
15
lib/mongo.rb
|
@ -21,11 +21,18 @@ module Mongo
|
|||
OP_DELETE = 2006
|
||||
OP_KILL_CURSORS = 2007
|
||||
|
||||
OP_QUERY_TAILABLE = 2
|
||||
OP_QUERY_SLAVE_OK = 4
|
||||
OP_QUERY_NO_CURSOR_TIMEOUT = 16
|
||||
end
|
||||
OP_QUERY_TAILABLE = 2 ** 1
|
||||
OP_QUERY_SLAVE_OK = 2 ** 2
|
||||
OP_QUERY_OPLOG_REPLAY = 2 ** 3
|
||||
OP_QUERY_NO_CURSOR_TIMEOUT = 2 ** 4
|
||||
OP_QUERY_AWAIT_DATA = 2 ** 5
|
||||
OP_QUERY_EXHAUST = 2 ** 6
|
||||
|
||||
REPLY_CURSOR_NOT_FOUND = 2 ** 0
|
||||
REPLY_QUERY_FAILURE = 2 ** 1
|
||||
REPLY_SHARD_CONFIG_STALE = 2 ** 2
|
||||
REPLY_AWAIT_CAPABLE = 2 ** 3
|
||||
end
|
||||
end
|
||||
|
||||
require 'bson'
|
||||
|
|
|
@ -157,7 +157,8 @@ module Mongo
|
|||
raise RuntimeError, "Unknown options [#{opts.inspect}]" unless opts.empty?
|
||||
|
||||
cursor = Cursor.new(self, :selector => selector, :fields => fields, :skip => skip, :limit => limit,
|
||||
:order => sort, :hint => hint, :snapshot => snapshot, :timeout => timeout, :batch_size => batch_size)
|
||||
:order => sort, :hint => hint, :snapshot => snapshot, :timeout => timeout, :batch_size => batch_size)
|
||||
|
||||
if block_given?
|
||||
yield cursor
|
||||
cursor.close()
|
||||
|
|
|
@ -632,13 +632,22 @@ module Mongo
|
|||
"expected #{RESPONSE_HEADER_SIZE} bytes, saw #{header_buf.length}"
|
||||
end
|
||||
header_buf.rewind
|
||||
result_flags = header_buf.get_int
|
||||
check_response_flags(header_buf.get_int)
|
||||
cursor_id = header_buf.get_long
|
||||
starting_from = header_buf.get_int
|
||||
number_remaining = header_buf.get_int
|
||||
[number_remaining, cursor_id]
|
||||
end
|
||||
|
||||
def check_response_flags(flags)
|
||||
if flags & Mongo::Constants::REPLY_CURSOR_NOT_FOUND != 0
|
||||
raise Mongo::OperationFailure, "Query response returned CURSOR_NOT_FOUND. " +
|
||||
"Either an invalid cursor was specified, or the cursor may have timed out on the server."
|
||||
elsif flags & Mongo::Constants::REPLY_QUERY_FAILURE != 0
|
||||
raise Mongo::OperationFailure, "Query response returned QUERY_FAILURE."
|
||||
end
|
||||
end
|
||||
|
||||
def read_documents(number_received, cursor_id, sock)
|
||||
docs = []
|
||||
number_remaining = number_received
|
||||
|
|
|
@ -23,7 +23,7 @@ module Mongo
|
|||
|
||||
attr_reader :collection, :selector, :admin, :fields,
|
||||
:order, :hint, :snapshot, :timeout,
|
||||
:full_collection_name
|
||||
:full_collection_name, :batch_size
|
||||
|
||||
# Create a new cursor.
|
||||
#
|
||||
|
@ -237,7 +237,7 @@ module Mongo
|
|||
message = BSON::ByteBuffer.new([0, 0, 0, 0])
|
||||
message.put_int(1)
|
||||
message.put_long(@cursor_id)
|
||||
@connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, "cursor.close")
|
||||
@connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, "cursor.close #{@cursor_id}")
|
||||
end
|
||||
@cursor_id = 0
|
||||
@closed = true
|
||||
|
|
|
@ -137,7 +137,7 @@ class CursorTest < Test::Unit::TestCase
|
|||
@@coll.save({:t => 't2'})
|
||||
@@coll.save({:t => 't2'})
|
||||
|
||||
assert_equal 3, @@coll.find({'_id' => {'$gt' => t1_id}, '_id' => {'$lt' => t2_id}}).count
|
||||
assert_equal 3, @@coll.find({'_id' => {'$gt' => t1_id, '$lt' => t2_id}}).count
|
||||
@@coll.find({'_id' => {'$gt' => t2_id}}).each do |doc|
|
||||
assert_equal 't2', doc['t']
|
||||
end
|
||||
|
@ -396,4 +396,21 @@ class CursorTest < Test::Unit::TestCase
|
|||
|
||||
assert_equal false, cursor.has_next?
|
||||
end
|
||||
|
||||
def test_cursor_invalid
|
||||
@@coll.remove
|
||||
1000.times do |n|
|
||||
@@coll.insert({:a => n})
|
||||
end
|
||||
|
||||
cursor = @@coll.find({})
|
||||
cursor.next_document
|
||||
cursor.close
|
||||
|
||||
assert_raise_error(Mongo::OperationFailure, "CURSOR_NOT_FOUND") do
|
||||
999.times do
|
||||
cursor.next_document
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue