From b8e39be6d0817d63684b8e7a49ff6c22edb41519 Mon Sep 17 00:00:00 2001 From: Ezra Nuite Date: Mon, 4 Jun 2012 12:37:23 -0700 Subject: [PATCH 01/18] Add code that should query for girdfs files using arguments --- mongo_gridfs.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mongo_gridfs.cpp b/mongo_gridfs.cpp index 177d037..d18dafc 100644 --- a/mongo_gridfs.cpp +++ b/mongo_gridfs.cpp @@ -98,19 +98,23 @@ static int gridfs_find_file(lua_State *L) { } - - - - /* - * cursor,err = gridfs:list() + * cursor,err = gridfs:list([lua_table or json_str]) */ static int gridfs_list(lua_State *L) { GridFS *gridfs = userdata_to_gridfs(L, 1); - auto_ptr autocursor = gridfs->list(); + BSONObj query; + int type = lua_type(L, 2); + if (type == LUA_TSTRING) { + const char *jsonstr = luaL_checkstring(L, 2); + query = fromjson(jsonstr); + } else if (type == LUA_TTABLE) { + lua_to_bson(L, 2, query); + } + auto_ptr autocursor = gridfs->list(query); - if (!autocursor.get()) { + if (!autocursor.get()){ lua_pushnil(L); lua_pushstring(L, LUAMONGO_ERR_CONNECTION_LOST); return 2; @@ -149,7 +153,7 @@ static int gridfs_remove_file(lua_State *L) { } /* - * gridfile, err = gridfs:store_file(filename[, remote_file], content_type]]) + * gridfile, err = gridfs:store_file(filename[, remote_file[, content_type]]) */ static int gridfs_store_file(lua_State *L) { int resultcount = 1; From c963648baa8bd79c532c23328c92d9c485124d39 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 10:47:35 +0200 Subject: [PATCH 02/18] Added gitignore --- .gitignore | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a1404d --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +gmon.out + +# Building files # +################## +*.o +*.so + +# Emacs backups # +################# +*~ +\#*\# +.\#* + +# Vim swap # +*.swp +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db From e5cf212d2271eaaaae11fd1b40ee2ce2e1a6e7b2 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 10:57:33 +0200 Subject: [PATCH 03/18] Updating for lua 5.2 --- Makefile | 4 ++-- common.h | 16 ++++++++-------- main.cpp | 25 +++++++++++++++++++++++-- mongo_bsontypes.cpp | 5 +++-- mongo_connection.cpp | 9 ++++++--- mongo_cursor.cpp | 6 ++++-- mongo_dbclient.cpp | 6 +++--- mongo_gridfile.cpp | 6 ++++-- mongo_gridfs.cpp | 8 +++++--- mongo_gridfschunk.cpp | 4 +++- mongo_query.cpp | 6 ++++-- mongo_replicaset.cpp | 11 +++++++---- utils.cpp | 8 ++++++++ utils.h | 14 ++++++++++++++ 14 files changed, 94 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 65454db..d2a010f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ CC= g++ -CFLAGS= -g -O2 -shared -fPIC -I /usr/include/lua5.1/ -I/usr/local/include/mongo/ +CFLAGS= -g -O2 -shared -fPIC -I/usr/include/mongo `pkg-config --cflags lua5.2` `pkg-config --cflags libmongo-client` AR= ar rcu RANLIB= ranlib RM= rm -f -LIBS=-lmongoclient -lboost_thread -lboost_filesystem +LIBS=`pkg-config --libs lua5.2` `pkg-config --libs libmongo-client` OUTLIB=mongo.so LDFLAGS= $(LIBS) diff --git a/common.h b/common.h index 8582cb1..852fa54 100644 --- a/common.h +++ b/common.h @@ -1,14 +1,14 @@ #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" +#define LUAMONGO_CONNECTION "Connection" +#define LUAMONGO_REPLICASET "ReplicaSet" +#define LUAMONGO_CURSOR "Cursor" +#define LUAMONGO_QUERY "Query" +#define LUAMONGO_GRIDFS "GridFS" +#define LUAMONGO_GRIDFILE "GridFile" +#define LUAMONGO_GRIDFSCHUNK "GridFSChunk" // not an actual class, pseudo-base for error messages -#define LUAMONGO_DBCLIENT "mongo.DBClient" +#define LUAMONGO_DBCLIENT "DBClient" #define LUAMONGO_ERR_CONNECTION_FAILED "Connection failed: %s" #define LUAMONGO_ERR_REPLICASET_FAILED "ReplicaSet.New failed: %s" diff --git a/main.cpp b/main.cpp index e98a51e..7a67d93 100644 --- a/main.cpp +++ b/main.cpp @@ -54,21 +54,42 @@ extern int mongo_gridfschunk_register(lua_State *L); extern "C" { LM_EXPORT int luaopen_mongo(lua_State *L) { + // bsontypes is the root table mongo_bsontypes_register(L); + + // LUAMONGO_CONNECTION mongo_connection_register(L); + lua_setfield(L, -2, LUAMONGO_CONNECTION); + + // LUAMONGO_REPLICASET mongo_replicaset_register(L); + lua_setfield(L, -2, LUAMONGO_REPLICASET); + + // LUAMONGO_CURSOR mongo_cursor_register(L); + lua_setfield(L, -2, LUAMONGO_CURSOR); + + // LUAMONGO_QUERY mongo_query_register(L); - + lua_setfield(L, -2, LUAMONGO_QUERY); + + // LUAMONGO_GRIDFS mongo_gridfs_register(L); + lua_setfield(L, -2, LUAMONGO_GRIDFS); + + // LUAMONGO_GRIDFILE mongo_gridfile_register(L); + lua_setfield(L, -2, LUAMONGO_GRIDFILE); + + // LUAMONGO_GRIDFSCHUNK mongo_gridfschunk_register(L); + lua_setfield(L, -2, LUAMONGO_GRIDFSCHUNK); /* * push the created table to the top of the stack * so "mongo = require('mongo')" works */ - lua_getglobal(L, LUAMONGO_ROOT); + // lua_getglobal(L, LUAMONGO_ROOT); return 1; } diff --git a/mongo_bsontypes.cpp b/mongo_bsontypes.cpp index 617eddc..bfc05ec 100644 --- a/mongo_bsontypes.cpp +++ b/mongo_bsontypes.cpp @@ -381,8 +381,9 @@ int mongo_bsontypes_register(lua_State *L) { {NULL, NULL} }; - luaL_register(L, LUAMONGO_ROOT, bsontype_methods); - + //luaL_register(L, LUAMONGO_ROOT, bsontype_methods); + luaL_newlib(L, bsontype_methods); + return 1; } diff --git a/mongo_connection.cpp b/mongo_connection.cpp index 1d60826..682c92d 100644 --- a/mongo_connection.cpp +++ b/mongo_connection.cpp @@ -115,8 +115,10 @@ int mongo_connection_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_CONNECTION); - luaL_register(L, NULL, dbclient_methods); - luaL_register(L, NULL, connection_methods); + //luaL_register(L, NULL, dbclient_methods); + luaL_setfuncs(L, dbclient_methods, 0); + //luaL_register(L, NULL, connection_methods); + luaL_setfuncs(L, connection_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -126,7 +128,8 @@ int mongo_connection_register(lua_State *L) { lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); - luaL_register(L, LUAMONGO_CONNECTION, connection_class_methods); + //luaL_register(L, LUAMONGO_CONNECTION, connection_class_methods); + luaL_newlib(L, connection_class_methods); return 1; } diff --git a/mongo_cursor.cpp b/mongo_cursor.cpp index e430088..0f3ea3f 100644 --- a/mongo_cursor.cpp +++ b/mongo_cursor.cpp @@ -192,7 +192,8 @@ int mongo_cursor_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_CURSOR); - luaL_register(L, 0, cursor_methods); + //luaL_register(L, 0, cursor_methods); + luaL_setfuncs(L, cursor_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -202,7 +203,8 @@ int mongo_cursor_register(lua_State *L) { lua_pushcfunction(L, cursor_tostring); lua_setfield(L, -2, "__tostring"); - luaL_register(L, LUAMONGO_CURSOR, cursor_class_methods); + //luaL_register(L, LUAMONGO_CURSOR, cursor_class_methods); + luaL_newlib(L, cursor_class_methods); return 1; } diff --git a/mongo_dbclient.cpp b/mongo_dbclient.cpp index b8548e1..8826059 100644 --- a/mongo_dbclient.cpp +++ b/mongo_dbclient.cpp @@ -28,7 +28,7 @@ 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"); + luaL_typeerror(L, stackpos, "userdata"); // try Connection lua_getfield(L, LUA_REGISTRYINDEX, LUAMONGO_CONNECTION); @@ -60,7 +60,7 @@ DBClientBase* userdata_to_dbclient(lua_State *L, int stackpos) else lua_pop(L, 1); - luaL_typerror(L, stackpos, LUAMONGO_DBCLIENT); + luaL_typeerror(L, stackpos, LUAMONGO_DBCLIENT); return NULL; // should never get here } @@ -236,7 +236,7 @@ static int dbclient_insert_batch(lua_State *L) { try { std::vector vdata; - size_t tlen = lua_objlen(L, 3) + 1; + size_t tlen = lua_rawlen(L, 3) + 1; for (size_t i = 1; i < tlen; ++i) { vdata.push_back(BSONObj()); lua_rawgeti(L, 3, i); diff --git a/mongo_gridfile.cpp b/mongo_gridfile.cpp index af54b85..d00152d 100644 --- a/mongo_gridfile.cpp +++ b/mongo_gridfile.cpp @@ -260,7 +260,8 @@ int mongo_gridfile_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_GRIDFILE); - luaL_register(L, 0, gridfile_methods); + //luaL_register(L, 0, gridfile_methods); + luaL_setfuncs(L, gridfile_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -273,7 +274,8 @@ int mongo_gridfile_register(lua_State *L) { lua_pushcfunction(L, gridfile_content_length); lua_setfield(L, -2, "__len"); - luaL_register(L, LUAMONGO_GRIDFILE, gridfile_class_methods); + //luaL_register(L, LUAMONGO_GRIDFILE, gridfile_class_methods); + luaL_newlib(L, gridfile_class_methods); return 1; } diff --git a/mongo_gridfs.cpp b/mongo_gridfs.cpp index 177d037..ad19d95 100644 --- a/mongo_gridfs.cpp +++ b/mongo_gridfs.cpp @@ -238,7 +238,8 @@ int mongo_gridfs_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_GRIDFS); - luaL_register(L, 0, gridfs_methods); + //luaL_register(L, 0, gridfs_methods); + luaL_setfuncs(L, gridfs_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -247,8 +248,9 @@ int mongo_gridfs_register(lua_State *L) { lua_pushcfunction(L, gridfs_tostring); lua_setfield(L, -2, "__tostring"); - - luaL_register(L, LUAMONGO_GRIDFS, gridfs_class_methods); + + //luaL_register(L, LUAMONGO_GRIDFS, gridfs_class_methods); + luaL_newlib(L, gridfs_class_methods); return 1; } diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index 527404f..1b450ff 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -87,7 +87,8 @@ int mongo_gridfschunk_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_GRIDFSCHUNK); - luaL_register(L, 0, gridfschunk_methods); + //luaL_register(L, 0, gridfschunk_methods); + luaL_setfuncs(L, gridfschunk_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -101,6 +102,7 @@ int mongo_gridfschunk_register(lua_State *L) { lua_setfield(L, -2, "__len"); //luaL_register(L, LUAMONGO_GRIDFSCHUNK, gridfschunk_class_methods); + //luaL_newlib(L, gridfschunk_class_methods); return 1; } diff --git a/mongo_query.cpp b/mongo_query.cpp index 21ab11b..00797f2 100644 --- a/mongo_query.cpp +++ b/mongo_query.cpp @@ -344,7 +344,8 @@ int mongo_query_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_QUERY); - luaL_register(L, 0, query_methods); + //luaL_register(L, 0, query_methods); + luaL_setfuncs(L, query_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -354,7 +355,8 @@ int mongo_query_register(lua_State *L) { lua_pushcfunction(L, query_tostring); lua_setfield(L, -2, "__tostring"); - luaL_register(L, LUAMONGO_QUERY, query_class_methods); + //luaL_register(L, LUAMONGO_QUERY, query_class_methods); + luaL_newlib(L, query_class_methods); lua_pushstring(L, "Options"); lua_newtable(L); diff --git a/mongo_replicaset.cpp b/mongo_replicaset.cpp index 923a0a1..c23bb38 100644 --- a/mongo_replicaset.cpp +++ b/mongo_replicaset.cpp @@ -114,8 +114,10 @@ int mongo_replicaset_register(lua_State *L) { }; luaL_newmetatable(L, LUAMONGO_REPLICASET); - luaL_register(L, NULL, dbclient_methods); - luaL_register(L, NULL, replicaset_methods); + //luaL_register(L, NULL, dbclient_methods); + luaL_setfuncs(L, dbclient_methods, 0); + //luaL_register(L, NULL, replicaset_methods); + luaL_setfuncs(L, replicaset_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -124,8 +126,9 @@ int mongo_replicaset_register(lua_State *L) { lua_pushcfunction(L, replicaset_tostring); lua_setfield(L, -2, "__tostring"); - - luaL_register(L, LUAMONGO_REPLICASET, replicaset_class_methods); + + //luaL_register(L, LUAMONGO_REPLICASET, replicaset_class_methods); + luaL_newlib(L, replicaset_class_methods); return 1; } diff --git a/utils.cpp b/utils.cpp index 375b222..252edf4 100644 --- a/utils.cpp +++ b/utils.cpp @@ -364,3 +364,11 @@ const char *bson_name(int type) { return name; } + +/* this was removed in Lua 5.2 */ +LUALIB_API int luaL_typeerror (lua_State *L, int narg, const char *tname) { + const char *msg; + msg = lua_pushfstring(L, "%s expected, got %s", + tname, lua_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} diff --git a/utils.h b/utils.h index a626d4a..6b6857e 100644 --- a/utils.h +++ b/utils.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014 Francisco Zamora-Martinez (pakozm@gmail.com) * Copyright (c) 2007-2009 Neil Richardson (nrich@iinet.net.au) * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,6 +30,19 @@ * */ +extern "C" { +#include +#include +#include + +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) +#include +#endif +}; + +/* this was removed in Lua 5.2 */ +LUALIB_API int luaL_typeerror (lua_State *L, int narg, const char *tname); + #define LUA_PUSH_ATTRIB_INT(n, v) \ lua_pushstring(L, n); \ lua_pushinteger(L, v); \ From bf518eb4c2a8a585f8b091613ff8edad98fa1f56 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 10:59:30 +0200 Subject: [PATCH 04/18] Minor problem with gridfschunk solved --- mongo_gridfschunk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index 1b450ff..e584fd7 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -88,7 +88,7 @@ int mongo_gridfschunk_register(lua_State *L) { luaL_newmetatable(L, LUAMONGO_GRIDFSCHUNK); //luaL_register(L, 0, gridfschunk_methods); - luaL_setfuncs(L, gridfschunk_methods, 0); + //luaL_setfuncs(L, gridfschunk_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -102,7 +102,7 @@ int mongo_gridfschunk_register(lua_State *L) { lua_setfield(L, -2, "__len"); //luaL_register(L, LUAMONGO_GRIDFSCHUNK, gridfschunk_class_methods); - //luaL_newlib(L, gridfschunk_class_methods); + luaL_newlib(L, gridfschunk_methods); return 1; } From 0937e1768281232a45c0529f34009c4e817ed00f Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 12:24:25 +0200 Subject: [PATCH 05/18] Making it work --- Makefile | 4 ++-- debian/control | 10 +++++----- debian/install | 2 +- main.cpp | 12 +----------- mongo_bsontypes.cpp | 16 +++++----------- mongo_connection.cpp | 12 +----------- mongo_cursor.cpp | 11 ----------- mongo_dbclient.cpp | 12 ++---------- mongo_gridfile.cpp | 11 ----------- mongo_gridfs.cpp | 11 ----------- mongo_gridfschunk.cpp | 11 ----------- mongo_query.cpp | 11 ----------- mongo_replicaset.cpp | 12 +----------- tests/connection.lua | 7 +++---- tests/lunity.lua | 5 +++-- tests/replicaset.lua | 7 +++---- utils.cpp | 11 ----------- utils.h | 6 ++++-- 18 files changed, 31 insertions(+), 140 deletions(-) diff --git a/Makefile b/Makefile index d2a010f..8b65933 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ CC= g++ -CFLAGS= -g -O2 -shared -fPIC -I/usr/include/mongo `pkg-config --cflags lua5.2` `pkg-config --cflags libmongo-client` +CFLAGS= -Wall -g -O2 -shared -fPIC -I/usr/include/mongo `pkg-config --cflags lua5.2` `pkg-config --cflags libmongo-client` AR= ar rcu RANLIB= ranlib RM= rm -f -LIBS=`pkg-config --libs lua5.2` `pkg-config --libs libmongo-client` +LIBS=`pkg-config --libs lua5.2` `pkg-config --libs libmongo-client` -lboost_thread -lboost_filesystem OUTLIB=mongo.so LDFLAGS= $(LIBS) diff --git a/debian/control b/debian/control index c139ea0..448855d 100644 --- a/debian/control +++ b/debian/control @@ -1,16 +1,16 @@ Source: luamongo Section: database Priority: optional -Maintainer: Evan Wies -Build-Depends: debhelper (>= 7.0.50), liblua5.1-0-dev, +Maintainer: Francisco Zamora-Martinez +Build-Depends: debhelper (>= 7.0.50), liblua5.2-dev, mongodb (>= 1.6) | mongodb-stable (>= 1.6) | mongodb-unstable (>= 1.6) | mongodb-snapshot (>= 1.6) | libmongoclient-dev (>= 1.6) | mongodb-dev (>= 1.6), libboost-thread-dev (>= 1.40), libboost-filesystem-dev (>= 1.40) Standards-Version: 3.8.4 -Homepage: http://code.google.com/p/luamongo/ +Homepage: https://github.com/pabloromeu/luamongo -Package: liblua5.1-mongo +Package: liblua5.2-mongo Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, lua5.1 +Depends: ${shlibs:Depends}, ${misc:Depends}, lua5.2 Description: Lua driver for MongoDB Lua (http://www.lua.org) driver for MongoDB (http://www.mongodb.org). diff --git a/debian/install b/debian/install index 45ababb..f5580d9 100644 --- a/debian/install +++ b/debian/install @@ -1 +1 @@ -mongo.so usr/lib/lua/5.1 \ No newline at end of file +mongo.so usr/lib/lua/5.2 \ No newline at end of file diff --git a/main.cpp b/main.cpp index 7a67d93..ee8081c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014 Francisco Zamora-Martinez (pakozm@gmail.com) * Copyright (c) 2009 Neil Richardson (nrich@iinet.net.au) * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -20,19 +21,8 @@ * IN THE SOFTWARE. */ -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include #include - #include "utils.h" #include "common.h" diff --git a/mongo_bsontypes.cpp b/mongo_bsontypes.cpp index bfc05ec..db931c0 100644 --- a/mongo_bsontypes.cpp +++ b/mongo_bsontypes.cpp @@ -1,16 +1,6 @@ #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - +#include "utils.h" #include "common.h" using namespace mongo; @@ -233,6 +223,8 @@ void push_bsontype_table(lua_State* L, mongo::BSONType bsontype) { case mongo::jstNULL: lua_pushcfunction(L, null_value); break; + default: + ; } lua_settable(L, -3); @@ -257,6 +249,8 @@ void push_bsontype_table(lua_State* L, mongo::BSONType bsontype) { case mongo::jstNULL: lua_pushcfunction(L, null_tostring); break; + default: + ; } lua_settable(L, -3); diff --git a/mongo_connection.cpp b/mongo_connection.cpp index 682c92d..9359438 100644 --- a/mongo_connection.cpp +++ b/mongo_connection.cpp @@ -1,15 +1,5 @@ #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - +#include "utils.h" #include "common.h" using namespace mongo; diff --git a/mongo_cursor.cpp b/mongo_cursor.cpp index 0f3ea3f..96b39a9 100644 --- a/mongo_cursor.cpp +++ b/mongo_cursor.cpp @@ -1,16 +1,5 @@ #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/mongo_dbclient.cpp b/mongo_dbclient.cpp index 8826059..fae41d0 100644 --- a/mongo_dbclient.cpp +++ b/mongo_dbclient.cpp @@ -1,14 +1,4 @@ #include - -extern "C" { -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" @@ -263,6 +253,7 @@ static int dbclient_insert_batch(lua_State *L) { */ static int dbclient_query(lua_State *L) { int n = lua_gettop(L); + UNUSED_VARIABLE(n); DBClientBase *dbclient = userdata_to_dbclient(L, 1); const char *ns = luaL_checkstring(L, 2); @@ -331,6 +322,7 @@ static int dbclient_query(lua_State *L) { */ static int dbclient_find_one(lua_State *L) { int n = lua_gettop(L); + UNUSED_VARIABLE(n); DBClientBase *dbclient = userdata_to_dbclient(L, 1); const char *ns = luaL_checkstring(L, 2); diff --git a/mongo_gridfile.cpp b/mongo_gridfile.cpp index d00152d..5f81968 100644 --- a/mongo_gridfile.cpp +++ b/mongo_gridfile.cpp @@ -1,17 +1,6 @@ #include #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/mongo_gridfs.cpp b/mongo_gridfs.cpp index ad19d95..61744ba 100644 --- a/mongo_gridfs.cpp +++ b/mongo_gridfs.cpp @@ -1,17 +1,6 @@ #include #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index e584fd7..dde2377 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -1,17 +1,6 @@ #include #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/mongo_query.cpp b/mongo_query.cpp index 00797f2..d3065e7 100644 --- a/mongo_query.cpp +++ b/mongo_query.cpp @@ -1,16 +1,5 @@ #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/mongo_replicaset.cpp b/mongo_replicaset.cpp index c23bb38..01573be 100644 --- a/mongo_replicaset.cpp +++ b/mongo_replicaset.cpp @@ -1,15 +1,5 @@ #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - +#include "utils.h" #include "common.h" using namespace mongo; diff --git a/tests/connection.lua b/tests/connection.lua index ffe44d9..70e9e6b 100755 --- a/tests/connection.lua +++ b/tests/connection.lua @@ -7,11 +7,10 @@ -- TEST_USER (nil, no auth will be done) -- TEST_PASS ('') -require 'mongo' -require 'os' +local mongo = require 'mongo' +local os = require 'os' -require 'tests/lunity' -module( 'LUAMONGO_TEST_CONNECTION', lunity ) +local lunity = require 'tests.lunity' function setup() test_server = os.getenv('TEST_SERVER') or 'localhost' diff --git a/tests/lunity.lua b/tests/lunity.lua index 3bc0248..3c1ba04 100644 --- a/tests/lunity.lua +++ b/tests/lunity.lua @@ -46,7 +46,6 @@ local setmetatable=setmetatable local _G=_G -module( 'lunity' ) VERSION = "0.9" @@ -363,4 +362,6 @@ function __runAllTests( testSuite, options ) end io.stdout:flush() -end \ No newline at end of file +end + +return lunity diff --git a/tests/replicaset.lua b/tests/replicaset.lua index 236104c..aa9d51d 100755 --- a/tests/replicaset.lua +++ b/tests/replicaset.lua @@ -7,11 +7,10 @@ -- TEST_USER (nil, no auth will be done) -- TEST_PASS ('') -require 'mongo' -require 'os' +local mongo = require 'mongo' +local os = require 'os' -require 'tests/lunity' -module( 'LUAMONGO_TEST_REPLICASET', lunity ) +local lunity = require 'tests.lunity' function setup() test_server = os.getenv('TEST_SERVER') or 'localhost' diff --git a/utils.cpp b/utils.cpp index 252edf4..2fef406 100644 --- a/utils.cpp +++ b/utils.cpp @@ -1,16 +1,5 @@ #include #include - -extern "C" { -#include -#include -#include - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include -#endif -}; - #include "utils.h" #include "common.h" diff --git a/utils.h b/utils.h index 6b6857e..0d47c25 100644 --- a/utils.h +++ b/utils.h @@ -35,11 +35,13 @@ extern "C" { #include #include -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 502) +#error "Needs Lua 5.2 or greater" #endif }; +#define UNUSED_VARIABLE(x) (void)(x) + /* this was removed in Lua 5.2 */ LUALIB_API int luaL_typeerror (lua_State *L, int narg, const char *tname); From 6edd58ec024ea7f3adc3965d518732080de3d5ee Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 12:30:37 +0200 Subject: [PATCH 06/18] Shared libraries problems solved --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8b65933..f1fdf9b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS= -Wall -g -O2 -shared -fPIC -I/usr/include/mongo `pkg-config --cflags lua AR= ar rcu RANLIB= ranlib RM= rm -f -LIBS=`pkg-config --libs lua5.2` `pkg-config --libs libmongo-client` -lboost_thread -lboost_filesystem +LIBS=`pkg-config --libs lua5.2` -lmongoclient -lssl -lboost_thread -lboost_filesystem OUTLIB=mongo.so LDFLAGS= $(LIBS) From 53b5af6ad9bc8ec2540ba5aef95494e8bdf2c2dc Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 13:13:35 +0200 Subject: [PATCH 07/18] It is working in linux --- mongo_connection.cpp | 4 +++- mongo_cursor.cpp | 4 +++- mongo_gridfile.cpp | 2 ++ mongo_gridfs.cpp | 2 ++ mongo_gridfschunk.cpp | 2 ++ mongo_query.cpp | 4 +++- mongo_replicaset.cpp | 2 ++ tests/connection.lua | 5 +++-- tests/lunity.lua | 4 +--- tests/replicaset.lua | 5 +++-- 10 files changed, 24 insertions(+), 10 deletions(-) diff --git a/mongo_connection.cpp b/mongo_connection.cpp index 9359438..4bfa82a 100644 --- a/mongo_connection.cpp +++ b/mongo_connection.cpp @@ -117,7 +117,9 @@ int mongo_connection_register(lua_State *L) { lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); - + + lua_pop(L,1); + //luaL_register(L, LUAMONGO_CONNECTION, connection_class_methods); luaL_newlib(L, connection_class_methods); diff --git a/mongo_cursor.cpp b/mongo_cursor.cpp index 96b39a9..c384f35 100644 --- a/mongo_cursor.cpp +++ b/mongo_cursor.cpp @@ -191,7 +191,9 @@ int mongo_cursor_register(lua_State *L) { lua_pushcfunction(L, cursor_tostring); lua_setfield(L, -2, "__tostring"); - + + lua_pop(L,1); + //luaL_register(L, LUAMONGO_CURSOR, cursor_class_methods); luaL_newlib(L, cursor_class_methods); diff --git a/mongo_gridfile.cpp b/mongo_gridfile.cpp index 5f81968..506444e 100644 --- a/mongo_gridfile.cpp +++ b/mongo_gridfile.cpp @@ -263,6 +263,8 @@ int mongo_gridfile_register(lua_State *L) { lua_pushcfunction(L, gridfile_content_length); lua_setfield(L, -2, "__len"); + lua_pop(L,1); + //luaL_register(L, LUAMONGO_GRIDFILE, gridfile_class_methods); luaL_newlib(L, gridfile_class_methods); diff --git a/mongo_gridfs.cpp b/mongo_gridfs.cpp index 61744ba..6319974 100644 --- a/mongo_gridfs.cpp +++ b/mongo_gridfs.cpp @@ -238,6 +238,8 @@ int mongo_gridfs_register(lua_State *L) { lua_pushcfunction(L, gridfs_tostring); lua_setfield(L, -2, "__tostring"); + lua_pop(L,1); + //luaL_register(L, LUAMONGO_GRIDFS, gridfs_class_methods); luaL_newlib(L, gridfs_class_methods); diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index dde2377..723897c 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -90,6 +90,8 @@ int mongo_gridfschunk_register(lua_State *L) { lua_pushcfunction(L, gridfschunk_len); lua_setfield(L, -2, "__len"); + lua_pop(L,1); + //luaL_register(L, LUAMONGO_GRIDFSCHUNK, gridfschunk_class_methods); luaL_newlib(L, gridfschunk_methods); diff --git a/mongo_query.cpp b/mongo_query.cpp index d3065e7..28c2650 100644 --- a/mongo_query.cpp +++ b/mongo_query.cpp @@ -343,7 +343,9 @@ int mongo_query_register(lua_State *L) { lua_pushcfunction(L, query_tostring); lua_setfield(L, -2, "__tostring"); - + + lua_pop(L,1); + //luaL_register(L, LUAMONGO_QUERY, query_class_methods); luaL_newlib(L, query_class_methods); diff --git a/mongo_replicaset.cpp b/mongo_replicaset.cpp index 01573be..28c9c56 100644 --- a/mongo_replicaset.cpp +++ b/mongo_replicaset.cpp @@ -117,6 +117,8 @@ int mongo_replicaset_register(lua_State *L) { lua_pushcfunction(L, replicaset_tostring); lua_setfield(L, -2, "__tostring"); + lua_pop(L,1); + //luaL_register(L, LUAMONGO_REPLICASET, replicaset_class_methods); luaL_newlib(L, replicaset_class_methods); diff --git a/tests/connection.lua b/tests/connection.lua index 70e9e6b..9733e9c 100755 --- a/tests/connection.lua +++ b/tests/connection.lua @@ -65,5 +65,6 @@ function test_ReplicaSet() assertEqual( result.b, data.b ) end - -runTests() +local t = {setup=setup, test=test_ReplicaSet, teardown=teardown} +lunity(t) +t.runTests() diff --git a/tests/lunity.lua b/tests/lunity.lua index 3c1ba04..de08a5c 100644 --- a/tests/lunity.lua +++ b/tests/lunity.lua @@ -47,9 +47,7 @@ local setmetatable=setmetatable local _G=_G -VERSION = "0.9" - -local lunity = _M +local lunity = { _VERSION = "0.9", _NAME="lunity" } setmetatable( lunity, { __index = _G, __call = function( self, testSuite ) diff --git a/tests/replicaset.lua b/tests/replicaset.lua index aa9d51d..5a7d99b 100755 --- a/tests/replicaset.lua +++ b/tests/replicaset.lua @@ -65,5 +65,6 @@ function test_ReplicaSet() assertEqual( result.b, data.b ) end - -runTests() +local t = {setup=setup, test=test_ReplicaSet, teardown=teardown} +lunity(t) +t.runTests() From 1e65efa26527f1be0909987ce91557b07aa438c0 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Tue, 8 Apr 2014 13:59:01 +0200 Subject: [PATCH 08/18] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5db59f..f994ea8 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ There is a Google Groups maili ## Example - require('mongo') + local mongo = require('mongo') -- Create a connection object local db = assert(mongo.Connection.New()) From c0a929f7d7416c36c1f308f3d9f8f5794dca9fae Mon Sep 17 00:00:00 2001 From: pakozm Date: Tue, 8 Apr 2014 14:23:48 +0200 Subject: [PATCH 09/18] Added makefiles for linux and macports --- Makefile | 48 ++++++++++++------------------------------- Makefile.linux | 52 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile.macports | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 35 deletions(-) create mode 100644 Makefile.linux create mode 100644 Makefile.macports diff --git a/Makefile b/Makefile index f1fdf9b..0052e33 100644 --- a/Makefile +++ b/Makefile @@ -10,43 +10,21 @@ LDFLAGS= $(LIBS) 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 +UNAME = `uname` +PLAT = DetectOS + +all: $(PLAT) + +DetectOS: + @make $(UNAME) + +Linux: + @make -f Makefile.linux + +Darwin: + @make -f Makefile.macports clean: $(RM) $(OBJS) $(OUTLIB) -luamongo: $(OBJS) - $(CC) $(CFLAGS) $(OBJS) -o $(OUTLIB) $(LDFLAGS) - -echo: - @echo "CC = $(CC)" - @echo "CFLAGS = $(CFLAGS)" - @echo "AR = $(AR)" - @echo "RANLIB = $(RANLIB)" - @echo "RM = $(RM)" - @echo "LDFLAGS = $(LDFLAGS)" - -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 - $(CC) -c -o $@ $< $(CFLAGS) -mongo_gridfile.o: mongo_gridfile.cpp common.h utils.h - $(CC) -c -o $@ $< $(CFLAGS) -mongo_gridfs.o: mongo_gridfs.cpp common.h utils.h - $(CC) -c -o $@ $< $(CFLAGS) -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 - $(CC) -c -o $@ $< $(CFLAGS) - .PHONY: all diff --git a/Makefile.linux b/Makefile.linux new file mode 100644 index 0000000..f1fdf9b --- /dev/null +++ b/Makefile.linux @@ -0,0 +1,52 @@ +CC= g++ +CFLAGS= -Wall -g -O2 -shared -fPIC -I/usr/include/mongo `pkg-config --cflags lua5.2` `pkg-config --cflags libmongo-client` +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS=`pkg-config --libs lua5.2` -lmongoclient -lssl -lboost_thread -lboost_filesystem +OUTLIB=mongo.so + +LDFLAGS= $(LIBS) + +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 + +clean: + $(RM) $(OBJS) $(OUTLIB) + +luamongo: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(OUTLIB) $(LDFLAGS) + +echo: + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "LDFLAGS = $(LDFLAGS)" + +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 + $(CC) -c -o $@ $< $(CFLAGS) +mongo_gridfile.o: mongo_gridfile.cpp common.h utils.h + $(CC) -c -o $@ $< $(CFLAGS) +mongo_gridfs.o: mongo_gridfs.cpp common.h utils.h + $(CC) -c -o $@ $< $(CFLAGS) +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 + $(CC) -c -o $@ $< $(CFLAGS) + +.PHONY: all diff --git a/Makefile.macports b/Makefile.macports new file mode 100644 index 0000000..508124b --- /dev/null +++ b/Makefile.macports @@ -0,0 +1,52 @@ +CC= g++ +CFLAGS= -Wall -g -O2 -fPIC `pkg-config --cflags "lua >= 5.2"` -I/opt/local/include/mongo/ +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS=`pkg-config --libs "lua >= 5.2"` -lmongoclient -lssl -lboost_thread-mt -lboost_filesystem-mt -flat_namespace -bundle -L/opt/local/lib -rdynamic +OUTLIB=mongo.so + +LDFLAGS= $(LIBS) + +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 + +clean: + $(RM) $(OBJS) $(OUTLIB) + +luamongo: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(OUTLIB) $(LDFLAGS) + +echo: + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "LDFLAGS = $(LDFLAGS)" + +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 + $(CC) -c -o $@ $< $(CFLAGS) +mongo_gridfile.o: mongo_gridfile.cpp common.h utils.h + $(CC) -c -o $@ $< $(CFLAGS) +mongo_gridfs.o: mongo_gridfs.cpp common.h utils.h + $(CC) -c -o $@ $< $(CFLAGS) +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 + $(CC) -c -o $@ $< $(CFLAGS) + +.PHONY: all From de40b3053631d7f80fc79685d453cd10992cda83 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Wed, 9 Apr 2014 10:38:43 +0200 Subject: [PATCH 10/18] Making work mapreduce --- mongo_dbclient.cpp | 109 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 19 deletions(-) diff --git a/mongo_dbclient.cpp b/mongo_dbclient.cpp index fae41d0..acc9a63 100644 --- a/mongo_dbclient.cpp +++ b/mongo_dbclient.cpp @@ -81,7 +81,8 @@ static int dbclient_ensure_index(lua_State *L) { } } catch (std::exception &e) { lua_pushboolean(L, 0); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "ensure_index", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "ensure_index", e.what()); return 2; } catch (const char *err) { lua_pushboolean(L, 0); @@ -119,10 +120,10 @@ static int dbclient_auth(lua_State *L) { 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); + lua_pop(L, 4); if (!success) { lua_pushnil(L); lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, errmsg.c_str()); @@ -501,7 +502,8 @@ static int dbclient_drop_collection(lua_State *L) { dbclient->dropCollection(ns); } catch (std::exception &e) { lua_pushboolean(L, 0); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_collection", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "drop_collection", e.what()); return 2; } @@ -532,7 +534,8 @@ static int dbclient_drop_index_by_fields(lua_State *L) { 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()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "drop_index_by_fields", e.what()); return 2; } catch (const char *err) { lua_pushboolean(L, 0); @@ -555,7 +558,8 @@ static int dbclient_drop_index_by_name(lua_State *L) { 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()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "drop_index_by_name", e.what()); return 2; } @@ -574,7 +578,8 @@ static int dbclient_drop_indexes(lua_State *L) { dbclient->dropIndexes(ns); } catch (std::exception &e) { lua_pushboolean(L, 0); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_indexes", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "drop_indexes", e.what()); return 2; } @@ -609,7 +614,8 @@ static int dbclient_eval(lua_State *L) { } } catch (std::exception &e) { lua_pushnil(L); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "eval", e.what()); return 2; } catch (const char *err) { lua_pushnil(L); @@ -622,7 +628,8 @@ static int dbclient_eval(lua_State *L) { if (!res) { lua_pushboolean(L, 0); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", info["errmsg"].str().c_str()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", + info["errmsg"].str().c_str()); return 2; } @@ -672,7 +679,8 @@ static int dbclient_gen_index_name(lua_State *L) { } } catch (std::exception &e) { lua_pushnil(L); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "gen_index_name", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "gen_index_name", e.what()); return 2; } catch (const char *err) { lua_pushnil(L); @@ -699,7 +707,8 @@ static int dbclient_get_indexes(lua_State *L) { return 2; } - DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *)); + DBClientCursor **cursor = + (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *)); *cursor = autocursor.get(); autocursor.release(); @@ -710,14 +719,16 @@ static int dbclient_get_indexes(lua_State *L) { } /* - * res,err = db:mapreduce(jsmapfunc, jsreducefunc[, query[, output]]) + * res,err = db:mapreduce(ns, 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); - + const char *output = NULL; + if (!lua_isnoneornil(L, 6)) output = luaL_checkstring(L, 6); + BSONObj query; if (!lua_isnoneornil(L, 5)) { try { @@ -732,7 +743,8 @@ static int dbclient_mapreduce(lua_State *L) { } } catch (std::exception &e) { lua_pushnil(L); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "mapreduce", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "mapreduce", e.what()); return 2; } catch (const char *err) { lua_pushnil(L); @@ -740,10 +752,12 @@ static int dbclient_mapreduce(lua_State *L) { return 2; } } - - const char *output = luaL_optstring(L, 6, ""); - - BSONObj res = dbclient->mapreduce(ns, jsmapfunc, jsreducefunc, query, output); + + BSONObj res; + if (output == NULL) + res = dbclient->mapreduce(ns, jsmapfunc, jsreducefunc, query); + else + res = dbclient->mapreduce(ns, jsmapfunc, jsreducefunc, query, output); bson_to_lua(L, res); @@ -761,7 +775,8 @@ static int dbclient_reindex(lua_State *L) { dbclient->reIndex(ns); } catch (std::exception &e) { lua_pushboolean(L, 0); - lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "reindex", e.what()); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "reindex", e.what()); return 2; } @@ -841,6 +856,60 @@ static int dbclient_run_command(lua_State *L) { } } +/* + * res,err = db:get_dbnames() + */ +static int dbclient_get_dbnames(lua_State *L) { + DBClientBase *dbclient = userdata_to_dbclient(L, 1); + try { + list dbs = dbclient->getDatabaseNames(); + lua_newtable(L); + int i=1; + for (list::iterator it=dbs.begin(); it!=dbs.end(); ++it, ++i) { + lua_pushnumber(L,i); + lua_pushstring(L,it->c_str()); + lua_settable(L,-3); + } + return 1; + } catch (std::exception &e) { + lua_pushboolean(L, 0); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "get_dbnames", e.what()); + return 2; + } catch (const char *err) { + lua_pushboolean(L, 0); + lua_pushstring(L, err); + return 2; + } +} + +/* + * res,err = db:get_collections() + */ +static int dbclient_get_collections(lua_State *L) { + DBClientBase *dbclient = userdata_to_dbclient(L, 1); + const char *ns = luaL_checkstring(L, 2); + try { + list dbs = dbclient->getCollectionNames(ns); + lua_newtable(L); + int i=1; + for (list::iterator it=dbs.begin(); it!=dbs.end(); ++it, ++i) { + lua_pushnumber(L,i); + lua_pushstring(L,it->c_str()); + lua_settable(L,-3); + } + return 1; + } catch (std::exception &e) { + lua_pushboolean(L, 0); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, + "get_collections", e.what()); + return 2; + } catch (const char *err) { + lua_pushboolean(L, 0); + lua_pushstring(L, err); + return 2; + } +} // Method registration table for DBClients extern const luaL_Reg dbclient_methods[] = { @@ -869,6 +938,8 @@ extern const luaL_Reg dbclient_methods[] = { {"reset_index_cache", dbclient_reset_index_cache}, {"run_command", dbclient_run_command}, {"update", dbclient_update}, + {"get_dbnames", dbclient_get_dbnames}, + {"get_collections", dbclient_get_collections}, {NULL, NULL} }; From b97e1848515bfe25e150deec9c3493762a2688dd Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Thu, 1 May 2014 18:34:54 +0200 Subject: [PATCH 11/18] Added gridfschunk methods --- mongo_gridfschunk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index 723897c..a34539d 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -74,10 +74,10 @@ int mongo_gridfschunk_register(lua_State *L) { {"len", gridfschunk_len}, {NULL, NULL} }; - + luaL_newmetatable(L, LUAMONGO_GRIDFSCHUNK); //luaL_register(L, 0, gridfschunk_methods); - //luaL_setfuncs(L, gridfschunk_methods, 0); + luaL_setfuncs(L, gridfschunk_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); From 0d21a119d206a5db637bedd4223d9399f5599448 Mon Sep 17 00:00:00 2001 From: Francisco Zamora-Martinez Date: Fri, 2 May 2014 19:19:18 +0200 Subject: [PATCH 12/18] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f994ea8..a4e9db9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ ## Support -Submit issues to the moai github site. +Submit issues to the pakozm github site. There is a Google Groups mailing list. @@ -54,11 +54,11 @@ There is a Google Groups maili ## How It Works -luamongo is a Lua library that wraps the mongodb C++ API. +luamongo is a Lua library that wraps the mongodb C++ API. -The current implementation does not give you raw access to the BSON objects. BSON objects are passed to the API using a Lua table or a JSON string representation. Every returned BSON document is fully marshalled to a Lua table. +The current implementation does not give you raw access to the BSON objects. BSON objects are passed to the API using a Lua table or a JSON string representation. Every returned BSON document is fully marshalled to a Lua table. ## History -This project was forked from the luamongo project on googlecode. +This project was forked from the luamongo project on GitHub. From 09f42c87013f1d5c0be244f1bce036a9eeb344be Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Sun, 4 May 2014 14:32:07 +0200 Subject: [PATCH 13/18] Added gridfile builder, which allow stream like append of data --- Makefile | 6 +- common.h | 17 ++-- main.cpp | 5 ++ mongo_cxx_extension.cpp | 169 ++++++++++++++++++++++++++++++++++++++ mongo_cxx_extension.h | 73 ++++++++++++++++ mongo_gridfilebuilder.cpp | 157 +++++++++++++++++++++++++++++++++++ mongo_gridfs.cpp | 8 +- mongo_gridfschunk.cpp | 8 +- 8 files changed, 429 insertions(+), 14 deletions(-) create mode 100644 mongo_cxx_extension.cpp create mode 100644 mongo_cxx_extension.h create mode 100644 mongo_gridfilebuilder.cpp diff --git a/Makefile b/Makefile index f1fdf9b..284e3db 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ OUTLIB=mongo.so LDFLAGS= $(LIBS) -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 +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 mongo_cxx_extension.o mongo_gridfilebuilder.o all: luamongo @@ -48,5 +48,9 @@ mongo_bsontypes.o: mongo_bsontypes.cpp common.h $(CC) -c -o $@ $< $(CFLAGS) utils.o: utils.cpp common.h utils.h $(CC) -c -o $@ $< $(CFLAGS) +mongo_cxx_extension.o: mongo_cxx_extension.cpp mongo_cxx_extension.h + $(CC) -c -o $@ $< $(CFLAGS) +mongo_gridfilebuilder.o: mongo_gridfilebuilder.cpp mongo_cxx_extension.h common.h utils.h + $(CC) -c -o $@ $< $(CFLAGS) .PHONY: all diff --git a/common.h b/common.h index 852fa54..9800ba6 100644 --- a/common.h +++ b/common.h @@ -1,11 +1,12 @@ -#define LUAMONGO_ROOT "mongo" -#define LUAMONGO_CONNECTION "Connection" -#define LUAMONGO_REPLICASET "ReplicaSet" -#define LUAMONGO_CURSOR "Cursor" -#define LUAMONGO_QUERY "Query" -#define LUAMONGO_GRIDFS "GridFS" -#define LUAMONGO_GRIDFILE "GridFile" -#define LUAMONGO_GRIDFSCHUNK "GridFSChunk" +#define LUAMONGO_ROOT "mongo" +#define LUAMONGO_CONNECTION "Connection" +#define LUAMONGO_REPLICASET "ReplicaSet" +#define LUAMONGO_CURSOR "Cursor" +#define LUAMONGO_QUERY "Query" +#define LUAMONGO_GRIDFS "GridFS" +#define LUAMONGO_GRIDFILE "GridFile" +#define LUAMONGO_GRIDFSCHUNK "GridFSChunk" +#define LUAMONGO_GRIDFILEBUILDER "GridFileBuilder" // not an actual class, pseudo-base for error messages #define LUAMONGO_DBCLIENT "DBClient" diff --git a/main.cpp b/main.cpp index ee8081c..9ed93b1 100644 --- a/main.cpp +++ b/main.cpp @@ -34,6 +34,7 @@ extern int mongo_query_register(lua_State *L); extern int mongo_gridfs_register(lua_State *L); extern int mongo_gridfile_register(lua_State *L); extern int mongo_gridfschunk_register(lua_State *L); +extern int mongo_gridfilebuilder_register(lua_State *L); /* * @@ -75,6 +76,10 @@ LM_EXPORT int luaopen_mongo(lua_State *L) { mongo_gridfschunk_register(L); lua_setfield(L, -2, LUAMONGO_GRIDFSCHUNK); + // LUAMONGO_GRIDFILEBUILDER + mongo_gridfilebuilder_register(L); + lua_setfield(L, -2, LUAMONGO_GRIDFILEBUILDER); + /* * push the created table to the top of the stack * so "mongo = require('mongo')" works diff --git a/mongo_cxx_extension.cpp b/mongo_cxx_extension.cpp new file mode 100644 index 0000000..40f5c63 --- /dev/null +++ b/mongo_cxx_extension.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2014 Francisco Zamora-Martinez (pakozm@gmail.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "mongo_cxx_extension.h" + +namespace mongo { + + using std::ios; + using std::ofstream; + using std::ostream; + using std::string; + using std::min; + + GridFileBuilder::GridFileBuilder(DBClientBase *client, + const string &dbName, + unsigned int chunkSize, + const string& prefix) : + _client(client), _dbName(dbName), _prefix(prefix), _chunkSize(chunkSize), + _current_chunk(0), _pending_data(NULL), _pending_data_size(0), + _file_length(0) { + _chunkNS = _dbName + "." + _prefix + ".chunks"; + _filesNS = _dbName + "." + _prefix + ".files"; + OID id; + id.init(); + _file_id = BSON("_id" << id); + // forces to build the gridFS collections + GridFS aux(*client, dbName, prefix); + } + + GridFileBuilder::~GridFileBuilder() { + delete[] _pending_data; + } + + const char *GridFileBuilder::privateAppendChunk(const char *data, + size_t length, + bool pending_insert) { + size_t chunk_len; + char const * const end = data + length; + while (data < end) { + chunk_len = min(_chunkSize, (size_t)(end-data)); + // the last chunk needs to be stored as pending_data + if (chunk_len < _chunkSize && !pending_insert) break; + /* from gridfs.cpp at https://github.com/mongodb/mongo-cxx-driver/blob/legacy/src/mongo/client/gridfs.cpp */ + BSONObjBuilder b; + b.appendAs( _file_id["_id"] , "files_id" ); + b.append( "n" , _current_chunk ); + b.appendBinData( "data" , chunk_len, BinDataGeneral, data ); + BSONObj chunk_data = b.obj(); + /************************************************************************/ + ++_current_chunk; + _client->insert( _chunkNS.c_str(), chunk_data ); + data += chunk_len; + _file_length += chunk_len; + } + return data; + } + + void GridFileBuilder::privateAppendPendingData() { + if (_pending_data_size > 0) { + privateAppendChunk(_pending_data, _pending_data_size, true); + delete[] _pending_data; + _pending_data_size = 0; + _pending_data = NULL; + } + } + + void GridFileBuilder::appendChunk(const char *data, size_t length) { + if (length == 0 || _client == NULL) return; + // check if there are pending data + if (_pending_data != NULL) { + size_t total_size = _pending_data_size + length; + size_t size = min(_chunkSize, total_size) - _pending_data_size; + memcpy(_pending_data + _pending_data_size, data, size*sizeof(char)); + _pending_data_size += size; + // CHECK _pending_data_size <= _chunkSize + if (_pending_data_size == _chunkSize) { + privateAppendPendingData(); + appendChunk(data + size, length - size); + } + } + else { + char const * const end = data + length; + // split data in _chunkSize blocks, and store as pending the last block if + // necessary + data = privateAppendChunk(data, length); + // process pending data if necessary + if (data != end) { + if (_pending_data_size == 0) _pending_data = new char[_chunkSize]; + size_t size = (size_t)(end-data); + memcpy(_pending_data+_pending_data_size, data, size*sizeof(char)); + _pending_data_size += size; + } + } + } + + BSONObj GridFileBuilder::buildFile(const string &name, + const string& content_type) { + if (_client == NULL) return BSONObj(); + privateAppendPendingData(); + + /* from gridfs.cpp at https://github.com/mongodb/mongo-cxx-driver/blob/legacy/src/mongo/client/gridfs.cpp */ + + // Wait for any pending writebacks to finish + BSONObj errObj = _client->getLastErrorDetailed(); + uassert( 16428, + str::stream() << "Error storing GridFS chunk for file: " << name + << ", error: " << errObj, + DBClientWithCommands::getLastErrorString(errObj) == "" ); + + BSONObj res; + if ( ! _client->runCommand( _dbName.c_str() , + BSON( "filemd5" << _file_id << "root" << _prefix ) , + res ) ) + throw UserException( 9008 , "filemd5 failed" ); + + BSONObjBuilder file; + file << "_id" << _file_id["_id"] + << "filename" << name + << "chunkSize" << (unsigned int)_chunkSize + << "uploadDate" << DATENOW + << "md5" << res["md5"] + ; + + if (_file_length < 1024*1024*1024) { // 2^30 + file << "length" << (int) _file_length; + } + else { + file << "length" << (long long) _file_length; + } + + if (!content_type.empty()) + file << "contentType" << content_type; + + BSONObj ret = file.obj(); + _client->insert(_filesNS.c_str(), ret); + + // disallow builder object + _client = NULL; + + return ret; + } + +} diff --git a/mongo_cxx_extension.h b/mongo_cxx_extension.h new file mode 100644 index 0000000..02ec918 --- /dev/null +++ b/mongo_cxx_extension.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 Francisco Zamora-Martinez (pakozm@gmail.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef MONGO_CXX_EXTENSION +#define MONGO_CXX_EXTENSION + +#include +#include + +namespace mongo { + + const unsigned int DEFAULT_CHUNK_SIZE = 256*1024; + + // FIXME: client pointer is keep, review Lua binding in order to avoid + // unexpected garbage collection of DBClientBase + class GridFileBuilder { + public: + /** + * @param client - db connection + * @param dbName - root database name + * @param chunkSize - size of chunks + * @param prefix - if you want your data somewhere besides .fs + */ + GridFileBuilder(DBClientBase *client, const std::string &dbName, + unsigned int chunkSize = DEFAULT_CHUNK_SIZE, + const std::string& prefix = "fs"); + ~GridFileBuilder(); + // chunks are splitted in as many as necessary chunkSize blocks; sizes not + // multiple of chunkSize will copy remaining data at pending_data pointer + void appendChunk(const char *data, size_t length); + // buildFile will destroy this builder, not allowing to insert more data + BSONObj buildFile(const std::string &name, + const std::string& contentType=""); + + private: + DBClientBase *_client; + std::string _dbName; + std::string _prefix; + std::string _chunkNS; + std::string _filesNS; + size_t _chunkSize; + unsigned int _current_chunk; + BSONObj _file_id; + char *_pending_data; // NULL or pointer with _chunkSize space + size_t _pending_data_size; + gridfs_offset _file_length; + + const char *privateAppendChunk(const char *data, size_t length, + bool pending_insert = false); + void privateAppendPendingData(); + }; +} + +#endif // MONGO_CXX_EXTENSION diff --git a/mongo_gridfilebuilder.cpp b/mongo_gridfilebuilder.cpp new file mode 100644 index 0000000..cb56cfc --- /dev/null +++ b/mongo_gridfilebuilder.cpp @@ -0,0 +1,157 @@ +#include +#include +#include "mongo_cxx_extension.h" +#include "utils.h" +#include "common.h" + +// FIXME: client pointer is keep, review Lua binding in order to avoid +// unexpected garbage collection of DBClientBase + +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 GridFileBuilder* userdata_to_gridfilebuilder(lua_State* L, + int index) { + void *ud = 0; + + ud = luaL_checkudata(L, index, LUAMONGO_GRIDFILEBUILDER); + GridFileBuilder *gridfilebuilder = *((GridFileBuilder **)ud); + + return gridfilebuilder; + } +} // anonymous namespace + +/* + * builder, err = mongo.GridFileBuilder.New(connection, dbname[, chunksize[, prefix]]) + */ +static int gridfilebuilder_new(lua_State *L) { + int n = lua_gettop(L); + int resultcount = 1; + + try { + DBClientBase *connection = userdata_to_dbclient(L, 1); + const char *dbname = lua_tostring(L, 2); + + GridFileBuilder **builder = (GridFileBuilder **)lua_newuserdata(L, sizeof(GridFileBuilder *)); + + if (n >= 4) { + unsigned int chunksize = static_cast(luaL_checkint(L, 3)); + const char *prefix = luaL_checkstring(L, 4); + + *builder = new GridFileBuilder(connection, dbname, chunksize, prefix); + } else if (n == 3) { + unsigned int chunksize = static_cast(luaL_checkint(L, 3)); + + *builder = new GridFileBuilder(connection, dbname, chunksize); + } else { + *builder = new GridFileBuilder(connection, dbname); + } + + luaL_getmetatable(L, LUAMONGO_GRIDFILEBUILDER); + lua_setmetatable(L, -2); + } catch (std::exception &e) { + lua_pushnil(L); + lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, e.what()); + resultcount = 2; + } + + return resultcount; +} + +/* + * ok, err = builder:append(data_string) + */ +static int gridfilebuilder_append(lua_State *L) { + GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + int resultcount = 1; + try { + size_t length = 0; + const char *data = luaL_checklstring(L, 2, &length); + builder->appendChunk(data, length); + lua_pushboolean(L, 1); + } catch (std::exception &e) { + lua_pushnil(L); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFILEBUILDER, + "append", e.what()); + resultcount = 2; + } + return resultcount; +} + +/* + * bson, err = builder:build(remote_file[, content_type]) + */ +static int gridfilebuilder_build(lua_State *L) { + int resultcount = 1; + GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + const char *remote = luaL_checkstring(L, 2); + const char *content_type = luaL_optstring(L, 3, ""); + try { + BSONObj res = builder->buildFile(remote, content_type); + bson_to_lua(L, res); + } catch (std::exception &e) { + lua_pushnil(L); + lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFILEBUILDER, + "build", e.what()); + resultcount = 2; + } + return resultcount; +} + +/* + * __gc + */ +static int gridfilebuilder_gc(lua_State *L) { + GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + + delete builder; + + return 0; +} + +/* + * __tostring + */ +static int gridfilebuilder_tostring(lua_State *L) { + GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + + lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFILEBUILDER, builder); + + return 1; +} + +int mongo_gridfilebuilder_register(lua_State *L) { + static const luaL_Reg gridfilebuilder_methods[] = { + {"append", gridfilebuilder_append}, + {"build", gridfilebuilder_build}, + {NULL, NULL} + }; + + static const luaL_Reg gridfilebuilder_class_methods[] = { + {"New", gridfilebuilder_new}, + {NULL, NULL} + }; + + luaL_newmetatable(L, LUAMONGO_GRIDFILEBUILDER); + //luaL_register(L, 0, gridfs_methods); + luaL_setfuncs(L, gridfilebuilder_methods, 0); + lua_pushvalue(L,-1); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, gridfilebuilder_gc); + lua_setfield(L, -2, "__gc"); + + lua_pushcfunction(L, gridfilebuilder_tostring); + lua_setfield(L, -2, "__tostring"); + + lua_pop(L,1); + + luaL_newlib(L, gridfilebuilder_class_methods); + + return 1; +} diff --git a/mongo_gridfs.cpp b/mongo_gridfs.cpp index 74fa2bf..7c5a53d 100644 --- a/mongo_gridfs.cpp +++ b/mongo_gridfs.cpp @@ -4,6 +4,9 @@ #include "utils.h" #include "common.h" +// FIXME: GridFS pointer is keep in GridFile objects, review Lua binding in +// order to avoid unexpected garbage collection of GridFS pointer + using namespace mongo; extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj); @@ -142,7 +145,7 @@ static int gridfs_remove_file(lua_State *L) { } /* - * gridfile, err = gridfs:store_file(filename[, remote_file[, content_type]]) + * bson, err = gridfs:store_file(filename[, remote_file[, content_type]]) */ static int gridfs_store_file(lua_State *L) { int resultcount = 1; @@ -167,7 +170,7 @@ static int gridfs_store_file(lua_State *L) { /* - * gridfile, err = gridfs:store_data(data[, remote_file], content_type]]) + * bson, err = gridfs:store_data(data[, remote_file], content_type]]) * puts the file represented by data into the db */ static int gridfs_store_data(lua_State *L) { @@ -192,7 +195,6 @@ static int gridfs_store_data(lua_State *L) { return resultcount; } - /* * __gc */ diff --git a/mongo_gridfschunk.cpp b/mongo_gridfschunk.cpp index 723897c..eb836ab 100644 --- a/mongo_gridfschunk.cpp +++ b/mongo_gridfschunk.cpp @@ -75,9 +75,13 @@ int mongo_gridfschunk_register(lua_State *L) { {NULL, NULL} }; + static const luaL_Reg gridfschunk_class_methods[] = { + {NULL, NULL} + }; + luaL_newmetatable(L, LUAMONGO_GRIDFSCHUNK); //luaL_register(L, 0, gridfschunk_methods); - //luaL_setfuncs(L, gridfschunk_methods, 0); + luaL_setfuncs(L, gridfschunk_methods, 0); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); @@ -93,7 +97,7 @@ int mongo_gridfschunk_register(lua_State *L) { lua_pop(L,1); //luaL_register(L, LUAMONGO_GRIDFSCHUNK, gridfschunk_class_methods); - luaL_newlib(L, gridfschunk_methods); + luaL_newlib(L, gridfschunk_class_methods); return 1; } From be23fae6f3a986e015bbd2d4140951d7891b7da7 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Sun, 4 May 2014 14:54:25 +0200 Subject: [PATCH 14/18] Added new namespace to avoid collisions with future mongo_cxx driver addition of the GridFileBuilder class --- mongo_cxx_extension.cpp | 4 +- mongo_cxx_extension.h | 14 ++-- mongo_gridfilebuilder.cpp | 147 ++++++++++++++++++++------------------ 3 files changed, 89 insertions(+), 76 deletions(-) diff --git a/mongo_cxx_extension.cpp b/mongo_cxx_extension.cpp index 40f5c63..22b66fe 100644 --- a/mongo_cxx_extension.cpp +++ b/mongo_cxx_extension.cpp @@ -29,8 +29,10 @@ #include #include "mongo_cxx_extension.h" -namespace mongo { +namespace mongo_cxx_extension { + using namespace mongo; + using std::ios; using std::ofstream; using std::ostream; diff --git a/mongo_cxx_extension.h b/mongo_cxx_extension.h index 02ec918..94a7ba5 100644 --- a/mongo_cxx_extension.h +++ b/mongo_cxx_extension.h @@ -26,7 +26,7 @@ #include #include -namespace mongo { +namespace mongo_cxx_extension { const unsigned int DEFAULT_CHUNK_SIZE = 256*1024; @@ -40,7 +40,7 @@ namespace mongo { * @param chunkSize - size of chunks * @param prefix - if you want your data somewhere besides .fs */ - GridFileBuilder(DBClientBase *client, const std::string &dbName, + GridFileBuilder(mongo::DBClientBase *client, const std::string &dbName, unsigned int chunkSize = DEFAULT_CHUNK_SIZE, const std::string& prefix = "fs"); ~GridFileBuilder(); @@ -48,21 +48,21 @@ namespace mongo { // multiple of chunkSize will copy remaining data at pending_data pointer void appendChunk(const char *data, size_t length); // buildFile will destroy this builder, not allowing to insert more data - BSONObj buildFile(const std::string &name, - const std::string& contentType=""); + mongo::BSONObj buildFile(const std::string &name, + const std::string& contentType=""); private: - DBClientBase *_client; + mongo::DBClientBase *_client; std::string _dbName; std::string _prefix; std::string _chunkNS; std::string _filesNS; size_t _chunkSize; unsigned int _current_chunk; - BSONObj _file_id; + mongo::BSONObj _file_id; char *_pending_data; // NULL or pointer with _chunkSize space size_t _pending_data_size; - gridfs_offset _file_length; + mongo::gridfs_offset _file_length; const char *privateAppendChunk(const char *data, size_t length, bool pending_insert = false); diff --git a/mongo_gridfilebuilder.cpp b/mongo_gridfilebuilder.cpp index cb56cfc..7e1a1bb 100644 --- a/mongo_gridfilebuilder.cpp +++ b/mongo_gridfilebuilder.cpp @@ -15,59 +15,67 @@ extern int gridfile_create(lua_State *L, GridFile gf); extern DBClientBase* userdata_to_dbclient(lua_State *L, int stackpos); namespace { - inline GridFileBuilder* userdata_to_gridfilebuilder(lua_State* L, - int index) { - void *ud = 0; + inline mongo_cxx_extension::GridFileBuilder* userdata_to_gridfilebuilder(lua_State* L, + int index) { + void *ud = 0; - ud = luaL_checkudata(L, index, LUAMONGO_GRIDFILEBUILDER); - GridFileBuilder *gridfilebuilder = *((GridFileBuilder **)ud); + ud = luaL_checkudata(L, index, LUAMONGO_GRIDFILEBUILDER); + mongo_cxx_extension::GridFileBuilder *gridfilebuilder; + gridfilebuilder = *((mongo_cxx_extension::GridFileBuilder **)ud); - return gridfilebuilder; - } + return gridfilebuilder; + } } // anonymous namespace /* * builder, err = mongo.GridFileBuilder.New(connection, dbname[, chunksize[, prefix]]) */ static int gridfilebuilder_new(lua_State *L) { - int n = lua_gettop(L); - int resultcount = 1; - - try { - DBClientBase *connection = userdata_to_dbclient(L, 1); - const char *dbname = lua_tostring(L, 2); - - GridFileBuilder **builder = (GridFileBuilder **)lua_newuserdata(L, sizeof(GridFileBuilder *)); - - if (n >= 4) { - unsigned int chunksize = static_cast(luaL_checkint(L, 3)); - const char *prefix = luaL_checkstring(L, 4); + int n = lua_gettop(L); + int resultcount = 1; - *builder = new GridFileBuilder(connection, dbname, chunksize, prefix); - } else if (n == 3) { - unsigned int chunksize = static_cast(luaL_checkint(L, 3)); + try { + DBClientBase *connection = userdata_to_dbclient(L, 1); + const char *dbname = lua_tostring(L, 2); + + mongo_cxx_extension::GridFileBuilder **builder; + builder = (mongo_cxx_extension::GridFileBuilder **) + lua_newuserdata(L, sizeof(mongo_cxx_extension::GridFileBuilder *)); + + if (n >= 4) { + unsigned int chunksize = static_cast(luaL_checkint(L, 3)); + const char *prefix = luaL_checkstring(L, 4); + + *builder = new mongo_cxx_extension::GridFileBuilder(connection, + dbname, + chunksize, + prefix); + } else if (n == 3) { + unsigned int chunksize = static_cast(luaL_checkint(L, 3)); - *builder = new GridFileBuilder(connection, dbname, chunksize); - } else { - *builder = new GridFileBuilder(connection, dbname); - } - - luaL_getmetatable(L, LUAMONGO_GRIDFILEBUILDER); - lua_setmetatable(L, -2); - } catch (std::exception &e) { - lua_pushnil(L); - lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, e.what()); - resultcount = 2; + *builder = new mongo_cxx_extension::GridFileBuilder(connection, + dbname, chunksize); + } else { + *builder = new mongo_cxx_extension::GridFileBuilder(connection, dbname); } - return resultcount; + luaL_getmetatable(L, LUAMONGO_GRIDFILEBUILDER); + lua_setmetatable(L, -2); + } catch (std::exception &e) { + lua_pushnil(L); + lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, e.what()); + resultcount = 2; + } + + return resultcount; } /* * ok, err = builder:append(data_string) */ static int gridfilebuilder_append(lua_State *L) { - GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + mongo_cxx_extension::GridFileBuilder *builder; + builder = userdata_to_gridfilebuilder(L, 1); int resultcount = 1; try { size_t length = 0; @@ -88,7 +96,8 @@ static int gridfilebuilder_append(lua_State *L) { */ static int gridfilebuilder_build(lua_State *L) { int resultcount = 1; - GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + mongo_cxx_extension::GridFileBuilder *builder; + builder = userdata_to_gridfilebuilder(L, 1); const char *remote = luaL_checkstring(L, 2); const char *content_type = luaL_optstring(L, 3, ""); try { @@ -107,51 +116,53 @@ static int gridfilebuilder_build(lua_State *L) { * __gc */ static int gridfilebuilder_gc(lua_State *L) { - GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); - - delete builder; + mongo_cxx_extension::GridFileBuilder *builder; + builder = userdata_to_gridfilebuilder(L, 1); + + delete builder; - return 0; + return 0; } /* * __tostring */ static int gridfilebuilder_tostring(lua_State *L) { - GridFileBuilder *builder = userdata_to_gridfilebuilder(L, 1); + mongo_cxx_extension::GridFileBuilder *builder; + builder = userdata_to_gridfilebuilder(L, 1); - lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFILEBUILDER, builder); + lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFILEBUILDER, builder); - return 1; + return 1; } int mongo_gridfilebuilder_register(lua_State *L) { - static const luaL_Reg gridfilebuilder_methods[] = { - {"append", gridfilebuilder_append}, - {"build", gridfilebuilder_build}, - {NULL, NULL} - }; - - static const luaL_Reg gridfilebuilder_class_methods[] = { - {"New", gridfilebuilder_new}, - {NULL, NULL} - }; - - luaL_newmetatable(L, LUAMONGO_GRIDFILEBUILDER); - //luaL_register(L, 0, gridfs_methods); - luaL_setfuncs(L, gridfilebuilder_methods, 0); - lua_pushvalue(L,-1); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, gridfilebuilder_gc); - lua_setfield(L, -2, "__gc"); - - lua_pushcfunction(L, gridfilebuilder_tostring); - lua_setfield(L, -2, "__tostring"); + static const luaL_Reg gridfilebuilder_methods[] = { + {"append", gridfilebuilder_append}, + {"build", gridfilebuilder_build}, + {NULL, NULL} + }; + + static const luaL_Reg gridfilebuilder_class_methods[] = { + {"New", gridfilebuilder_new}, + {NULL, NULL} + }; + + luaL_newmetatable(L, LUAMONGO_GRIDFILEBUILDER); + //luaL_register(L, 0, gridfs_methods); + luaL_setfuncs(L, gridfilebuilder_methods, 0); + lua_pushvalue(L,-1); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, gridfilebuilder_gc); + lua_setfield(L, -2, "__gc"); + + lua_pushcfunction(L, gridfilebuilder_tostring); + lua_setfield(L, -2, "__tostring"); - lua_pop(L,1); + lua_pop(L,1); - luaL_newlib(L, gridfilebuilder_class_methods); + luaL_newlib(L, gridfilebuilder_class_methods); - return 1; + return 1; } From 4e97348aa1cd7e76e26b0db151cfc1686a785ba4 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Sun, 4 May 2014 15:09:34 +0200 Subject: [PATCH 15/18] Reset the GridFileBuilder after every call to build --- mongo_cxx_extension.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mongo_cxx_extension.cpp b/mongo_cxx_extension.cpp index 22b66fe..bda2852 100644 --- a/mongo_cxx_extension.cpp +++ b/mongo_cxx_extension.cpp @@ -93,7 +93,7 @@ namespace mongo_cxx_extension { } void GridFileBuilder::appendChunk(const char *data, size_t length) { - if (length == 0 || _client == NULL) return; + if (length == 0) return; // check if there are pending data if (_pending_data != NULL) { size_t total_size = _pending_data_size + length; @@ -123,7 +123,6 @@ namespace mongo_cxx_extension { BSONObj GridFileBuilder::buildFile(const string &name, const string& content_type) { - if (_client == NULL) return BSONObj(); privateAppendPendingData(); /* from gridfs.cpp at https://github.com/mongodb/mongo-cxx-driver/blob/legacy/src/mongo/client/gridfs.cpp */ @@ -162,9 +161,15 @@ namespace mongo_cxx_extension { BSONObj ret = file.obj(); _client->insert(_filesNS.c_str(), ret); - // disallow builder object - _client = NULL; - + // resets the object + _current_chunk = 0; + _pending_data = NULL; + _pending_data_size = 0; + _file_length = 0; + OID id; + id.init(); + _file_id = BSON("_id" << id); + return ret; } From f60d6f9f9c367fa1db2c42bdb409387c99009522 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Sun, 4 May 2014 22:46:05 +0200 Subject: [PATCH 16/18] Added write synonim in luamongo --- mongo_gridfilebuilder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mongo_gridfilebuilder.cpp b/mongo_gridfilebuilder.cpp index 7e1a1bb..1132939 100644 --- a/mongo_gridfilebuilder.cpp +++ b/mongo_gridfilebuilder.cpp @@ -139,6 +139,7 @@ static int gridfilebuilder_tostring(lua_State *L) { int mongo_gridfilebuilder_register(lua_State *L) { static const luaL_Reg gridfilebuilder_methods[] = { {"append", gridfilebuilder_append}, + {"write", gridfilebuilder_append}, {"build", gridfilebuilder_build}, {NULL, NULL} }; From c2a3b4f9f513f543f2e45d09955747dacae93d89 Mon Sep 17 00:00:00 2001 From: pakozm Date: Mon, 5 May 2014 13:51:09 +0200 Subject: [PATCH 17/18] Added luamongo version and name in module table --- common.h | 5 +++++ main.cpp | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/common.h b/common.h index 9800ba6..bc081b1 100644 --- a/common.h +++ b/common.h @@ -1,3 +1,8 @@ +#define LUAMONGO_NAME "mongo" +#define LUAMONGO_NAME_STRING "_NAME" +#define LUAMONGO_VERSION "0.4" +#define LUAMONGO_VERSION_STRING "_VERSION" + #define LUAMONGO_ROOT "mongo" #define LUAMONGO_CONNECTION "Connection" #define LUAMONGO_REPLICASET "ReplicaSet" diff --git a/main.cpp b/main.cpp index 9ed93b1..d53fd5b 100644 --- a/main.cpp +++ b/main.cpp @@ -85,6 +85,12 @@ LM_EXPORT int luaopen_mongo(lua_State *L) { * so "mongo = require('mongo')" works */ // lua_getglobal(L, LUAMONGO_ROOT); + + // push the version number and module name + lua_pushstring(L, LUAMONGO_NAME); + lua_setfield(L, -2, LUMONGO_NAME_STRING); + lua_pushstring(L, LUAMONGO_VERSION); + lua_setfield(L, -2, LUAMONGO_VERSION_STRING); return 1; } From a5b3b1c86f837bb4b196bf8b299308f5edf60b56 Mon Sep 17 00:00:00 2001 From: Paco Zamora Martinez Date: Mon, 5 May 2014 13:56:47 +0200 Subject: [PATCH 18/18] Solved compilation problem --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index d53fd5b..95e9865 100644 --- a/main.cpp +++ b/main.cpp @@ -88,7 +88,7 @@ LM_EXPORT int luaopen_mongo(lua_State *L) { // push the version number and module name lua_pushstring(L, LUAMONGO_NAME); - lua_setfield(L, -2, LUMONGO_NAME_STRING); + lua_setfield(L, -2, LUAMONGO_NAME_STRING); lua_pushstring(L, LUAMONGO_VERSION); lua_setfield(L, -2, LUAMONGO_VERSION_STRING);