Skip to content

Commit

Permalink
Merge from gridfs branch
Browse files Browse the repository at this point in the history
git-svn-id: http://luamongo.googlecode.com/svn/trunk@30 17e306f6-9439-11de-a13a-71b910e68cc8
  • Loading branch information
nrich@ii.net committed Jul 25, 2010
2 parents b4d288d + 467f150 commit aeade91
Show file tree
Hide file tree
Showing 8 changed files with 890 additions and 38 deletions.
8 changes: 7 additions & 1 deletion Makefile
Expand Up @@ -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

Expand All @@ -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
Expand Down
33 changes: 23 additions & 10 deletions common.h
Expand Up @@ -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
7 changes: 7 additions & 0 deletions main.cpp
Expand Up @@ -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);

/*
*
Expand All @@ -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
Expand Down
212 changes: 190 additions & 22 deletions mongo_bsontypes.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -74,13 +54,201 @@ 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},
{"Timestamp", bson_type_Timestamp},
{"RegEx", bson_type_RegEx},
{"NumberInt", bson_type_NumberInt},
{"Symbol", bson_type_Symbol},
{"type", bson_type_name},
{NULL, NULL}
};

Expand Down

0 comments on commit aeade91

Please sign in to comment.