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
diff --git a/Makefile b/Makefile
index 65454db..d2d4959 100644
--- a/Makefile
+++ b/Makefile
@@ -1,52 +1,30 @@
CC= g++
-CFLAGS= -g -O2 -shared -fPIC -I /usr/include/lua5.1/ -I/usr/local/include/mongo/
+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=-lmongoclient -lboost_thread -lboost_filesystem
+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
+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
+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..284e3db
--- /dev/null
+++ b/Makefile.linux
@@ -0,0 +1,56 @@
+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 mongo_cxx_extension.o mongo_gridfilebuilder.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)
+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/Makefile.macports b/Makefile.macports
new file mode 100644
index 0000000..64a2947
--- /dev/null
+++ b/Makefile.macports
@@ -0,0 +1,56 @@
+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 mongo_cxx_extension.o mongo_gridfilebuilder.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)
+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/README.md b/README.md
index c2ab938..dcbe7df 100644
--- a/README.md
+++ b/README.md
@@ -16,13 +16,13 @@
## Support
-Submit issues to the moai github site.
+Submit issues to the pakozm github site.
There is a Google Groups mailing list.
## Example
- require('mongo')
+ local mongo = require('mongo')
-- Create a connection object
local db = assert(mongo.Connection.New())
@@ -54,9 +54,9 @@ 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.
## Installing
@@ -66,5 +66,5 @@ luarocks can be used to install luamongo.
## History
-This project was forked from the luamongo project on googlecode.
+This project was forked from the luamongo project on GitHub.
diff --git a/common.h b/common.h
index 8582cb1..bc081b1 100644
--- a/common.h
+++ b/common.h
@@ -1,14 +1,20 @@
-#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_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"
+#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 "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/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 e98a51e..95e9865 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"
@@ -44,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);
/*
*
@@ -54,21 +45,52 @@ 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);
+
+ // 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
*/
- lua_getglobal(L, LUAMONGO_ROOT);
+ // lua_getglobal(L, LUAMONGO_ROOT);
+
+ // push the version number and module name
+ lua_pushstring(L, LUAMONGO_NAME);
+ lua_setfield(L, -2, LUAMONGO_NAME_STRING);
+ lua_pushstring(L, LUAMONGO_VERSION);
+ lua_setfield(L, -2, LUAMONGO_VERSION_STRING);
return 1;
}
diff --git a/mongo_bsontypes.cpp b/mongo_bsontypes.cpp
index 617eddc..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);
@@ -381,8 +375,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..4bfa82a 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;
@@ -115,8 +105,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");
@@ -125,8 +117,11 @@ 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);
+
+ lua_pop(L,1);
+
+ //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..c384f35 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"
@@ -192,7 +181,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");
@@ -201,8 +191,11 @@ 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);
+
+ lua_pop(L,1);
+
+ //luaL_register(L, LUAMONGO_CURSOR, cursor_class_methods);
+ luaL_newlib(L, cursor_class_methods);
return 1;
}
diff --git a/mongo_cxx_extension.cpp b/mongo_cxx_extension.cpp
new file mode 100644
index 0000000..bda2852
--- /dev/null
+++ b/mongo_cxx_extension.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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_cxx_extension {
+
+ using 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) 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) {
+ 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);
+
+ // 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;
+ }
+
+}
diff --git a/mongo_cxx_extension.h b/mongo_cxx_extension.h
new file mode 100644
index 0000000..94a7ba5
--- /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_cxx_extension {
+
+ 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(mongo::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
+ mongo::BSONObj buildFile(const std::string &name,
+ const std::string& contentType="");
+
+ private:
+ mongo::DBClientBase *_client;
+ std::string _dbName;
+ std::string _prefix;
+ std::string _chunkNS;
+ std::string _filesNS;
+ size_t _chunkSize;
+ unsigned int _current_chunk;
+ mongo::BSONObj _file_id;
+ char *_pending_data; // NULL or pointer with _chunkSize space
+ size_t _pending_data_size;
+ mongo::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_dbclient.cpp b/mongo_dbclient.cpp
index b8548e1..acc9a63 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"
@@ -28,7 +18,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 +50,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
}
@@ -91,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);
@@ -129,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());
@@ -236,7 +227,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);
@@ -263,6 +254,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 +323,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);
@@ -509,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;
}
@@ -540,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);
@@ -563,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;
}
@@ -582,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;
}
@@ -617,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);
@@ -630,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;
}
@@ -680,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);
@@ -707,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();
@@ -718,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 {
@@ -740,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);
@@ -748,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);
@@ -769,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;
}
@@ -849,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[] = {
@@ -877,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}
};
diff --git a/mongo_gridfile.cpp b/mongo_gridfile.cpp
index af54b85..506444e 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"
@@ -260,7 +249,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 +263,10 @@ 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);
+ lua_pop(L,1);
+
+ //luaL_register(L, LUAMONGO_GRIDFILE, gridfile_class_methods);
+ luaL_newlib(L, gridfile_class_methods);
return 1;
}
diff --git a/mongo_gridfilebuilder.cpp b/mongo_gridfilebuilder.cpp
new file mode 100644
index 0000000..1132939
--- /dev/null
+++ b/mongo_gridfilebuilder.cpp
@@ -0,0 +1,169 @@
+#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 mongo_cxx_extension::GridFileBuilder* userdata_to_gridfilebuilder(lua_State* L,
+ int index) {
+ void *ud = 0;
+
+ ud = luaL_checkudata(L, index, LUAMONGO_GRIDFILEBUILDER);
+ mongo_cxx_extension::GridFileBuilder *gridfilebuilder;
+ gridfilebuilder = *((mongo_cxx_extension::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);
+
+ 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 mongo_cxx_extension::GridFileBuilder(connection,
+ dbname, chunksize);
+ } else {
+ *builder = new mongo_cxx_extension::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) {
+ mongo_cxx_extension::GridFileBuilder *builder;
+ 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;
+ 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 {
+ 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) {
+ mongo_cxx_extension::GridFileBuilder *builder;
+ builder = userdata_to_gridfilebuilder(L, 1);
+
+ delete builder;
+
+ return 0;
+}
+
+/*
+ * __tostring
+ */
+static int gridfilebuilder_tostring(lua_State *L) {
+ mongo_cxx_extension::GridFileBuilder *builder;
+ 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},
+ {"write", 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 177d037..7c5a53d 100644
--- a/mongo_gridfs.cpp
+++ b/mongo_gridfs.cpp
@@ -1,20 +1,12 @@
#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"
+// 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);
@@ -98,19 +90,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 +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;
@@ -174,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) {
@@ -199,7 +195,6 @@ static int gridfs_store_data(lua_State *L) {
return resultcount;
}
-
/*
* __gc
*/
@@ -238,7 +233,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 +243,11 @@ 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_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..eb836ab 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"
@@ -86,8 +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_register(L, 0, gridfschunk_methods);
+ luaL_setfuncs(L, gridfschunk_methods, 0);
lua_pushvalue(L,-1);
lua_setfield(L, -2, "__index");
@@ -100,7 +94,10 @@ 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_class_methods);
return 1;
}
diff --git a/mongo_query.cpp b/mongo_query.cpp
index 21ab11b..28c2650 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"
@@ -344,7 +333,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");
@@ -353,8 +343,11 @@ 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);
+
+ lua_pop(L,1);
+
+ //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..28c9c56 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;
@@ -114,8 +104,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 +116,11 @@ 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);
+
+ lua_pop(L,1);
+
+ //luaL_register(L, LUAMONGO_REPLICASET, replicaset_class_methods);
+ luaL_newlib(L, replicaset_class_methods);
return 1;
}
diff --git a/tests/connection.lua b/tests/connection.lua
index ffe44d9..9733e9c 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'
@@ -66,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 3bc0248..de08a5c 100644
--- a/tests/lunity.lua
+++ b/tests/lunity.lua
@@ -46,11 +46,8 @@
local setmetatable=setmetatable
local _G=_G
-module( 'lunity' )
-VERSION = "0.9"
-
-local lunity = _M
+local lunity = { _VERSION = "0.9", _NAME="lunity" }
setmetatable( lunity, {
__index = _G,
__call = function( self, testSuite )
@@ -363,4 +360,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..5a7d99b 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'
@@ -66,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/utils.cpp b/utils.cpp
index 2f8556c..13127d7 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"
#include
@@ -365,3 +354,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..0d47c25 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,21 @@
*
*/
+extern "C" {
+#include
+#include
+#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);
+
#define LUA_PUSH_ATTRIB_INT(n, v) \
lua_pushstring(L, n); \
lua_pushinteger(L, v); \