diff --git a/lualib/skynet/db/mongo.lua b/lualib/skynet/db/mongo.lua index 00ae86d5..d51b4d14 100644 --- a/lualib/skynet/db/mongo.lua +++ b/lualib/skynet/db/mongo.lua @@ -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 diff --git a/test/testmongodb.lua b/test/testmongodb.lua index bff60fab..89033e99 100644 --- a/test/testmongodb.lua +++ b/test/testmongodb.lua @@ -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)