Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge from gridfs branch

git-svn-id: http://luamongo.googlecode.com/svn/trunk@30 17e306f6-9439-11de-a13a-71b910e68cc8
  • Loading branch information...
commit aeade9162585eed5d65e8a1eb5d36d072a6ba6c9 2 parents b4d288d + 467f150
nrich@ii.net authored
View
8 Makefile
@@ -8,7 +8,7 @@ OUTLIB=mongo.so
LDFLAGS= $(LIBS)
-OBJS = main.o mongo_connection.o mongo_cursor.o mongo_query.o mongo_bsontypes.o utils.o
+OBJS = main.o mongo_bsontypes.o mongo_connection.o mongo_cursor.o mongo_gridfile.o mongo_gridfs.o mongo_gridfschunk.o mongo_query.o utils.o
all: luamongo
@@ -32,6 +32,12 @@ 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_bsontypes.o: mongo_bsontypes.cpp common.h
View
33 common.h
@@ -2,14 +2,27 @@
#define LUAMONGO_CONNECTION "mongo.Connection"
#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_ERR_CONNECTION_FAILED "Connection failed: %s"
-#define LUAMONGO_ERR_QUERY_FAILED "Query failed: %s"
-#define LUAMONGO_ERR_INSERT_FAILED "Insert failed: %s"
-#define LUAMONGO_ERR_CONNECT_FAILED "Connection to %s failed: %s"
-#define LUAMONGO_ERR_COUNT_FAILED "Count failed: %s"
-#define LUAMONGO_ERR_REMOVE_FAILED "Remove failed: %s"
-#define LUAMONGO_ERR_UPDATE_FAILED "Update failed: %s"
-#define LUAMONGO_UNSUPPORTED_BSON_TYPE "Unsupported BSON type"
-#define LUAMONGO_UNSUPPORTED_LUA_TYPE "Unsupported Lua type `%s'"
-#define LUAMONGO_REQUIRES_JSON_OR_TABLE "JSON string or Lua table required"
+#define LUAMONGO_ERR_CONNECTION_FAILED "Connection failed: %s"
+#define LUAMONGO_ERR_GRIDFS_FAILED "GridFS failed: %s"
+#define LUAMONGO_ERR_GRIDFSCHUNK_FAILED "GridFSChunk failed: %s"
+#define LUAMONGO_ERR_QUERY_FAILED "Query failed: %s"
+#define LUAMONGO_ERR_INSERT_FAILED "Insert failed: %s"
+#define LUAMONGO_ERR_CONNECT_FAILED "Connection to %s failed: %s"
+#define LUAMONGO_ERR_COUNT_FAILED "Count failed: %s"
+#define LUAMONGO_ERR_REMOVE_FAILED "Remove failed: %s"
+#define LUAMONGO_ERR_UPDATE_FAILED "Update failed: %s"
+#define LUAMONGO_UNSUPPORTED_BSON_TYPE "Unsupported BSON type `%s'"
+#define LUAMONGO_UNSUPPORTED_LUA_TYPE "Unsupported Lua type `%s'"
+#define LUAMONGO_REQUIRES_JSON_OR_TABLE "JSON string or Lua table required"
+#define LUAMONGO_NOT_IMPLEMENTED "Not implemented: %s.%s"
+#define LUAMONGO_ERR_CALLING "Error calling %s.%s: %s"
+
+#if defined(MONGO_1_5)
+ #define CHUNK GridFSChunk
+#else
+ #define CHUNK Chunk
+#endif
View
7 main.cpp
@@ -40,6 +40,9 @@ extern int mongo_bsontypes_register(lua_State *L);
extern int mongo_connection_register(lua_State *L);
extern int mongo_cursor_register(lua_State *L);
extern int mongo_query_register(lua_State *L);
+extern int mongo_gridfs_register(lua_State *L);
+extern int mongo_gridfile_register(lua_State *L);
+extern int mongo_gridfschunk_register(lua_State *L);
/*
*
@@ -55,6 +58,10 @@ LM_EXPORT int luaopen_mongo(lua_State *L) {
mongo_cursor_register(L);
mongo_query_register(L);
+ mongo_gridfs_register(L);
+ mongo_gridfile_register(L);
+ mongo_gridfschunk_register(L);
+
/*
* push the created table to the top of the stack
* so "mongo = require('mongo')" works
View
212 mongo_bsontypes.cpp
@@ -15,28 +15,8 @@ extern "C" {
using namespace mongo;
-// TODO:
-// all of this should be in Lua so it can get JIT wins
-// bind the bson typeids
-// each type could have its cached metatable (from registry)
-
-// all these types are represented as tables
-// the metatable entry __bsontype dictates the type
-// the t[1] represents the object itself, with some types using other fields
-
-namespace {
-// pushes onto the stack a new table with the bsontype metatable set up
-void push_bsontype_table(lua_State* L, mongo::BSONType bsontype)
-{
- lua_newtable(L);
- lua_newtable(L);
- lua_pushstring(L, "__bsontype");
- lua_pushinteger(L, bsontype);
- lua_settable(L, -3);
- lua_setmetatable(L, -2);
-}
-} // anonynous namespace
-
+void push_bsontype_table(lua_State* L, mongo::BSONType bsontype);
+extern const char *bson_name(int type);
static int bson_type_Date(lua_State *L) {
push_bsontype_table(L, mongo::Date);
@@ -74,6 +54,193 @@ static int bson_type_Symbol(lua_State *L) {
return 1;
}
+static int integer_value(lua_State *L) {
+ int n = lua_gettop(L);
+ int returncount = 1;
+
+ lua_rawgeti(L, 1, 1);
+
+ if (n > 1) {
+ lua_pushinteger(L, luaL_checkint(L, 2));
+ lua_rawseti(L, 1, 1);
+ returncount = 0;
+ } else {
+ lua_pushinteger(L, luaL_checkint(L, -1));
+ }
+
+ return returncount;
+}
+
+static int number_value(lua_State *L) {
+ int n = lua_gettop(L);
+ int returncount = 1;
+
+ lua_rawgeti(L, 1, 1);
+
+ if (n > 1) {
+ lua_pushnumber(L, luaL_checknumber(L, 2));
+ lua_rawseti(L, 1, 1);
+ returncount = 0;
+ } else {
+ lua_pushnumber(L, luaL_checknumber(L, -1));
+ }
+
+ return returncount;
+}
+
+static int string_value(lua_State *L) {
+ int n = lua_gettop(L);
+ int returncount = 1;
+
+ lua_rawgeti(L, 1, 1);
+
+ if (n > 1) {
+ lua_pushstring(L, luaL_checkstring(L, 2));
+ lua_rawseti(L, 1, 1);
+ returncount = 0;
+ } else {
+ lua_pushstring(L, luaL_checkstring(L, -1));
+ }
+
+ return returncount;
+}
+
+static int stringpair_value(lua_State *L) {
+ int n = lua_gettop(L);
+ int returncount = 2;
+
+ lua_rawgeti(L, 1, 1);
+ lua_rawgeti(L, 1, 2);
+
+ if (n > 1) {
+ lua_pushstring(L, luaL_checkstring(L, 2));
+ lua_rawseti(L, 1, 1);
+ lua_pushstring(L, luaL_checkstring(L, 3));
+ lua_rawseti(L, 1, 2);
+ returncount = 0;
+ } else {
+ lua_pushstring(L, luaL_checkstring(L, -2));
+ lua_pushstring(L, luaL_checkstring(L, -2));
+ }
+
+ return returncount;
+}
+
+static int generic_tostring(lua_State *L) {
+ lua_rawgeti(L, 1, 1);
+
+ //lua_pushstring(L, lua_tostring(L, -1));
+ lua_pushstring(L, luaL_optstring(L, -1, "nil"));
+
+ return 1;
+}
+
+static int date_tostring(lua_State *L) {
+ char datestr[64];
+
+ lua_rawgeti(L, 1, 1);
+
+ time_t t = (time_t)(lua_tonumber(L, -1)/1000);
+
+#if defined(_WIN32)
+ ctime_s(datestr, 64, &t);
+#else
+ ctime_r(&t,datestr);
+#endif
+
+ datestr[24] = 0; // don't want the \n
+
+ lua_pushstring(L, datestr);
+
+ return 1;
+}
+
+static int regex_tostring(lua_State *L) {
+ lua_rawgeti(L, 1, 1);
+ lua_rawgeti(L, 1, 2);
+
+ lua_pushfstring(L, "/%s/%s", lua_tostring(L, -2), lua_tostring(L, -1));
+
+ return 1;
+}
+
+
+// TODO:
+// all of this should be in Lua so it can get JIT wins
+// bind the bson typeids
+// each type could have its cached metatable (from registry)
+
+// all these types are represented as tables
+// the metatable entry __bsontype dictates the type
+// the t[1] represents the object itself, with some types using other fields
+
+void push_bsontype_table(lua_State* L, mongo::BSONType bsontype) {
+ lua_newtable(L);
+ lua_newtable(L);
+
+ lua_pushstring(L, "__bsontype");
+ lua_pushinteger(L, bsontype);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__call");
+ switch(bsontype) {
+ case mongo::NumberInt:
+ lua_pushcfunction(L, integer_value);
+ break;
+ case mongo::Date:
+ case mongo::Timestamp:
+ lua_pushcfunction(L, number_value);
+ break;
+ case mongo::Symbol:
+ lua_pushcfunction(L, string_value);
+ break;
+ case mongo::RegEx:
+ lua_pushcfunction(L, stringpair_value);
+ break;
+ }
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "__tostring");
+ switch(bsontype) {
+ case mongo::NumberInt:
+ case mongo::Timestamp:
+ case mongo::Symbol:
+ lua_pushcfunction(L, generic_tostring);
+ break;
+ case mongo::Date:
+ lua_pushcfunction(L, date_tostring);
+ break;
+ case mongo::RegEx:
+ lua_pushcfunction(L, regex_tostring);
+ break;
+ }
+ lua_settable(L, -3);
+
+ lua_setmetatable(L, -2);
+}
+
+/*
+ * typename = mongo.type(obj)
+ */
+static int bson_type_name(lua_State *L) {
+ if (lua_istable(L, 1)) {
+ int bsontype_found = luaL_getmetafield(L, 1, "__bsontype");
+
+ if (bsontype_found) {
+ int bson_type = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+
+ lua_pushfstring(L, "%s.%s", LUAMONGO_ROOT, bson_name(bson_type));
+ } else {
+ lua_pushstring(L, luaL_typename(L, 1));
+ }
+ } else {
+ lua_pushstring(L, luaL_typename(L, 1));
+ }
+
+ return 1;
+}
+
int mongo_bsontypes_register(lua_State *L) {
static const luaL_Reg bsontype_methods[] = {
{"Date", bson_type_Date},
@@ -81,6 +248,7 @@ int mongo_bsontypes_register(lua_State *L) {
{"RegEx", bson_type_RegEx},
{"NumberInt", bson_type_NumberInt},
{"Symbol", bson_type_Symbol},
+ {"type", bson_type_name},
{NULL, NULL}
};
View
257 mongo_gridfile.cpp
@@ -0,0 +1,257 @@
+#include <iostream>
+#include <client/dbclient.h>
+#include <client/gridfs.h>
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
+#include <compat-5.1.h>
+#endif
+};
+
+#include "utils.h"
+#include "common.h"
+
+using namespace mongo;
+
+extern void bson_to_lua(lua_State *L, const BSONObj &obj);
+extern void push_bsontype_table(lua_State* L, mongo::BSONType bsontype);
+extern void lua_push_value(lua_State *L, const BSONElement &elem);
+
+namespace {
+ inline GridFile* userdata_to_gridfile(lua_State* L, int index) {
+ void *ud = 0;
+
+ ud = luaL_checkudata(L, index, LUAMONGO_GRIDFILE);
+ GridFile *gridfile = *((GridFile **)ud);
+
+ return gridfile;
+ }
+}
+
+int gridfile_create(lua_State *L, GridFile gf) {
+ GridFile **gridfile = (GridFile **)lua_newuserdata(L, sizeof(GridFile **));
+
+ *gridfile = new GridFile(gf);
+
+ luaL_getmetatable(L, LUAMONGO_GRIDFILE);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+/*
+ * chunk, err = gridfile:chunk(chunk_num)
+ */
+static int gridfile_chunk(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+ int num = luaL_checkint(L, 2);
+ int resultcount = 1;
+
+ try {
+ CHUNK c = gridfile->getChunk(num);
+ CHUNK *chunk_ptr = new CHUNK(c);
+
+ CHUNK **chunk = (CHUNK **)lua_newuserdata(L, sizeof(CHUNK *));
+ *chunk = chunk_ptr;
+
+ luaL_getmetatable(L, LUAMONGO_GRIDFSCHUNK);
+ lua_setmetatable(L, -2);
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_GRIDFSCHUNK_FAILED, e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+/*
+ * chunk_size = gridfile:chunk_size()
+ */
+static int gridfile_chunk_size(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushinteger(L, gridfile->getChunkSize());
+
+ return 1;
+}
+
+/*
+ * content_length = gridfile:content_length()
+ * __len
+ */
+static int gridfile_content_length(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushnumber(L, gridfile->getContentLength());
+
+ return 1;
+}
+
+/*
+ * bool = gridfile:exists()
+ */
+static int gridfile_exists(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushboolean(L, gridfile->exists());
+
+ return 1;
+}
+
+/*
+ *
+ */
+
+static int gridfile_field(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+ const char *field_name = luaL_checkstring(L, 2);
+
+ BSONElement elem = gridfile->getFileField(field_name);
+ lua_push_value(L, elem);
+
+ return 1;
+}
+
+/*
+ * filename_str = gridfile:filename()
+ */
+static int gridfile_filename(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushstring(L, gridfile->getFilename().c_str());
+
+ return 1;
+}
+
+/*
+ * md5_str = gridfile:md5()
+ */
+static int gridfile_md5(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushstring(L, gridfile->getMD5().c_str());
+
+ return 1;
+}
+
+/*
+ * metadata_table = gridfile:metadata()
+ */
+static int gridfile_metadata(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ bson_to_lua(L, gridfile->getMetadata());
+
+ return 1;
+}
+
+/*
+ * num_chunks = gridfile:num_chunks()
+ */
+static int gridfile_num_chunks(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushinteger(L, gridfile->getNumChunks());
+
+ return 1;
+}
+
+/*
+ * date = gridfile:upload_date()
+ */
+static int gridfile_upload_date(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ Date_t upload_date = gridfile->getUploadDate();
+
+ push_bsontype_table(L, mongo::Date);
+ lua_pushnumber(L, upload_date);
+ lua_rawseti(L, -2, 1);
+
+ return 1;
+}
+
+/*
+ * success,err = gridfile:write(filename)
+ */
+static int gridfile_write(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+ const char *where = luaL_checkstring(L, 2);
+
+ try {
+ gridfile->write(lua_tostring(L, 2));
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFILE, "write", e.what());
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/*
+ * __gc
+ */
+static int gridfile_gc(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ delete gridfile;
+
+ return 0;
+}
+
+/*
+ * __tostring
+ */
+static int gridfile_tostring(lua_State *L) {
+ GridFile *gridfile = userdata_to_gridfile(L, 1);
+
+ lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFILE, gridfile);
+
+ return 1;
+}
+
+int mongo_gridfile_register(lua_State *L) {
+ static const luaL_Reg gridfile_methods[] = {
+ {"chunk", gridfile_chunk},
+ {"chunk_size", gridfile_chunk_size},
+ {"content_length", gridfile_content_length},
+ {"exists", gridfile_exists},
+ {"field", gridfile_field},
+ {"filename", gridfile_filename},
+ {"md5", gridfile_md5},
+ {"metadata", gridfile_metadata},
+ {"num_chunks", gridfile_num_chunks},
+ {"upload_date", gridfile_upload_date},
+ {"write", gridfile_write},
+ {NULL, NULL}
+ };
+
+ static const luaL_Reg gridfile_class_methods[] = {
+ {NULL, NULL}
+ };
+
+ luaL_newmetatable(L, LUAMONGO_GRIDFILE);
+ luaL_register(L, 0, gridfile_methods);
+ lua_pushvalue(L,-1);
+ lua_setfield(L, -2, "__index");
+
+ lua_pushcfunction(L, gridfile_gc);
+ lua_setfield(L, -2, "__gc");
+
+ lua_pushcfunction(L, gridfile_tostring);
+ lua_setfield(L, -2, "__tostring");
+
+ lua_pushcfunction(L, gridfile_content_length);
+ lua_setfield(L, -2, "__len");
+
+ luaL_register(L, LUAMONGO_GRIDFILE, gridfile_class_methods);
+
+ return 1;
+}
View
203 mongo_gridfs.cpp
@@ -0,0 +1,203 @@
+#include <iostream>
+#include <client/dbclient.h>
+#include <client/gridfs.h>
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
+#include <compat-5.1.h>
+#endif
+};
+
+#include "utils.h"
+#include "common.h"
+
+using namespace mongo;
+
+extern void bson_to_lua(lua_State *L, const BSONObj &obj);
+extern int gridfile_create(lua_State *L, GridFile gf);
+
+namespace {
+ inline GridFS* userdata_to_gridfs(lua_State* L, int index) {
+ void *ud = 0;
+
+ ud = luaL_checkudata(L, index, LUAMONGO_GRIDFS);
+ GridFS *gridfs = *((GridFS **)ud);
+
+ return gridfs;
+ }
+}
+
+/*
+ * gridfs, err = mongo.GridFS.New(connection, dbname[, prefix])
+ */
+static int gridfs_new(lua_State *L) {
+ int n = lua_gettop(L);
+ int resultcount = 1;
+
+ try {
+ void *ud = 0;
+
+ ud = luaL_checkudata(L, 1, LUAMONGO_CONNECTION);
+ DBClientConnection *connection = *((DBClientConnection **)ud);
+
+ const char *dbname = lua_tostring(L, 2);
+
+ GridFS **gridfs = (GridFS **)lua_newuserdata(L, sizeof(GridFS *));
+
+ if (n >= 3) {
+ const char *prefix = luaL_checkstring(L, 3);
+
+ *gridfs = new GridFS(*connection, dbname, prefix);
+ } else {
+ *gridfs = new GridFS(*connection, dbname);
+ }
+
+ luaL_getmetatable(L, LUAMONGO_GRIDFS);
+ lua_setmetatable(L, -2);
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_GRIDFS_FAILED, e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+/*
+ * gridfile, err = gridfs:find_file(filename)
+ */
+static int gridfs_find_file(lua_State *L) {
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+ int resultcount = 1;
+
+ try {
+ GridFile gridfile = gridfs->findFile(luaL_checkstring(L, 2));
+ resultcount = gridfile_create(L, gridfile);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFS, "find_file", e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+/*
+ * cursor = gridfs:list()
+ */
+static int gridfs_list(lua_State *L) {
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+
+ DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *));
+ auto_ptr<DBClientCursor> autocursor = gridfs->list();
+ *cursor = autocursor.get();
+ autocursor.release();
+
+ luaL_getmetatable(L, LUAMONGO_CURSOR);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+/*
+ * ok, err = gridfs:remove_file(filename)
+ */
+static int gridfs_remove_file(lua_State *L) {
+ int resultcount = 1;
+
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+
+ const char *filename = luaL_checkstring(L, 2);
+
+ try {
+ gridfs->removeFile(filename);
+ lua_pushboolean(L, 1);
+ } catch (std::exception &e) {
+ lua_pushboolean(L, 0);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFS, "remove_file", e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+/*
+ * gridfile, err = gridfs:store_file(filename[, remote_file], content_type]])
+ */
+static int gridfs_store_file(lua_State *L) {
+ int resultcount = 1;
+
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+
+ const char *filename = luaL_checkstring(L, 2);
+ const char *remote = luaL_optstring(L, 3, "");
+ const char *content_type = luaL_optstring(L, 4, "");
+
+ try {
+ BSONObj res = gridfs->storeFile(filename, remote, content_type);
+ bson_to_lua(L, res);
+ } catch (std::exception &e) {
+ lua_pushnil(L);
+ lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_GRIDFS, "store_file", e.what());
+ resultcount = 2;
+ }
+
+ return resultcount;
+}
+
+
+/*
+ * __gc
+ */
+static int gridfs_gc(lua_State *L) {
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+
+ delete gridfs;
+
+ return 0;
+}
+
+/*
+ * __tostring
+ */
+static int gridfs_tostring(lua_State *L) {
+ GridFS *gridfs = userdata_to_gridfs(L, 1);
+
+ lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFS, gridfs);
+
+ return 1;
+}
+
+int mongo_gridfs_register(lua_State *L) {
+ static const luaL_Reg gridfs_methods[] = {
+ {"find_file", gridfs_find_file},
+ {"list", gridfs_list},
+ {"remove_file", gridfs_remove_file},
+ {"store_file", gridfs_store_file},
+ {NULL, NULL}
+ };
+
+ static const luaL_Reg gridfs_class_methods[] = {
+ {"New", gridfs_new},
+ {NULL, NULL}
+ };
+
+ luaL_newmetatable(L, LUAMONGO_GRIDFS);
+ luaL_register(L, 0, gridfs_methods);
+ lua_pushvalue(L,-1);
+ lua_setfield(L, -2, "__index");
+
+ lua_pushcfunction(L, gridfs_gc);
+ lua_setfield(L, -2, "__gc");
+
+ lua_pushcfunction(L, gridfs_tostring);
+ lua_setfield(L, -2, "__tostring");
+
+ luaL_register(L, LUAMONGO_GRIDFS, gridfs_class_methods);
+
+ return 1;
+}
View
106 mongo_gridfschunk.cpp
@@ -0,0 +1,106 @@
+#include <iostream>
+#include <client/dbclient.h>
+#include <client/gridfs.h>
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
+#include <compat-5.1.h>
+#endif
+};
+
+#include "utils.h"
+#include "common.h"
+
+using namespace mongo;
+
+namespace {
+ inline CHUNK* userdata_to_gridfschunk(lua_State* L, int index) {
+ void *ud = 0;
+
+ ud = luaL_checkudata(L, index, LUAMONGO_GRIDFSCHUNK);
+ CHUNK *chunk = *((CHUNK **)ud);
+
+ return chunk;
+ }
+}
+
+/*
+ * str = chunk:data()
+ */
+static int gridfschunk_data(lua_State *L) {
+ CHUNK *chunk = userdata_to_gridfschunk(L, 1);
+ int len;
+
+ const char *data = chunk->data(len);
+
+ lua_pushlstring(L, data, len);
+
+ return 1;
+}
+
+/*
+ * length = chunk:len()
+ * __len
+ */
+static int gridfschunk_len(lua_State *L) {
+ CHUNK *chunk = userdata_to_gridfschunk(L, 1);
+
+ int len = chunk->len();
+
+ lua_pushinteger(L, len);
+
+ return 1;
+}
+
+
+/*
+ * __gc
+ */
+static int gridfschunk_gc(lua_State *L) {
+ CHUNK *chunk = userdata_to_gridfschunk(L, 1);
+
+ delete chunk;
+
+ return 0;
+}
+
+/*
+ * __tostring
+ */
+static int gridfschunk_tostring(lua_State *L) {
+ CHUNK *chunk = userdata_to_gridfschunk(L, 1);
+
+ lua_pushfstring(L, "%s: %p", LUAMONGO_GRIDFSCHUNK, chunk);
+
+ return 1;
+}
+
+int mongo_gridfschunk_register(lua_State *L) {
+ static const luaL_Reg gridfschunk_methods[] = {
+ {"data", gridfschunk_data},
+ {"len", gridfschunk_len},
+ {NULL, NULL}
+ };
+
+ luaL_newmetatable(L, LUAMONGO_GRIDFSCHUNK);
+ luaL_register(L, 0, gridfschunk_methods);
+ lua_pushvalue(L,-1);
+ lua_setfield(L, -2, "__index");
+
+ lua_pushcfunction(L, gridfschunk_gc);
+ lua_setfield(L, -2, "__gc");
+
+ lua_pushcfunction(L, gridfschunk_tostring);
+ lua_setfield(L, -2, "__tostring");
+
+ lua_pushcfunction(L, gridfschunk_len);
+ lua_setfield(L, -2, "__len");
+
+ //luaL_register(L, LUAMONGO_GRIDFSCHUNK, gridfschunk_class_methods);
+
+ return 1;
+}
View
102 utils.cpp
@@ -16,7 +16,9 @@ extern "C" {
using namespace mongo;
-static void lua_push_value(lua_State *L, const BSONElement &elem);
+extern void push_bsontype_table(lua_State* L, mongo::BSONType bsontype);
+void lua_push_value(lua_State *L, const BSONElement &elem);
+const char *bson_name(int type);
static void bson_to_array(lua_State *L, const BSONObj &obj) {
BSONObjIterator it = BSONObjIterator(obj);
@@ -47,10 +49,10 @@ static void bson_to_table(lua_State *L, const BSONObj &obj) {
}
}
-static void lua_push_value(lua_State *L, const BSONElement &elem) {
+void lua_push_value(lua_State *L, const BSONElement &elem) {
int type = elem.type();
- switch(elem.type()) {
+ switch(type) {
case mongo::Undefined:
case mongo::jstNULL:
lua_pushnil(L);
@@ -76,10 +78,32 @@ static void lua_push_value(lua_State *L, const BSONElement &elem) {
case mongo::jstOID:
lua_pushstring(L, elem.__oid().str().c_str());
break;
+ case mongo::Date:
+ push_bsontype_table(L, mongo::Date);
+ lua_pushnumber(L, elem.date());
+ lua_rawseti(L, -2, 1);
+ break;
+ case mongo::Timestamp:
+ push_bsontype_table(L, mongo::Date);
+ lua_pushnumber(L, elem.timestampTime());
+ lua_rawseti(L, -2, 1);
+ break;
+ case mongo::Symbol:
+ push_bsontype_table(L, mongo::Symbol);
+ lua_pushstring(L, elem.valuestr());
+ lua_rawseti(L, -2, 1);
+ break;
+ case mongo::RegEx:
+ push_bsontype_table(L, mongo::RegEx);
+ lua_pushstring(L, elem.regex());
+ lua_rawseti(L, -2, 1);
+ lua_pushstring(L, elem.regexFlags());
+ lua_rawseti(L, -2, 2);
+ break;
case mongo::EOO:
break;
default:
- luaL_error(L, LUAMONGO_UNSUPPORTED_BSON_TYPE);
+ luaL_error(L, LUAMONGO_UNSUPPORTED_BSON_TYPE, bson_name(type));
}
}
@@ -115,7 +139,7 @@ static void lua_append_bson(lua_State *L, const char *key, int stackpos, BSONObj
break;
case mongo::RegEx: {
const char* regex = lua_tostring(L, -1);
- lua_rawgeti(L, -1, 1); // options
+ lua_rawgeti(L, -2, 2); // options
const char* options = lua_tostring(L, -1);
lua_pop(L, 1);
builder->appendRegex(key, regex, options);
@@ -165,3 +189,71 @@ void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj) {
obj = builder.obj();
}
+
+const char *bson_name(int type) {
+ const char *name;
+
+ switch(type) {
+ case mongo::EOO:
+ name = "EndOfObject";
+ break;
+ case mongo::NumberDouble:
+ name = "NumberDouble";
+ break;
+ case mongo::String:
+ name = "String";
+ break;
+ case mongo::Object:
+ name = "Object";
+ break;
+ case mongo::Array:
+ name = "Array";
+ break;
+ case mongo::BinData:
+ name = "BinData";
+ break;
+ case mongo::Undefined:
+ name = "Undefined";
+ break;
+ case mongo::jstOID:
+ name = "ObjectID";
+ break;
+ case mongo::Bool:
+ name = "Bool";
+ break;
+ case mongo::Date:
+ name = "Date";
+ break;
+ case mongo::jstNULL:
+ name = "NULL";
+ break;
+ case mongo::RegEx:
+ name = "RegEx";
+ break;
+ case mongo::DBRef:
+ name = "DBRef";
+ break;
+ case mongo::Code:
+ name = "Code";
+ break;
+ case mongo::Symbol:
+ name = "Symbol";
+ break;
+ case mongo::CodeWScope:
+ name = "CodeWScope";
+ break;
+ case mongo::NumberInt:
+ name = "NumberInt";
+ break;
+ case mongo::Timestamp:
+ name = "Timestamp";
+ break;
+ case mongo::NumberLong:
+ name = "NumberLong";
+ break;
+ default:
+ name = "UnknownType";
+ }
+
+ return name;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.