Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added ReplicaSet support

You can create one via:
    mongo.ReplicaSet.New( 'rsname', { 'host1:port1', 'host2:port2' } )

In doing this, refactored all the common client methods to use DBClientBase rather than DBClientConnection.  Basically, a ton of stuff was moved from mongo_connection.cpp to mongo_dbclient.cpp with search/replace of DBClientConnection/DBClientBase and connection/dbclient.  No other functional changes were made to these functions, except that they dispatch to a new function userdata_to_dbclient.

Once that refactoring was done, adding ReplicaSet as a new top-level class was relatively straight-forward.
  • Loading branch information...
commit 90e2fdf491e005f33026e04c4a03e5b3c61db46f 1 parent ae8d9c9
@neomantra neomantra authored
View
6 Makefile
@@ -8,7 +8,7 @@ OUTLIB=mongo.so
LDFLAGS= $(LIBS)
-OBJS = main.o mongo_bsontypes.o mongo_connection.o mongo_cursor.o mongo_gridfile.o mongo_gridfs.o mongo_gridfschunk.o mongo_query.o utils.o
+OBJS = main.o mongo_bsontypes.o mongo_dbclient.o mongo_replicaset.o mongo_connection.o mongo_cursor.o mongo_gridfile.o mongo_gridfs.o mongo_gridfschunk.o mongo_query.o utils.o
all: luamongo
@@ -31,6 +31,8 @@ echo:
main.o: main.cpp utils.h
$(CC) -c -o $@ $< $(CFLAGS)
+mongo_dbclient.o: mongo_dbclient.cpp common.h utils.h
+ $(CC) -c -o $@ $< $(CFLAGS)
mongo_connection.o: mongo_connection.cpp common.h utils.h
$(CC) -c -o $@ $< $(CFLAGS)
mongo_cursor.o: mongo_cursor.cpp common.h utils.h
@@ -43,6 +45,8 @@ mongo_gridfschunk.o: mongo_gridfschunk.cpp common.h utils.h
$(CC) -c -o $@ $< $(CFLAGS)
mongo_query.o: mongo_query.cpp common.h utils.h
$(CC) -c -o $@ $< $(CFLAGS)
+mongo_replicaset.o: mongo_replicaset.cpp common.h utils.h
+ $(CC) -c -o $@ $< $(CFLAGS)
mongo_bsontypes.o: mongo_bsontypes.cpp common.h
$(CC) -c -o $@ $< $(CFLAGS)
utils.o: utils.cpp common.h utils.h
View
14 common.h
@@ -1,12 +1,17 @@
-#define LUAMONGO_ROOT "mongo"
-#define LUAMONGO_CONNECTION "mongo.Connection"
-#define LUAMONGO_CURSOR "mongo.Cursor"
-#define LUAMONGO_QUERY "mongo.Query"
+#define LUAMONGO_ROOT "mongo"
+#define LUAMONGO_CONNECTION "mongo.Connection"
+#define LUAMONGO_REPLICASET "mongo.ReplicaSet"
+#define LUAMONGO_CURSOR "mongo.Cursor"
+#define LUAMONGO_QUERY "mongo.Query"
#define LUAMONGO_GRIDFS "mongo.GridFS"
#define LUAMONGO_GRIDFILE "mongo.GridFile"
#define LUAMONGO_GRIDFSCHUNK "mongo.GridFSChunk"
+// not an actual class, pseudo-base for error messages
+#define LUAMONGO_DBCLIENT "mongo.DBClient"
+
#define LUAMONGO_ERR_CONNECTION_FAILED "Connection failed: %s"
+#define LUAMONGO_ERR_REPLICASET_FAILED "ReplicaSet.New failed: %s"
#define LUAMONGO_ERR_GRIDFS_FAILED "GridFS failed: %s"
#define LUAMONGO_ERR_GRIDFSCHUNK_FAILED "GridFSChunk failed: %s"
#define LUAMONGO_ERR_QUERY_FAILED "Query failed: %s"
@@ -27,3 +32,4 @@
#else
#define CHUNK GridFSChunk
#endif
+
View
2  main.cpp
@@ -38,6 +38,7 @@ extern "C" {
extern int mongo_bsontypes_register(lua_State *L);
extern int mongo_connection_register(lua_State *L);
+extern int mongo_replicaset_register(lua_State *L);
extern int mongo_cursor_register(lua_State *L);
extern int mongo_query_register(lua_State *L);
extern int mongo_gridfs_register(lua_State *L);
@@ -55,6 +56,7 @@ extern "C" {
LM_EXPORT int luaopen_mongo(lua_State *L) {
mongo_bsontypes_register(L);
mongo_connection_register(L);
+ mongo_replicaset_register(L);
mongo_cursor_register(L);
mongo_query_register(L);
View
677 mongo_connection.cpp
@@ -1,4 +1,3 @@
-#include <iostream>
#include <client/dbclient.h>
extern "C" {
@@ -11,26 +10,19 @@ extern "C" {
#endif
};
-#include "utils.h"
#include "common.h"
using namespace mongo;
-extern int cursor_create(lua_State *L, DBClientConnection *connection, const char *ns,
- const Query &query, int nToReturn, int nToSkip,
- const BSONObj *fieldsToReturn, int queryOptions, int batchSize);
-
-extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj);
-extern void bson_to_lua(lua_State *L, const BSONObj &obj);
-extern void lua_push_value(lua_State *L, const BSONElement &elem);
+extern const luaL_Reg dbclient_methods[];
namespace {
inline DBClientConnection* userdata_to_connection(lua_State* L, int index) {
- void *ud = 0;
- ud = luaL_checkudata(L, index, LUAMONGO_CONNECTION);
+ void *ud = luaL_checkudata(L, index, LUAMONGO_CONNECTION);
DBClientConnection *connection = *((DBClientConnection **)ud);
return connection;
}
+
} // anonymous namespace
/*
@@ -75,8 +67,9 @@ static int connection_new(lua_State *L) {
return resultcount;
}
+
/*
- * ok,err = db:connect(connection_str)
+ * ok,err = connection:connect(connection_str)
*/
static int connection_connect(lua_State *L) {
DBClientConnection *connection = userdata_to_connection(L, 1);
@@ -94,640 +87,6 @@ static int connection_connect(lua_State *L) {
return 1;
}
-/*
- * created = db:ensure_index(ns, json_str or lua_table[, unique[, name]])
- */
-static int connection_ensure_index(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
- BSONObj fields;
-
- try {
- int type = lua_type(L, 3);
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 3);
- fields = fromjson(jsonstr);
- } else if (type == LUA_TTABLE) {
- lua_to_bson(L, 3, fields);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "ensure_index", e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- bool unique = lua_toboolean(L, 4);
- const char *name = luaL_optstring(L, 5, "");
-
- bool res = connection->ensureIndex(ns, fields, unique, name);
-
- lua_pushboolean(L, res);
- return 1;
-}
-
-/*
- * ok,err = db:auth({})
- * accepts a table of parameters:
- * dbname database to authenticate (required)
- * username username to authenticate against (required)
- * password password to authenticate against (required)
- * digestPassword set to true if password is pre-digested (default = true)
- *
- */
-static int connection_auth(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
-
- luaL_checktype(L, 2, LUA_TTABLE);
- lua_getfield(L, 2, "dbname");
- const char *dbname = luaL_checkstring(L, -1);
- lua_getfield(L, 2, "username");
- const char *username = luaL_checkstring(L, -1);
- lua_getfield(L, 2, "password");
- const char *password = luaL_checkstring(L, -1);
- lua_getfield(L, 2, "digestPassword");
- bool digestPassword = lua_isnil(L, -1) ? true : lua_toboolean(L, -1);
- lua_pop(L, 4);
-
- std::string errmsg;
- bool success = connection->auth(dbname, username, password, errmsg, digestPassword);
- if (!success) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, errmsg.c_str());
- return 2;
- }
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * is_failed = db:is_failed()
- */
-static int connection_is_failed(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
-
- bool is_failed = connection->isFailed();
- lua_pushboolean(L, is_failed);
- return 1;
-}
-
-/*
- * addr = db:get_server_address()
- */
-static int connection_get_server_address(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
-
- std::string address = connection->getServerAddress();
- lua_pushstring(L, address.c_str());
- return 1;
-}
-
-/*
- * count,err = db:count(ns)
- */
-static int connection_count(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- int count = 0;
- try {
- count = connection->count(ns);
- } catch (std::exception &e) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_COUNT_FAILED, e.what());
- return 2;
- }
-
- lua_pushinteger(L, count);
- return 1;
-}
-
-/*
- * ok,err = db:insert(ns, lua_table or json_str)
- */
-static int connection_insert(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- int type = lua_type(L, 3);
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 3);
- connection->insert(ns, fromjson(jsonstr));
- } else if (type == LUA_TTABLE) {
- BSONObj data;
- lua_to_bson(L, 3, data);
-
- connection->insert(ns, data);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:insert_batch(ns, lua_array_of_tables)
- */
-static int connection_insert_batch(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
- luaL_checktype(L, 3, LUA_TTABLE);
-
- try {
- std::vector<BSONObj> vdata;
- size_t tlen = lua_objlen(L, 3) + 1;
- for (size_t i = 1; i < tlen; ++i) {
- vdata.push_back(BSONObj());
- lua_rawgeti(L, 3, i);
- lua_to_bson(L, 4, vdata.back());
- lua_pop(L, 1);
- }
- connection->insert(ns, vdata);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * cursor,err = db:query(ns, lua_table or json_str or query_obj, limit, skip, lua_table or json_str, options, batchsize)
- */
-static int connection_query(lua_State *L) {
- int n = lua_gettop(L);
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- Query query;
- if (!lua_isnoneornil(L, 3)) {
- try {
- int type = lua_type(L, 3);
- if (type == LUA_TSTRING) {
- query = fromjson(luaL_checkstring(L, 3));
- } else if (type == LUA_TTABLE) {
- BSONObj obj;
- lua_to_bson(L, 3, obj);
- query = obj;
- } else if (type == LUA_TUSERDATA) {
- void *uq = 0;
-
- uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
- query = *(*((Query **)uq));
- } else {
- throw(LUAMONGO_REQUIRES_QUERY);
- }
- } catch (std::exception &e) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_QUERY_FAILED, e.what());
- return 2;
- } catch (const char *err) {
- lua_pushnil(L);
- lua_pushstring(L, err);
- return 2;
- }
- }
-
- int nToReturn = luaL_optint(L, 4, 0);
- int nToSkip = luaL_optint(L, 5, 0);
-
- const BSONObj *fieldsToReturn = NULL;
- if (!lua_isnoneornil(L, 6)) {
- fieldsToReturn = new BSONObj();
-
- int type = lua_type(L, 6);
-
- if (type == LUA_TSTRING) {
- fieldsToReturn = new BSONObj(luaL_checkstring(L, 6));
- } else if (type == LUA_TTABLE) {
- BSONObj obj;
- lua_to_bson(L, 6, obj);
- fieldsToReturn = new BSONObj(obj);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- }
-
- int queryOptions = luaL_optint(L, 7, 0);
- int batchSize = luaL_optint(L, 8, 0);
-
- int res = cursor_create(L, connection, ns, query, nToReturn, nToSkip,
- fieldsToReturn, queryOptions, batchSize);
-
- if (fieldsToReturn) {
- delete fieldsToReturn;
- }
-
- return res;
-}
-
-/*
- * ok,err = db:remove(ns, lua_table or json_str or query_obj)
- */
-static int connection_remove(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- int type = lua_type(L, 3);
- bool justOne = lua_toboolean(L, 4);
-
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 3);
- connection->remove(ns, fromjson(jsonstr), justOne);
- } else if (type == LUA_TTABLE) {
- BSONObj data;
- lua_to_bson(L, 3, data);
-
- connection->remove(ns, data, justOne);
- } else if (type == LUA_TUSERDATA) {
- Query query;
- void *uq = 0;
-
- uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
- query = *(*((Query **)uq));
-
- connection->remove(ns, query, justOne);
- } else {
- throw(LUAMONGO_REQUIRES_QUERY);
- }
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_REMOVE_FAILED, e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:update(ns, lua_table or json_str or query_obj, lua_table or json_str, upsert, multi)
- */
-static int connection_update(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- int type_query = lua_type(L, 3);
- int type_obj = lua_type(L, 4);
-
- bool upsert = lua_toboolean(L, 5);
- bool multi = lua_toboolean(L, 6);
-
- Query query;
- BSONObj obj;
-
- if (type_query == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 3);
- query = fromjson(jsonstr);
- } else if (type_query == LUA_TTABLE) {
- BSONObj q;
-
- lua_to_bson(L, 3, q);
- query = q;
- } else if (type_query == LUA_TUSERDATA) {
- void *uq = 0;
-
- uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
- query = *(*((Query **)uq));
- } else {
- throw(LUAMONGO_REQUIRES_QUERY);
- }
-
- if (type_obj == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 4);
- obj = fromjson(jsonstr);
- } else if (type_obj == LUA_TTABLE) {
- lua_to_bson(L, 4, obj);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
-
- connection->update(ns, query, obj, upsert, multi);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_UPDATE_FAILED, e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:drop_collection(ns)
- */
-static int connection_drop_collection(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- connection->dropCollection(ns);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_collection", e.what());
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:drop_index_by_fields(ns, json_str or lua_table)
- */
-static int connection_drop_index_by_fields(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- BSONObj keys;
-
- try {
- int type = lua_type(L, 3);
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 3);
- keys = fromjson(jsonstr);
- } else if (type == LUA_TTABLE) {
- lua_to_bson(L, 3, keys);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
-
- connection->dropIndex(ns, keys);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_fields", e.what());
- return 2;
- } catch (const char *err) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:drop_index_by_name(ns, index_name)
- */
-static int connection_drop_index_by_name(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- connection->dropIndex(ns, luaL_checkstring(L, 3));
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_name", e.what());
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * ok,err = db:drop_indexes(ns)
- */
-static int connection_drop_indexes(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- connection->dropIndexes(ns);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_indexes", e.what());
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * res,err = (dbname, jscode[, args_table])
- */
-static int connection_eval(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *dbname = luaL_checkstring(L, 2);
- const char *jscode = luaL_checkstring(L, 3);
-
- BSONObj info;
- BSONElement retval;
- BSONObj *args = NULL;
- if (!lua_isnoneornil(L, 4)) {
- try {
- int type = lua_type(L, 4);
-
- if (type == LUA_TSTRING) {
- args = new BSONObj(luaL_checkstring(L, 4));
- } else if (type == LUA_TTABLE) {
- BSONObj obj;
- lua_to_bson(L, 4, obj);
-
- args = new BSONObj(obj);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- } catch (std::exception &e) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", e.what());
- return 2;
- } catch (const char *err) {
- lua_pushnil(L);
- lua_pushstring(L, err);
- return 2;
- }
- }
-
- bool res = connection->eval(dbname, jscode, info, retval, args);
-
- if (!res) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", info["errmsg"].str().c_str());
-
- return 2;
- }
-
- if (args) {
- delete args;
- }
-
- lua_push_value(L, retval);
- return 1;
-}
-
-/*
- * bool = db:exists(ns)
- */
-static int connection_exists(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- bool res = connection->exists(ns);
-
- lua_pushboolean(L, res);
-
- return 1;
-}
-
-/*
- * name = db:gen_index_name(json_str or lua_table)
- */
-static int connection_gen_index_name(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
-
- string name = "";
-
- try {
- int type = lua_type(L, 2);
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 2);
- name = connection->genIndexName(fromjson(jsonstr));
- } else if (type == LUA_TTABLE) {
- BSONObj data;
- lua_to_bson(L, 2, data);
-
- name = connection->genIndexName(data);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- } catch (std::exception &e) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "gen_index_name", e.what());
- return 2;
- } catch (const char *err) {
- lua_pushnil(L);
- lua_pushstring(L, err);
- return 2;
- }
-
- lua_pushstring(L, name.c_str());
- return 1;
-}
-
-/*
- * cursor = db:get_indexes(ns)
- */
-static int connection_get_indexes(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- auto_ptr<DBClientCursor> autocursor = connection->getIndexes(ns);
-
- DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *));
- *cursor = autocursor.get();
- autocursor.release();
-
- luaL_getmetatable(L, LUAMONGO_CURSOR);
- lua_setmetatable(L, -2);
-
- return 1;
-}
-
-/*
- * res,err = db:mapreduce(jsmapfunc, jsreducefunc[, query[, output]])
- */
-static int connection_mapreduce(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
- const char *jsmapfunc = luaL_checkstring(L, 3);
- const char *jsreducefunc = luaL_checkstring(L, 4);
-
- BSONObj query;
- if (!lua_isnoneornil(L, 5)) {
- try {
- int type = lua_type(L, 5);
- if (type == LUA_TSTRING) {
- const char *jsonstr = luaL_checkstring(L, 5);
- query = fromjson(jsonstr);
- } else if (type == LUA_TTABLE) {
- lua_to_bson(L, 5, query);
- } else {
- throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
- }
- } catch (std::exception &e) {
- lua_pushnil(L);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "mapreduce", e.what());
- return 2;
- } catch (const char *err) {
- lua_pushnil(L);
- lua_pushstring(L, err);
- return 2;
- }
- }
-
- const char *output = luaL_optstring(L, 6, "");
-
- BSONObj res = connection->mapreduce(ns, jsmapfunc, jsreducefunc, query, output);
-
- bson_to_lua(L, res);
-
- return 1;
-}
-
-/*
- * ok,err = db:reindex(ns);
- */
-static int connection_reindex(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
- const char *ns = luaL_checkstring(L, 2);
-
- try {
- connection->reIndex(ns);
- } catch (std::exception &e) {
- lua_pushboolean(L, 0);
- lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "reindex", e.what());
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-/*
- * db:reset_index_cache()
- */
-static int connection_reset_index_cache(lua_State *L) {
- DBClientConnection *connection = userdata_to_connection(L, 1);
-
- connection->resetIndexCache();
-
- return 0;
-}
/*
* __gc
@@ -744,35 +103,13 @@ static int connection_gc(lua_State *L) {
static int connection_tostring(lua_State *L) {
DBClientConnection *connection = userdata_to_connection(L, 1);
lua_pushfstring(L, "%s: %s", LUAMONGO_CONNECTION, connection->toString().c_str());
-
return 1;
}
int mongo_connection_register(lua_State *L) {
static const luaL_Reg connection_methods[] = {
- {"auth", connection_auth},
{"connect", connection_connect},
- {"count", connection_count},
- {"drop_collection", connection_drop_collection},
- {"drop_index_by_fields", connection_drop_index_by_fields},
- {"drop_index_by_name", connection_drop_index_by_name},
- {"drop_indexes", connection_drop_indexes},
- {"ensure_index", connection_ensure_index},
- {"eval", connection_eval},
- {"exists", connection_exists},
- {"gen_index_name", connection_gen_index_name},
- {"get_indexes", connection_get_indexes},
- {"get_server_address", connection_get_server_address},
- {"insert", connection_insert},
- {"insert_batch", connection_insert_batch},
- {"is_failed", connection_is_failed},
- {"mapreduce", connection_mapreduce},
- {"query", connection_query},
- {"reindex", connection_reindex},
- {"remove", connection_remove},
- {"reset_index_cache", connection_reset_index_cache},
- {"update", connection_update},
{NULL, NULL}
};
@@ -782,7 +119,8 @@ int mongo_connection_register(lua_State *L) {
};
luaL_newmetatable(L, LUAMONGO_CONNECTION);
- luaL_register(L, 0, connection_methods);
+ luaL_register(L, NULL, dbclient_methods);
+ luaL_register(L, NULL, connection_methods);
lua_pushvalue(L,-1);
lua_setfield(L, -2, "__index");
@@ -796,3 +134,4 @@ int mongo_connection_register(lua_State *L) {
return 1;
}
+
View
2  mongo_cursor.cpp
@@ -30,7 +30,7 @@ inline DBClientCursor* userdata_to_cursor(lua_State* L, int index) {
/*
* cursor,err = db:query(ns, query)
*/
-int cursor_create(lua_State *L, DBClientConnection *connection, const char *ns,
+int cursor_create(lua_State *L, DBClientBase *connection, const char *ns,
const Query &query, int nToReturn, int nToSkip,
const BSONObj *fieldsToReturn, int queryOptions, int batchSize) {
int resultcount = 1;
View
735 mongo_dbclient.cpp
@@ -0,0 +1,735 @@
+#include <client/dbclient.h>
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+
+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
+#include <compat-5.1.h>
+#endif
+};
+
+#include "utils.h"
+#include "common.h"
+
+using namespace mongo;
+
+extern int cursor_create(lua_State *L, DBClientBase *connection, const char *ns,
+ const Query &query, int nToReturn, int nToSkip,
+ const BSONObj *fieldsToReturn, int queryOptions, int batchSize);
+
+extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj);
+extern void bson_to_lua(lua_State *L, const BSONObj &obj);
+extern void lua_push_value(lua_State *L, const BSONElement &elem);
+
+
+DBClientBase* userdata_to_dbclient(lua_State *L, int stackpos)
+{
+ // adapted from http://www.lua.org/source/5.1/lauxlib.c.html#luaL_checkudata
+ void *ud = lua_touserdata(L, stackpos);
+ if (ud == NULL)
+ luaL_typerror(L, stackpos, "userdata");
+
+ // try Connection
+ lua_getfield(L, LUA_REGISTRYINDEX, LUAMONGO_CONNECTION);
+ if (lua_getmetatable(L, stackpos))
+ {
+ if (lua_rawequal(L, -1, -2))
+ {
+ DBClientConnection *connection = *((DBClientConnection **)ud);
+ lua_pop(L, 2);
+ return connection;
+ }
+ lua_pop(L, 2);
+ }
+ else
+ lua_pop(L, 1);
+
+ // try ReplicaSet
+ lua_getfield(L, LUA_REGISTRYINDEX, LUAMONGO_REPLICASET); // get correct metatable
+ if (lua_getmetatable(L, stackpos))
+ {
+ if (lua_rawequal(L, -1, -2))
+ {
+ DBClientReplicaSet *replicaset = *((DBClientReplicaSet **)ud);
+ lua_pop(L, 2); // remove both metatables
+ return replicaset;
+ }
+ lua_pop(L, 2);
+ }
+ else
+ lua_pop(L, 1);
+
+ luaL_typerror(L, stackpos, LUAMONGO_DBCLIENT);
+ return NULL; // should never get here
+}
+
+
+/***********************************************************************/
+// The following methods are common to all DBClients
+// (DBClientConnection and DBClientReplicaSet)
+/***********************************************************************/
+
+
+/*
+ * created = db:ensure_index(ns, json_str or lua_table[, unique[, name]])
+ */
+static int dbclient_ensure_index(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+ BSONObj fields;
+
+ try {
+ int type = lua_type(L, 3);
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 3);
+ fields = fromjson(jsonstr);
+ } else if (type == LUA_TTABLE) {
+ lua_to_bson(L, 3, fields);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "ensure_index", e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ bool unique = lua_toboolean(L, 4);
+ const char *name = luaL_optstring(L, 5, "");
+
+ bool res = dbclient->ensureIndex(ns, fields, unique, name);
+
+ lua_pushboolean(L, res);
+ return 1;
+}
+
+/*
+ * ok,err = db:auth({})
+ * accepts a table of parameters:
+ * dbname database to authenticate (required)
+ * username username to authenticate against (required)
+ * password password to authenticate against (required)
+ * digestPassword set to true if password is pre-digested (default = true)
+ *
+ */
+static int dbclient_auth(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_getfield(L, 2, "dbname");
+ const char *dbname = luaL_checkstring(L, -1);
+ lua_getfield(L, 2, "username");
+ const char *username = luaL_checkstring(L, -1);
+ lua_getfield(L, 2, "password");
+ const char *password = luaL_checkstring(L, -1);
+ lua_getfield(L, 2, "digestPassword");
+ bool digestPassword = lua_isnil(L, -1) ? true : lua_toboolean(L, -1);
+ lua_pop(L, 4);
+
+ std::string errmsg;
+ bool success = dbclient->auth(dbname, username, password, errmsg, digestPassword);
+ if (!success) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, errmsg.c_str());
+ return 2;
+ }
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * is_failed = db:is_failed()
+ */
+static int dbclient_is_failed(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+
+ bool is_failed = dbclient->isFailed();
+ lua_pushboolean(L, is_failed);
+ return 1;
+}
+
+/*
+ * addr = db:get_server_address()
+ */
+static int dbclient_get_server_address(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+
+ std::string address = dbclient->getServerAddress();
+ lua_pushstring(L, address.c_str());
+ return 1;
+}
+
+/*
+ * count,err = db:count(ns)
+ */
+static int dbclient_count(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ int count = 0;
+ try {
+ count = dbclient->count(ns);
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_COUNT_FAILED, e.what());
+ return 2;
+ }
+
+ lua_pushinteger(L, count);
+ return 1;
+}
+
+/*
+ * ok,err = db:insert(ns, lua_table or json_str)
+ */
+static int dbclient_insert(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ int type = lua_type(L, 3);
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 3);
+ dbclient->insert(ns, fromjson(jsonstr));
+ } else if (type == LUA_TTABLE) {
+ BSONObj data;
+ lua_to_bson(L, 3, data);
+
+ dbclient->insert(ns, data);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:insert_batch(ns, lua_array_of_tables)
+ */
+static int dbclient_insert_batch(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+ luaL_checktype(L, 3, LUA_TTABLE);
+
+ try {
+ std::vector<BSONObj> vdata;
+ size_t tlen = lua_objlen(L, 3) + 1;
+ for (size_t i = 1; i < tlen; ++i) {
+ vdata.push_back(BSONObj());
+ lua_rawgeti(L, 3, i);
+ lua_to_bson(L, 4, vdata.back());
+ lua_pop(L, 1);
+ }
+ dbclient->insert(ns, vdata);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * cursor,err = db:query(ns, lua_table or json_str or query_obj, limit, skip, lua_table or json_str, options, batchsize)
+ */
+static int dbclient_query(lua_State *L) {
+ int n = lua_gettop(L);
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ Query query;
+ if (!lua_isnoneornil(L, 3)) {
+ try {
+ int type = lua_type(L, 3);
+ if (type == LUA_TSTRING) {
+ query = fromjson(luaL_checkstring(L, 3));
+ } else if (type == LUA_TTABLE) {
+ BSONObj obj;
+ lua_to_bson(L, 3, obj);
+ query = obj;
+ } else if (type == LUA_TUSERDATA) {
+ void *uq = 0;
+
+ uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
+ query = *(*((Query **)uq));
+ } else {
+ throw(LUAMONGO_REQUIRES_QUERY);
+ }
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_QUERY_FAILED, e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushnil(L);
+ lua_pushstring(L, err);
+ return 2;
+ }
+ }
+
+ int nToReturn = luaL_optint(L, 4, 0);
+ int nToSkip = luaL_optint(L, 5, 0);
+
+ const BSONObj *fieldsToReturn = NULL;
+ if (!lua_isnoneornil(L, 6)) {
+ fieldsToReturn = new BSONObj();
+
+ int type = lua_type(L, 6);
+
+ if (type == LUA_TSTRING) {
+ fieldsToReturn = new BSONObj(luaL_checkstring(L, 6));
+ } else if (type == LUA_TTABLE) {
+ BSONObj obj;
+ lua_to_bson(L, 6, obj);
+ fieldsToReturn = new BSONObj(obj);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ }
+
+ int queryOptions = luaL_optint(L, 7, 0);
+ int batchSize = luaL_optint(L, 8, 0);
+
+ int res = cursor_create(L, dbclient, ns, query, nToReturn, nToSkip,
+ fieldsToReturn, queryOptions, batchSize);
+
+ if (fieldsToReturn) {
+ delete fieldsToReturn;
+ }
+
+ return res;
+}
+
+/*
+ * ok,err = db:remove(ns, lua_table or json_str or query_obj)
+ */
+static int dbclient_remove(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ int type = lua_type(L, 3);
+ bool justOne = lua_toboolean(L, 4);
+
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 3);
+ dbclient->remove(ns, fromjson(jsonstr), justOne);
+ } else if (type == LUA_TTABLE) {
+ BSONObj data;
+ lua_to_bson(L, 3, data);
+
+ dbclient->remove(ns, data, justOne);
+ } else if (type == LUA_TUSERDATA) {
+ Query query;
+ void *uq = 0;
+
+ uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
+ query = *(*((Query **)uq));
+
+ dbclient->remove(ns, query, justOne);
+ } else {
+ throw(LUAMONGO_REQUIRES_QUERY);
+ }
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_REMOVE_FAILED, e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:update(ns, lua_table or json_str or query_obj, lua_table or json_str, upsert, multi)
+ */
+static int dbclient_update(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ int type_query = lua_type(L, 3);
+ int type_obj = lua_type(L, 4);
+
+ bool upsert = lua_toboolean(L, 5);
+ bool multi = lua_toboolean(L, 6);
+
+ Query query;
+ BSONObj obj;
+
+ if (type_query == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 3);
+ query = fromjson(jsonstr);
+ } else if (type_query == LUA_TTABLE) {
+ BSONObj q;
+
+ lua_to_bson(L, 3, q);
+ query = q;
+ } else if (type_query == LUA_TUSERDATA) {
+ void *uq = 0;
+
+ uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
+ query = *(*((Query **)uq));
+ } else {
+ throw(LUAMONGO_REQUIRES_QUERY);
+ }
+
+ if (type_obj == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 4);
+ obj = fromjson(jsonstr);
+ } else if (type_obj == LUA_TTABLE) {
+ lua_to_bson(L, 4, obj);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+
+ dbclient->update(ns, query, obj, upsert, multi);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_UPDATE_FAILED, e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:drop_collection(ns)
+ */
+static int dbclient_drop_collection(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ dbclient->dropCollection(ns);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_collection", e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:drop_index_by_fields(ns, json_str or lua_table)
+ */
+static int dbclient_drop_index_by_fields(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ BSONObj keys;
+
+ try {
+ int type = lua_type(L, 3);
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 3);
+ keys = fromjson(jsonstr);
+ } else if (type == LUA_TTABLE) {
+ lua_to_bson(L, 3, keys);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+
+ dbclient->dropIndex(ns, keys);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_fields", e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:drop_index_by_name(ns, index_name)
+ */
+static int dbclient_drop_index_by_name(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ dbclient->dropIndex(ns, luaL_checkstring(L, 3));
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_name", e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * ok,err = db:drop_indexes(ns)
+ */
+static int dbclient_drop_indexes(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ dbclient->dropIndexes(ns);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_indexes", e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * res,err = (dbname, jscode[, args_table])
+ */
+static int dbclient_eval(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *dbname = luaL_checkstring(L, 2);
+ const char *jscode = luaL_checkstring(L, 3);
+
+ BSONObj info;
+ BSONElement retval;
+ BSONObj *args = NULL;
+ if (!lua_isnoneornil(L, 4)) {
+ try {
+ int type = lua_type(L, 4);
+
+ if (type == LUA_TSTRING) {
+ args = new BSONObj(luaL_checkstring(L, 4));
+ } else if (type == LUA_TTABLE) {
+ BSONObj obj;
+ lua_to_bson(L, 4, obj);
+
+ args = new BSONObj(obj);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushnil(L);
+ lua_pushstring(L, err);
+ return 2;
+ }
+ }
+
+ bool res = dbclient->eval(dbname, jscode, info, retval, args);
+
+ if (!res) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", info["errmsg"].str().c_str());
+
+ return 2;
+ }
+
+ if (args) {
+ delete args;
+ }
+
+ lua_push_value(L, retval);
+ return 1;
+}
+
+/*
+ * bool = db:exists(ns)
+ */
+static int dbclient_exists(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ bool res = dbclient->exists(ns);
+
+ lua_pushboolean(L, res);
+
+ return 1;
+}
+
+/*
+ * name = db:gen_index_name(json_str or lua_table)
+ */
+static int dbclient_gen_index_name(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+
+ string name = "";
+
+ try {
+ int type = lua_type(L, 2);
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 2);
+ name = dbclient->genIndexName(fromjson(jsonstr));
+ } else if (type == LUA_TTABLE) {
+ BSONObj data;
+ lua_to_bson(L, 2, data);
+
+ name = dbclient->genIndexName(data);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "gen_index_name", e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushnil(L);
+ lua_pushstring(L, err);
+ return 2;
+ }
+
+ lua_pushstring(L, name.c_str());
+ return 1;
+}
+
+/*
+ * cursor = db:get_indexes(ns)
+ */
+static int dbclient_get_indexes(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ auto_ptr<DBClientCursor> autocursor = dbclient->getIndexes(ns);
+
+ DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *));
+ *cursor = autocursor.get();
+ autocursor.release();
+
+ luaL_getmetatable(L, LUAMONGO_CURSOR);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+/*
+ * res,err = db:mapreduce(jsmapfunc, jsreducefunc[, query[, output]])
+ */
+static int dbclient_mapreduce(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+ const char *jsmapfunc = luaL_checkstring(L, 3);
+ const char *jsreducefunc = luaL_checkstring(L, 4);
+
+ BSONObj query;
+ if (!lua_isnoneornil(L, 5)) {
+ try {
+ int type = lua_type(L, 5);
+ if (type == LUA_TSTRING) {
+ const char *jsonstr = luaL_checkstring(L, 5);
+ query = fromjson(jsonstr);
+ } else if (type == LUA_TTABLE) {
+ lua_to_bson(L, 5, query);
+ } else {
+ throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
+ }
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "mapreduce", e.what());
+ return 2;
+ } catch (const char *err) {
+ lua_pushnil(L);
+ lua_pushstring(L, err);
+ return 2;
+ }
+ }
+
+ const char *output = luaL_optstring(L, 6, "");
+
+ BSONObj res = dbclient->mapreduce(ns, jsmapfunc, jsreducefunc, query, output);
+
+ bson_to_lua(L, res);
+
+ return 1;
+}
+
+/*
+ * ok,err = db:reindex(ns);
+ */
+static int dbclient_reindex(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+ const char *ns = luaL_checkstring(L, 2);
+
+ try {
+ dbclient->reIndex(ns);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "reindex", e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * db:reset_index_cache()
+ */
+static int dbclient_reset_index_cache(lua_State *L) {
+ DBClientBase *dbclient = userdata_to_dbclient(L, 1);
+
+ dbclient->resetIndexCache();
+
+ return 0;
+}
+
+// Method registration table for DBClients
+extern const luaL_Reg dbclient_methods[] = {
+ {"auth", dbclient_auth},
+ {"count", dbclient_count},
+ {"drop_collection", dbclient_drop_collection},
+ {"drop_index_by_fields", dbclient_drop_index_by_fields},
+ {"drop_index_by_name", dbclient_drop_index_by_name},
+ {"drop_indexes", dbclient_drop_indexes},
+ {"ensure_index", dbclient_ensure_index},
+ {"eval", dbclient_eval},
+ {"exists", dbclient_exists},
+ {"gen_index_name", dbclient_gen_index_name},
+ {"get_indexes", dbclient_get_indexes},
+ {"get_server_address", dbclient_get_server_address},
+ {"insert", dbclient_insert},
+ {"insert_batch", dbclient_insert_batch},
+ {"is_failed", dbclient_is_failed},
+ {"mapreduce", dbclient_mapreduce},
+ {"query", dbclient_query},
+ {"reindex", dbclient_reindex},
+ {"remove", dbclient_remove},
+ {"reset_index_cache", dbclient_reset_index_cache},
+ {"update", dbclient_update},
+ {NULL, NULL}
+};
+
+
View
9 mongo_gridfs.cpp
@@ -20,6 +20,7 @@ using namespace mongo;
extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj);
extern void bson_to_lua(lua_State *L, const BSONObj &obj);
extern int gridfile_create(lua_State *L, GridFile gf);
+extern DBClientBase* userdata_to_dbclient(lua_State *L, int stackpos);
namespace {
inline GridFS* userdata_to_gridfs(lua_State* L, int index) {
@@ -30,7 +31,7 @@ namespace {
return gridfs;
}
-}
+} // anonymous namespace
/*
* gridfs, err = mongo.GridFS.New(connection, dbname[, prefix])
@@ -40,11 +41,7 @@ static int gridfs_new(lua_State *L) {
int resultcount = 1;
try {
- void *ud = 0;
-
- ud = luaL_checkudata(L, 1, LUAMONGO_CONNECTION);
- DBClientConnection *connection = *((DBClientConnection **)ud);
-
+ DBClientBase *connection = userdata_to_dbclient(L, 1);
const char *dbname = lua_tostring(L, 2);
GridFS **gridfs = (GridFS **)lua_newuserdata(L, sizeof(GridFS *));
View
132 mongo_replicaset.cpp
@@ -0,0 +1,132 @@
+#include <client/dbclient.h>
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
+#include <compat-5.1.h>
+#endif
+};
+
+#include "common.h"
+
+using namespace mongo;
+
+extern const luaL_Reg dbclient_methods[];
+
+namespace {
+inline DBClientReplicaSet* userdata_to_replicaset(lua_State* L, int index) {
+ void *ud = luaL_checkudata(L, index, LUAMONGO_REPLICASET);
+ DBClientReplicaSet *replicaset = *((DBClientReplicaSet **)ud);
+ return replicaset;
+}
+
+} // anonymous namespace
+
+
+/*
+ * db,err = mongo.ReplicaSet.New(name, {hostAndPort1, ...)
+ */
+static int replicaset_new(lua_State *L) {
+ luaL_checktype(L, 1, LUA_TSTRING);
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ int resultcount = 1;
+ try {
+ const char *rs_name = luaL_checkstring(L, 1);
+
+ std::vector<mongo::HostAndPort> rs_servers;
+ int i = 1;
+ while (1) {
+ lua_pushinteger(L, i++);
+ lua_gettable(L, 2);
+ const char* hostAndPort = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ if (!hostAndPort)
+ break;
+ HostAndPort hp(hostAndPort);
+ rs_servers.push_back(hp);
+ }
+
+ DBClientReplicaSet **replicaset = (DBClientReplicaSet **)lua_newuserdata(L, sizeof(DBClientReplicaSet *));
+ *replicaset = new DBClientReplicaSet(rs_name, rs_servers);
+
+ luaL_getmetatable(L, LUAMONGO_REPLICASET);
+ lua_setmetatable(L, -2);
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_REPLICASET_FAILED, e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+/*
+ * ok,err = replicaset:connect()
+ */
+static int replicaset_connect(lua_State *L) {
+ DBClientReplicaSet *replicaset = userdata_to_replicaset(L, 1);
+
+ try {
+ replicaset->connect();
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CONNECT_FAILED, LUAMONGO_REPLICASET, e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+
+/*
+ * __gc
+ */
+static int replicaset_gc(lua_State *L) {
+ DBClientReplicaSet *replicaset = userdata_to_replicaset(L, 1);
+ delete replicaset;
+ return 0;
+}
+
+/*
+ * __tostring
+ */
+static int replicaset_tostring(lua_State *L) {
+ DBClientReplicaSet *replicaset = userdata_to_replicaset(L, 1);
+ lua_pushfstring(L, "%s: %s", LUAMONGO_REPLICASET, replicaset->toString().c_str());
+ return 1;
+}
+
+
+int mongo_replicaset_register(lua_State *L) {
+ static const luaL_Reg replicaset_methods[] = {
+ {"connect", replicaset_connect},
+ {NULL, NULL}
+ };
+
+ static const luaL_Reg replicaset_class_methods[] = {
+ {"New", replicaset_new},
+ {NULL, NULL}
+ };
+
+ luaL_newmetatable(L, LUAMONGO_REPLICASET);
+ luaL_register(L, NULL, dbclient_methods);
+ luaL_register(L, NULL, replicaset_methods);
+ lua_pushvalue(L,-1);
+ lua_setfield(L, -2, "__index");
+
+ lua_pushcfunction(L, replicaset_gc);
+ lua_setfield(L, -2, "__gc");
+
+ lua_pushcfunction(L, replicaset_tostring);
+ lua_setfield(L, -2, "__tostring");
+
+ luaL_register(L, LUAMONGO_REPLICASET, replicaset_class_methods);
+
+ return 1;
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.