修复 mongo 游标没有数据 hasNext 返回 true,以及无效关闭游标的问题 (#1653)

Co-authored-by: yy151474 <yy151474@alibaba-inc.com>
This commit is contained in:
ykxpb
2022-09-24 08:41:37 +08:00
committed by GitHub
parent ccfdc9440a
commit bc4800f326
2 changed files with 21 additions and 4 deletions

View File

@@ -14,6 +14,7 @@ local table = table
local bson_encode = bson.encode
local bson_encode_order = bson.encode_order
local bson_decode = bson.decode
local bson_int64 = bson.int64
local empty_bson = bson_encode {}
local mongo = {}
@@ -489,7 +490,10 @@ end
function mongo_collection:findOne(query, projection)
local cursor = self:find(query, projection)
return cursor:hasNext() and cursor:next()
if cursor:hasNext() then
return cursor:next()
end
return nil
end
function mongo_collection:find(query, projection)
@@ -686,7 +690,7 @@ function mongo_cursor:hasNext()
else
if self.__cursor and self.__cursor > 0 then
local name = self.__collection.name
response = database:runCommand("getMore", bson.int64(self.__cursor), "collection", name, "batchSize", self.__limit)
response = database:runCommand("getMore", bson_int64(self.__cursor), "collection", name, "batchSize", self.__limit)
else
-- no more
self.__document = nil
@@ -719,6 +723,10 @@ function mongo_cursor:hasNext()
self.__limit = limit
end
if cursor.id == 0 and #self.__document == 0 then -- nomore
return false
end
return true
end
@@ -739,9 +747,9 @@ function mongo_cursor:next()
end
function mongo_cursor:close()
if self.__cursor then
if self.__cursor and self.__cursor > 0 then
local coll = self.__collection
coll.database:send_command("killCursors", coll.name, "cursors", {self.__cursor})
coll.database:send_command("killCursors", coll.name, "cursors", {bson_int64(self.__cursor)})
self.__cursor = nil
end
end

View File

@@ -79,11 +79,20 @@ function test_find_and_remove()
db.testcoll:dropIndex("*")
db.testcoll:drop()
local cursor = db.testcoll:find()
assert(cursor:hasNext() == false)
db.testcoll:ensureIndex({test_key = 1}, {test_key2 = -1}, {unique = true, name = "test_index"})
ok, err, ret = db.testcoll:safe_insert({test_key = 1, test_key2 = 1})
assert(ok and ret and ret.n == 1, err)
cursor = db.testcoll:find()
assert(cursor:hasNext() == true)
local v = cursor:next()
assert(v)
assert(v.test_key == 1)
ok, err, ret = db.testcoll:safe_insert({test_key = 1, test_key2 = 2})
assert(ok and ret and ret.n == 1, err)