diff --git a/lualib/mongo.lua b/lualib/mongo.lua index 7a8d6eb6..a1a2e11e 100644 --- a/lualib/mongo.lua +++ b/lualib/mongo.lua @@ -279,9 +279,45 @@ function mongo_collection:find(query, selector) __cursor = nil, __document = {}, __flags = 0, + __skip = 0, + __sortquery = nil, + __limit = 0, } , cursor_meta) end +function mongo_cursor:sort(key_list) + self.__sortquery = bson_encode {['$query'] = self.__query, ['$orderby'] = key_list} + return self +end + +function mongo_cursor:skip(amount) + self.__skip = amount + return self +end + +function mongo_cursor:limit(amount) + self.__limit = amount + return self +end + +function mongo_cursor:count(with_limit_and_skip) + local cmd = { + 'count', self.__collection.name, + 'query', self.__query, + } + if with_limit_and_skip then + local len = #cmd + cmd[len+1] = 'limit' + cmd[len+2] = self.__limit + cmd[len+3] = 'skip' + cmd[len+4] = self.__skip + end + local ret = self.__collection.database:runCommand(table.unpack(cmd)) + assert(ret and ret.ok == 1) + return ret.n +end + + -- collection:createIndex({username = 1}, {unique = true}) function mongo_collection:createIndex(keys, option) local name = option.name @@ -348,10 +384,11 @@ function mongo_cursor:hasNext() local sock = conn.__sock local pack if self.__data == nil then - pack = driver.query(request_id, self.__flags, self.__collection.full_name,0,0,self.__query,self.__selector) + local query = self.__sortquery or self.__query + pack = driver.query(request_id, self.__flags, self.__collection.full_name, self.__skip, -self.__limit, query, self.__selector) else if self.__cursor then - pack = driver.more(request_id, self.__collection.full_name,0,self.__cursor) + pack = driver.more(request_id, self.__collection.full_name, -self.__limit, self.__cursor) else -- no more self.__document = nil diff --git a/skynet-src/skynet_main.c b/skynet-src/skynet_main.c index 56d571f1..81148874 100644 --- a/skynet-src/skynet_main.c +++ b/skynet-src/skynet_main.c @@ -87,7 +87,7 @@ static const char * load_config = "\ local config_name = ...\ local f = assert(io.open(config_name))\ local code = assert(f:read \'*a\')\ - local function getenv(name) return assert(os.getenv(name), name) end\ + local function getenv(name) return assert(os.getenv(name), \'os.getenv() failed: \' .. name) end\ code = string.gsub(code, \'%$([%w_%d]+)\', getenv)\ f:close()\ local result = {}\ @@ -118,13 +118,13 @@ main(int argc, char *argv[]) { int err = luaL_loadstring(L, load_config); assert(err == LUA_OK); lua_pushstring(L, config_file); - + err = lua_pcall(L, 1, 1, 0); if (err) { fprintf(stderr,"%s\n",lua_tostring(L,-1)); lua_close(L); return 1; - } + } _init_env(L); config.thread = optint("thread",8); diff --git a/test/testmongodb.lua b/test/testmongodb.lua index f1fa81e0..d1fed034 100644 --- a/test/testmongodb.lua +++ b/test/testmongodb.lua @@ -43,10 +43,22 @@ function test_find_and_remove() local ret = db[db_name].testdb:safe_insert({test_key = 1}) assert(ret and ret.n == 1) + local ret = db[db_name].testdb:safe_insert({test_key = 2}) + assert(ret and ret.n == 1) + local ret = db[db_name].testdb:findOne({test_key = 1}) assert(ret and ret.test_key == 1) + local ret = db[db_name].testdb:find({test_key = {['$gt'] = 0}}):sort({test_key = -1}):skip(1):limit(1) + assert(ret:count() == 2) + assert(ret:count(true) == 1) + if ret:hasNext() then + ret = ret:next() + end + assert(ret and ret.test_key == 1) + db[db_name].testdb:delete({test_key = 1}) + db[db_name].testdb:delete({test_key = 2}) local ret = db[db_name].testdb:findOne({test_key = 1}) assert(ret == nil)