From ac7aad9d3cf22d4556d52239da37a2d8859fe122 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 15 Mar 2013 01:10:24 +0700 Subject: [PATCH] #51 --- luaejdb/Makefile | 2 +- luaejdb/ejdb.lua | 17 +++++++------ luaejdb/luabson.c | 2 +- luaejdb/luabson.h | 1 + luaejdb/luaejdb.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++-- luaejdb/test/t1.lua | 13 +++++++++- tcejdb/bson.c | 4 +-- tcejdb/bson.h | 2 +- tcejdb/tcutil.h | 2 +- 9 files changed, 98 insertions(+), 16 deletions(-) diff --git a/luaejdb/Makefile b/luaejdb/Makefile index 7d324ac..4e9db33 100644 --- a/luaejdb/Makefile +++ b/luaejdb/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-g -O2 -fPIC -std=c99 -Wall -D_GNU_SOURCE +CFLAGS=-g -O0 -fPIC -std=c99 -Wall -D_GNU_SOURCE build: luarocks --pack-binary-rock CFLAGS='$(CFLAGS)' make diff --git a/luaejdb/ejdb.lua b/luaejdb/ejdb.lua index eb0a936..97ad63d 100644 --- a/luaejdb/ejdb.lua +++ b/luaejdb/ejdb.lua @@ -114,12 +114,19 @@ local mtDBObj = { local luaejdb_open = luaejdb.open function luaejdb:open(path, omode, ...) - if type(omode) ~= "number" then - omode = luaejdb.DEFAULT_OPEN_MODE - end return setmetatable(luaejdb_open(path, omode), mtDBObj) end +function DB:save(cname, obj, ...) + assert(obj and type(obj) == "table", "Invalid arg #2") + if getmetatable(obj) == mtBObj then + obj = obj:toBSON() + else + obj = luaejdb.to_bson(obj) + end + return self:_save(cname, obj, ...) +end + function DB:find(cname, q, ...) assert(getmetatable(q) == mtBObj, "Query object must be instance of 'luaejdb.B' class `q = luaejdb.B()`") local flags = ... @@ -151,10 +158,6 @@ function B:_init(fname, ...) return self end -function B:_value(val) - return val -end - function B:_checkop() assert(type(self._field) == "string") end diff --git a/luaejdb/luabson.c b/luaejdb/luabson.c index 03359e2..f6308ab 100644 --- a/luaejdb/luabson.c +++ b/luaejdb/luabson.c @@ -487,7 +487,7 @@ static void bson_print_xstr(TCXSTR* xstr, const char *data, int depth) { /* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */ bson_iterator_code_scope(&i, &scope); tcxstrprintf(xstr, "\n SCOPE: "); - tcxstrprintf(xstr, &scope); + bson_print_xstr(xstr, scope.data, 0); /* bson_destroy( &scope ); */ /* review - causes free error */ break; case BSON_INT: diff --git a/luaejdb/luabson.h b/luaejdb/luabson.h index 842b093..5c87490 100644 --- a/luaejdb/luabson.h +++ b/luaejdb/luabson.h @@ -19,6 +19,7 @@ extern "C" { int lua_from_bson(lua_State *L); int lua_to_bson(lua_State *L); int print_bson(lua_State *L); + void lua_push_bsontype_table(lua_State* L, int bsontype); #ifdef __cplusplus } diff --git a/luaejdb/luaejdb.c b/luaejdb/luaejdb.c index 4c016bc..c644f81 100644 --- a/luaejdb/luaejdb.c +++ b/luaejdb/luaejdb.c @@ -38,6 +38,12 @@ typedef struct { #define EJDBERR(_L, _DB) \ return luaL_error((_L), "EJDB ERROR %d|%s", ejdbecode(_DB), ejdberrmsg(ejdbecode(_DB))) +static int set_ejdb_error(lua_State *L, EJDB *jb) { + int ecode = ejdbecode(jb); + const char *emsg = ejdberrmsg(ecode); + return luaL_error(L, emsg); +} + static void init_db_consts(lua_State *L) { if (!lua_istable(L, -1)) { luaL_error(L, "Table must be on top of lua stack"); @@ -121,6 +127,41 @@ static int db_close(lua_State *L) { return 0; } +static int db_save(lua_State *L) { + int argc = lua_gettop(L); + luaL_checktype(L, 1, LUA_TTABLE); //self + lua_getfield(L, 1, EJDBUDATAKEY); + EJDBDATA *data = luaL_checkudata(L, -1, EJDBUDATAMT); + EJDB *jb = data->db; + const char *cname = luaL_checkstring(L, 2); //collections name + bson bsonval; + const char *bsonbuf = luaL_checkstring(L, 3); //Object to save + bson_init_finished_data(&bsonval, bsonbuf); + bsonval.flags |= BSON_FLAG_STACK_ALLOCATED; + bool merge = false; + if (lua_isboolean(L, 4)) { //merge flag + merge = lua_toboolean(L, 4); + } + EJCOLL *coll = ejdbcreatecoll(jb, cname, NULL); + if (!coll) { + return set_ejdb_error(L, jb); + } + bson_oid_t oid; + if (!ejdbsavebson2(coll, &bsonval, &oid, merge)) { + bson_destroy(&bsonval); + return set_ejdb_error(L, jb); + } + char xoid[25]; + bson_oid_to_string(&oid, xoid); + lua_pushstring(L, xoid); + + bson_destroy(&bsonval); + if (lua_gettop(L) - argc != 2) { //got +lua_getfield(L, 1, EJDBUDATAKEY) + return luaL_error(L, "db_save: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1); + } + return 1; +} + static int db_find(lua_State *L) { //cname, q.toBSON(), orBsons, q.toHintsBSON(), flags luaL_checktype(L, 1, LUA_TTABLE); //self @@ -138,7 +179,7 @@ static int db_find(lua_State *L) { bson qbson = {NULL}; bson hbson = {NULL}; EJQ *q = NULL; - EJDB *db = data->db; + EJDB *jb = data->db; EJCOLL *coll = NULL; uint32_t count = 0; @@ -150,7 +191,30 @@ static int db_find(lua_State *L) { static int db_open(lua_State *L) { int argc = lua_gettop(L); const char *path = luaL_checkstring(L, 1); - int mode = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : DEFAULT_OPEN_MODE; + int mode = DEFAULT_OPEN_MODE; + if (lua_isnumber(L, 2)) { + mode = lua_tointeger(L, 2); + } else if (lua_isstring(L, 2)) { + mode = 0; + const char* om = lua_tostring(L, 2); + for (int i = 0; om[i] != '\0'; ++i) { + mode |= JBOREADER; + switch (om[i]) { + case 'w': + mode |= JBOWRITER; + break; + case 'c': + mode |= JBOCREAT; + break; + case 't': + mode |= JBOTRUNC; + break; + case 's': + mode |= JBOTSYNC; + break; + } + } + } //DB table lua_newtable(L); @@ -178,6 +242,9 @@ static int db_open(lua_State *L) { lua_pushcfunction(L, db_close); lua_setfield(L, -2, "close"); + lua_pushcfunction(L, db_save); + lua_setfield(L, -2, "_save"); + lua_pushcfunction(L, db_find); lua_setfield(L, -2, "_find"); diff --git a/luaejdb/test/t1.lua b/luaejdb/test/t1.lua index 75c749b..f66b7db 100644 --- a/luaejdb/test/t1.lua +++ b/luaejdb/test/t1.lua @@ -7,7 +7,9 @@ local ejdb = require("ejdb") assert(type(ejdb) == "table") local Q = ejdb.Q -local db = ejdb:open("testdb"); +local B = ejdb.B + +local db = ejdb:open("testdb", "rwct"); local q = Q("name", "Andy"):F("_id"):Eq("510f7fa91ad6270a00000000"):F("age"):Gt(20):Lt(40):F("score"):In({ 11, 22.12333, 1362835380447, db.toNull() }):Max(232); assert([[.name(2)=Andy @@ -57,6 +59,15 @@ assert(obj.bdate[1] == 1362835380447) assert(type(obj.dst) == "table" and getmetatable(obj.dst).__bsontype == db.BSON_NULL) +-- Test save +-- +local oid = db:save("mycoll", {foo="bar"}); +assert(oid and #oid == 24) + +oid = db:save("mycoll", B("foo2","bar2")); +assert(oid and #oid == 24) + + db:close() collectgarbage() diff --git a/tcejdb/bson.c b/tcejdb/bson.c index 6e03da3..6feafe6 100644 --- a/tcejdb/bson.c +++ b/tcejdb/bson.c @@ -118,8 +118,8 @@ int bson_init_data(bson *b, char *data) { return BSON_OK; } -EJDB_EXPORT int bson_init_finished_data(bson *b, char *data) { - bson_init_data(b, data); +EJDB_EXPORT int bson_init_finished_data(bson *b, const char *data) { + bson_init_data(b, (char*) data); bson_reset(b); b->finished = 1; return BSON_OK; diff --git a/tcejdb/bson.h b/tcejdb/bson.h index f51fc49..b2b7b67 100644 --- a/tcejdb/bson.h +++ b/tcejdb/bson.h @@ -612,7 +612,7 @@ EJDB_EXPORT void bson_init_as_query(bson *b); * @return BSON_OK or BSON_ERROR. */ int bson_init_data(bson *b, char *data); -EJDB_EXPORT int bson_init_finished_data(bson *b, char *data); +EJDB_EXPORT int bson_init_finished_data(bson *b, const char *data); /** * Initialize a BSON object, and set its diff --git a/tcejdb/tcutil.h b/tcejdb/tcutil.h index b35ac05..6c01ab0 100644 --- a/tcejdb/tcutil.h +++ b/tcejdb/tcutil.h @@ -3719,7 +3719,7 @@ typedef unsigned char TCBITMAP; /* type of a bit map object */ #include -#define _TC_VERSION "1.0.66" +#define _TC_VERSION "1.0.65" #define _TC_LIBVER 911 #define _TC_FORMATVER "1.0" -- 2.7.4