From 4be51ba1643289ee6ac820b3dd56a2782896f714 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 18 Jul 2013 18:03:18 +0700 Subject: [PATCH] #59 #72 --- Changelog | 7 + luaejdb/debian/changelog | 6 + luaejdb/debian/control | 4 +- luaejdb/doc/index.html | 104 ++++++++++++++ luaejdb/ejdb.lua | 12 ++ luaejdb/ejdb.luadoc | 43 ++++++ ...b-1.0.4-1.rockspec => luaejdb-1.0.5-1.rockspec} | 2 +- luaejdb/luaejdb.c | 150 +++++++-------------- luaejdb/test/t1.lua | 6 + node/ejdb.js | 74 ++++++++++ node/ejdb_native.cc | 65 ++++++++- node/tests/t2.js | 13 +- package.json | 6 +- pyejdb/debian/changelog | 6 + pyejdb/debian/control | 4 +- pyejdb/pyejdb.iml | 2 +- pyejdb/pyejdb/__init__.py | 48 ++++++- pyejdb/setup.py | 8 +- pyejdb/src/pejdb.c | 25 ++++ pyejdb/test/test_one.py | 8 ++ tcejdb/Changelog | 7 + tcejdb/Makefile.in | 3 +- tcejdb/configure | 18 +-- tcejdb/configure.ac | 2 +- tcejdb/debian/changelog | 7 + tcejdb/debian/libtcejdb9.symbols | 13 ++ tcejdb/ejdb.c | 19 +-- tcejdb/ejdb.h | 6 +- tcejdb/tcutil.h | 2 +- 29 files changed, 533 insertions(+), 137 deletions(-) rename luaejdb/{luaejdb-1.0.4-1.rockspec => luaejdb-1.0.5-1.rockspec} (97%) mode change 100755 => 100644 pyejdb/setup.py diff --git a/Changelog b/Changelog index 2db1ca3..2754184 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,10 @@ +libtcejdb (1.1.14) testing; urgency=low + + * Supports generic ejdb commands interface + * Export/Import database data implemented + + -- Anton Adamansky Thu, 18 Jul 2013 15:44:31 +0700 + libtcejdb (1.1.13) testing; urgency=low * .Net binding diff --git a/luaejdb/debian/changelog b/luaejdb/debian/changelog index d18536a..1c93d1f 100644 --- a/luaejdb/debian/changelog +++ b/luaejdb/debian/changelog @@ -1,3 +1,9 @@ +lua-ejdb (1.0.5-1) testing; urgency=low + + * EJDB 1.1.14 + + -- Anton Adamansky Thu, 18 Jul 2013 17:59:41 +0700 + lua-ejdb (1.0.4-1) testing; urgency=low * EJDB 1.1.13 diff --git a/luaejdb/debian/control b/luaejdb/debian/control index 9106a54..6c86414 100644 --- a/luaejdb/debian/control +++ b/luaejdb/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Anton Adamansky Build-Depends: debhelper (>= 9), - libtcejdb9-dev (>= 1.1.13), + libtcejdb9-dev (>= 1.1.14), luarocks (>= 2.0), lua-penlight, lua-filesystem @@ -18,7 +18,7 @@ Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, - libtcejdb9 (>= 1.1.13) + libtcejdb9 (>= 1.1.14) Recommends: lua5.1 Description: Lua binding for EJDB EJDB aims to be a fast MongoDB-like library which can be embedded into C/C++/NodeJS/Python/Lua diff --git a/luaejdb/doc/index.html b/luaejdb/doc/index.html index b21654f..4cc4551 100644 --- a/luaejdb/doc/index.html +++ b/luaejdb/doc/index.html @@ -185,10 +185,22 @@ Builds BSON_UNDEFINED value . + DB.version () + Returns EJDB version string eg: "1.1.14" + + DB:save (cname, obj, ...) Save/update specified JSON objects in the collection. + DB:load (cname, oid) + Loads JSON object identified by OID from the collection. + + + DB:command (cmd) + Executes ejdb command. + + DB:find (cname, q, flags) Execute query on collection. @@ -797,6 +809,19 @@
+ + DB.version () +
+
+ Returns EJDB version string eg: "1.1.14" + + + + + + +
+
DB:save (cname, obj, ...)
@@ -831,6 +856,85 @@
+ + DB:load (cname, oid) +
+
+ Loads JSON object identified by OID from the collection. + +

Parameters:

+
    +
  • cname + string + Collection name
  • +
  • oid + string or table + 24 hex chars BSON_OID or BSON oid table
  • +
+ + + + + +
+
+ + DB:command (cmd) +
+
+ +

Executes ejdb command. + Supported commands:

+
1) Exports database collections data. See ejdbexport() method.
+
+  "export" : {
+        "path" : string,                    //Exports database collections data
+        "cnames" : [string array]|null,     //List of collection names to export
+        "mode" : int|null                   //Values: null|`JBJSONEXPORT` See ejdbexport() method
+  }
+
+  Command response:
+     {
+        "log" : string,        //Diagnostic log about executing this command
+        "error" : string|null, //ejdb error message
+        "errorCode" : int|0,   //ejdb error code
+     }
+
+2) Imports previously exported collections data into ejdb.
+
+  "import" : {
+        "path" : string                     //The directory path in which data resides
+        "cnames" : [string array]|null,     //List of collection names to import
+        "mode" : int|null                //Values: null|`JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdbimport() method
+   }
+
+   Command response:
+     {
+        "log" : string,        //Diagnostic log about executing this command
+        "error" : string|null, //ejdb error message
+        "errorCode" : int|0,   //ejdb error code
+     }
+
+ + +

Parameters:

+
    +
  • cmd + table or Q + Command object.
  • +
+ +

Returns:

+
    + + Command response table +
+ + + + +
+
DB:find (cname, q, flags)
diff --git a/luaejdb/ejdb.lua b/luaejdb/ejdb.lua index 25be60f..145d703 100644 --- a/luaejdb/ejdb.lua +++ b/luaejdb/ejdb.lua @@ -124,6 +124,18 @@ function luaejdb.open(path, omode, ...) return setmetatable(luaejdb_open(path, omode), mtDBObj) end + +function DB:command(cmd) + assert(cmd and type(cmd) == "table", "Invalid arg #1") + if getmetatable(cmd) == mtBObj then + cmd = cmd:toBSON() + else + cmd = luaejdb.to_bson(cmd) + end + return self:_command(cmd) +end + + function DB:save(cname, obj, ...) assert(obj and type(obj) == "table", "Invalid arg #2") if getmetatable(obj) == mtBObj then diff --git a/luaejdb/ejdb.luadoc b/luaejdb/ejdb.luadoc index 8b9b54c..e0067a8 100644 --- a/luaejdb/ejdb.luadoc +++ b/luaejdb/ejdb.luadoc @@ -235,6 +235,9 @@ function DB.toNull() end -- @see ejdb.toUndefined function DB.toUndefined() end +--- Returns EJDB version string eg: "1.1.14" +function DB.version() end + --- Save/update specified JSON objects in the collection. -- If collection with `cname` does not exists it will be created. -- Each persistent object has unique identifier (OID) placed in the `_id` property. @@ -248,6 +251,46 @@ function DB.toUndefined() end -- @usage dQ:save("parrots2", Q("foo", "bar"), true) -- merge option is on function DB:save(cname, obj, ...) end +--- Loads JSON object identified by OID from the collection. +-- @tparam string cname Collection name +-- @tparam string|table oid 24 hex chars BSON_OID or BSON oid table +function DB:load(cname, oid) end + +--- Executes ejdb command. +-- Supported commands: +-- 1) Exports database collections data. See ejdbexport() method. +-- +-- "export" : { +-- "path" : string, //Exports database collections data +-- "cnames" : [string array]|null, //List of collection names to export +-- "mode" : int|null //Values: null|`JBJSONEXPORT` See ejdbexport() method +-- } +-- +-- Command response: +-- { +-- "log" : string, //Diagnostic log about executing this command +-- "error" : string|null, //ejdb error message +-- "errorCode" : int|0, //ejdb error code +-- } +-- +-- 2) Imports previously exported collections data into ejdb. +-- +-- "import" : { +-- "path" : string //The directory path in which data resides +-- "cnames" : [string array]|null, //List of collection names to import +-- "mode" : int|null //Values: null|`JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdbimport() method +-- } +-- +-- Command response: +-- { +-- "log" : string, //Diagnostic log about executing this command +-- "error" : string|null, //ejdb error message +-- "errorCode" : int|0, //ejdb error code +-- } +-- @tparam table|Q cmd Command object. +-- @return Command response table +function DB:command(cmd) end + --- Execute query on collection. -- -- EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy. diff --git a/luaejdb/luaejdb-1.0.4-1.rockspec b/luaejdb/luaejdb-1.0.5-1.rockspec similarity index 97% rename from luaejdb/luaejdb-1.0.4-1.rockspec rename to luaejdb/luaejdb-1.0.5-1.rockspec index d423769..10e8641 100644 --- a/luaejdb/luaejdb-1.0.4-1.rockspec +++ b/luaejdb/luaejdb-1.0.5-1.rockspec @@ -1,5 +1,5 @@ package = "luaejdb" -version = "1.0.4-1" +version = "1.0.5-1" source = { url = "https://github.com/Softmotions/ejdb.git" } diff --git a/luaejdb/luaejdb.c b/luaejdb/luaejdb.c index 4c41391..4d62236 100644 --- a/luaejdb/luaejdb.c +++ b/luaejdb/luaejdb.c @@ -484,118 +484,32 @@ static int db_txctl(lua_State *L) { } static int db_meta(lua_State *L) { - lua_checkstack(L, 6); int argc = lua_gettop(L); luaL_checktype(L, 1, LUA_TTABLE); //self lua_getfield(L, 1, EJDBUDATAKEY); EJDB *jb = ((EJDBDATA*) luaL_checkudata(L, -1, EJDBUDATAMT))->db; check_ejdb(L, jb); - bool jbret = true; lua_pop(L, 1); - - lua_newtable(L); //+root info - - lua_pushstring(L, jb->metadb->hdb->path); - lua_setfield(L, -2, "file"); - - lua_newtable(L); //+collections - TCLIST *cols = ejdbgetcolls(jb); - if (!cols) { - return set_ejdb_error(L, jb); - } - int i; - for (i = 0; i < TCLISTNUM(cols); ++i) { - EJCOLL *coll = (EJCOLL*) TCLISTVALPTR(cols, i); - if (!ejcollockmethod(coll, false)) continue; - - lua_pushlstring(L, coll->cname, coll->cnamesz); //coll key - - lua_newtable(L); //+ coll table - - lua_pushlstring(L, coll->cname, coll->cnamesz); - lua_setfield(L, -2, "name"); - - lua_pushstring(L, coll->tdb->hdb->path); - lua_setfield(L, -2, "file"); - - lua_pushinteger(L, coll->tdb->hdb->rnum); - lua_setfield(L, -2, "records"); - - lua_newtable(L); //+ coll options - - lua_pushinteger(L, coll->tdb->hdb->bnum); - lua_setfield(L, -2, "buckets"); - - lua_pushinteger(L, coll->tdb->hdb->rcnum); - lua_setfield(L, -2, "cachedrecords"); - - lua_pushboolean(L, coll->tdb->opts & TDBTLARGE); - lua_setfield(L, -2, "large"); - - lua_pushboolean(L, coll->tdb->opts & TDBTDEFLATE); - lua_setfield(L, -2, "compressed"); - lua_setfield(L, -2, "options"); - - lua_newtable(L); //+ coll indexes - - int ic = 0; - int j; - for (j = 0; j < coll->tdb->inum; ++j) { - TDBIDX *idx = (coll->tdb->idxs + j); - if (idx->type != TDBITLEXICAL && idx->type != TDBITDECIMAL && idx->type != TDBITTOKEN) { - continue; - } - lua_newtable(L); //+ index details - - lua_pushstring(L, idx->name + 1); - lua_setfield(L, -2, "field"); - - lua_pushstring(L, idx->name); - lua_setfield(L, -2, "iname"); - - switch (idx->type) { - case TDBITLEXICAL: - lua_pushstring(L, "lexical"); - lua_setfield(L, -2, "type"); - break; - case TDBITDECIMAL: - lua_pushstring(L, "decimal"); - lua_setfield(L, -2, "type"); - break; - case TDBITTOKEN: - lua_pushstring(L, "token"); - lua_setfield(L, -2, "type"); - break; - } - TCBDB *idb = (TCBDB*) idx->db; - if (idb) { - lua_pushinteger(L, idb->rnum); - lua_setfield(L, -2, "records"); - - lua_pushstring(L, idb->hdb->path); - lua_setfield(L, -2, "file"); - } - lua_rawseti(L, -2, ++ic); - } - lua_setfield(L, -2, "indexes"); - lua_settable(L, -3); - - ejcollunlockmethod(coll); - } - lua_setfield(L, -2, "collections"); - - if (cols) { - tclistdel(cols); - } - if (!jbret) { - return set_ejdb_error(L, jb); + bson *meta = ejdbmeta(jb); + if (meta == NULL) { + lua_pushnil(L); + return 1; } + bson_iterator it; + bson_iterator_init(&it, meta); + lua_push_bson_table(L, &it); + bson_del(meta); if (lua_gettop(L) - argc != 1) { return luaL_error(L, "db_meta: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1); } return 1; } +static int db_version(lua_State *L) { + lua_pushstring(L, ejdbversion()); + return 1; +} + static int db_save(lua_State *L) { int argc = lua_gettop(L); luaL_checktype(L, 1, LUA_TTABLE); //self @@ -632,6 +546,36 @@ static int db_save(lua_State *L) { return 1; } +static int db_command(lua_State *L) { + int argc = lua_gettop(L); + luaL_checktype(L, 1, LUA_TTABLE); //self + lua_getfield(L, 1, EJDBUDATAKEY); + EJDB *jb = ((EJDBDATA*) luaL_checkudata(L, -1, EJDBUDATAMT))->db; + check_ejdb(L, jb); + lua_pop(L, 1); + bson bsonval; + const char *bsonbuf = luaL_checkstring(L, 2); //Object to save + bson_init_finished_data(&bsonval, bsonbuf); + bsonval.flags |= BSON_FLAG_STACK_ALLOCATED; + bson *bs = ejdbcommand(jb, &bsonval); + if (!bs) { + lua_pushnil(L); + goto finish; + } + bson_iterator it; + bson_iterator_init(&it, bs); + lua_push_bson_table(L, &it); + bson_del(bs); + +finish: + if (lua_gettop(L) - argc != 1) { //got + return luaL_error(L, "db_command: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1); + } + bson_destroy(&bsonval); + return 1; +} + + static int db_load(lua_State *L) { int argc = lua_gettop(L); luaL_checktype(L, 1, LUA_TTABLE); //self @@ -678,7 +622,7 @@ static int db_load(lua_State *L) { finish: if (lua_gettop(L) - argc != 1) { //got - return luaL_error(L, "db_save: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1); + return luaL_error(L, "db_load: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1); } return 1; } @@ -877,6 +821,9 @@ static int db_open(lua_State *L) { lua_pushcfunction(L, db_load); lua_setfield(L, -2, "load"); + lua_pushcfunction(L, db_command); + lua_setfield(L, -2, "_command"); + lua_pushcfunction(L, db_find); lua_setfield(L, -2, "_find"); @@ -936,6 +883,9 @@ int luaopen_luaejdb(lua_State *L) { lua_pushcfunction(L, db_open); lua_setfield(L, -2, "open"); + lua_pushcfunction(L, db_version); + lua_setfield(L, -2, "version"); + //Push cursor methods into metatable luaL_newmetatable(L, EJDBCURSORMT); luaL_register(L, NULL, ejdbcursor_m); diff --git a/luaejdb/test/t1.lua b/luaejdb/test/t1.lua index 175e9dc..b3aad60 100644 --- a/luaejdb/test/t1.lua +++ b/luaejdb/test/t1.lua @@ -214,6 +214,12 @@ db:dropCollection("ecoll", true); assert(db:count("ecoll", Q("k1", "v2")) == 0) +local cret = db:command({ping = {}}); +assert(cret["log"] == "pong"); + + +--print(ejdb.version()); + assert(db:isOpen() == true) db:close() assert(db:isOpen() == false) diff --git a/node/ejdb.js b/node/ejdb.js index ac55516..c5495f5 100644 --- a/node/ejdb.js +++ b/node/ejdb.js @@ -471,6 +471,80 @@ EJDB.prototype.findOne = function() { /** + * Execute ejdb database command. + * + * Supported commands: + * + * + * 1) Exports database collections data. See ejdbexport() method. + * + * "export" : { + * "path" : string, //Exports database collections data + * "cnames" : [string array]|null, //List of collection names to export + * "mode" : int|null //Values: null|`JBJSONEXPORT` See ejdbexport() method + * } + * + * Command response: + * { + * "log" : string, //Diagnostic log about executing this command + * "error" : string|null, //ejdb error message + * "errorCode" : int|0, //ejdb error code + * } + * + * 2) Imports previously exported collections data into ejdb. + * + * "import" : { + * "path" : string //The directory path in which data resides + * "cnames" : [string array]|null, //List of collection names to import + * "mode" : int|null //Values: null|`JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdbimport() method + * } + * + * Command response: + * { + * "log" : string, //Diagnostic log about executing this command + * "error" : string|null, //ejdb error message + * "errorCode" : int|0, //ejdb error code + * } + * + * If callback is not provided this function will be synchronous. + * + * @param {Object} cmd BSON command spec. + * @param {Function} [cb] Callback function with arguments: (error, obj) where: + * `obj`: Command response JSON object. + * @return Command response JSON object if callback is not provided. + */ +EJDB.prototype.command = function(cmd, cb) { + if (cb) { + this._impl.command(cmd, function(err, cursor) { + if (err) { + cb(err); + return; + } + if (cursor.next()) { + try { + cb(null, cursor.object()); + } finally { + cursor.close(); + } + } else { + cb(null, null); + } + }); + } else { + var ret = null; + var cursor = this._impl.command(cmd); + if (cursor && typeof cursor === "object") { + if (cursor.next()) { + ret = cursor.object(); + } + cursor.close(); + } + return ret; + } +}; + + +/** * Convenient method to execute update queries. * If callback is not provided this function will be synchronous. * diff --git a/node/ejdb_native.cc b/node/ejdb_native.cc index fd9b58a..2401a90 100644 --- a/node/ejdb_native.cc +++ b/node/ejdb_native.cc @@ -509,7 +509,8 @@ namespace ejdb { cmdTxBegin = 8, //Begin collection transaction cmdTxAbort = 9, //Abort collection transaction cmdTxCommit = 10, //Commit collection transaction - cmdTxStatus = 11 //Get collection transaction status + cmdTxStatus = 11, //Get collection transaction status + cmdCmd = 12 //Execute EJDB command }; struct BSONCmdData { //Any bson related cmd data @@ -730,6 +731,37 @@ namespace ejdb { } } + static Handle s_cmd(const Arguments& args) { + HandleScope scope; + REQ_ARGS(1); + REQ_OBJ_ARG(0, cmdobj); + + Local cb; + BSONQCmdData *cmdata = new BSONQCmdData("", 0); + bson *bs = bson_create(); + bson_init_as_query(bs); + toBSON(cmdobj, bs, false); + if (bs->err) { + Local msg = String::New(bson_first_errormsg(bs)); + bson_del(bs); + delete cmdata; + return scope.Close(ThrowException(Exception::Error(msg))); + } + bson_finish(bs); + cmdata->bsons.push_back(bs); + NodeEJDB *njb = ObjectWrap::Unwrap< NodeEJDB > (args.This()); + if (args[1]->IsFunction()) { //callback provided + cb = Local::Cast(args[1]); + BSONQCmdTask *task = new BSONQCmdTask(cb, njb, cmdCmd, cmdata, BSONQCmdTask::delete_val); + uv_queue_work(uv_default_loop(), &task->uv_work, s_exec_cmd_eio, (uv_after_work_cb)s_exec_cmd_eio_after); + return scope.Close(Undefined()); + } else { + BSONQCmdTask task(cb, njb, cmdCmd, cmdata, BSONQCmdTask::delete_val); + njb->ejdbcmd(&task); + return scope.Close(njb->ejdbcmd_after(&task)); + } + } + static Handle s_query(const Arguments& args) { HandleScope scope; REQ_ARGS(3); @@ -975,6 +1007,9 @@ namespace ejdb { case cmdTxStatus: txctl((TxCmdTask*) task); break; + case cmdCmd: + ejdbcmd((BSONQCmdTask*) task); + break; default: assert(0); } @@ -1010,6 +1045,9 @@ namespace ejdb { case cmdTxStatus: txctl_after((TxCmdTask*) task); break; + case cmdCmd: + ejdbcmd_after((BSONQCmdTask*) task); + break; default: assert(0); } @@ -1328,6 +1366,30 @@ namespace ejdb { } } + + void ejdbcmd(BSONQCmdTask *task) { + if (!_check_state((EJBTask*) task)) { + return; + } + BSONQCmdData *cmdata = task->cmd_data; + std::vector &bsons = cmdata->bsons; + bson *qbs = bsons.front(); + assert(qbs); + TCLIST *res = tclistnew2(1); + bson *bret = ejdbcommand(m_jb, qbs); + assert(bret); + tclistpush(res, bson_data(bret), bson_size(bret)); + bson_del(bret); + cmdata->res = res; + cmdata->count = TCLISTNUM(cmdata->res); + cmdata->qflags = 0; + } + + Handle ejdbcmd_after(BSONQCmdTask *task) { + return query_after(task); + } + + void query(BSONQCmdTask *task) { if (!_check_state((EJBTask*) task)) { return; @@ -1495,6 +1557,7 @@ finish: NODE_SET_PROTOTYPE_METHOD(constructor_template, "setIndex", s_set_index); NODE_SET_PROTOTYPE_METHOD(constructor_template, "sync", s_sync); NODE_SET_PROTOTYPE_METHOD(constructor_template, "dbMeta", s_db_meta); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "command", s_cmd); NODE_SET_PROTOTYPE_METHOD(constructor_template, "_txctl", s_coll_txctl); //Symbols diff --git a/node/tests/t2.js b/node/tests/t2.js index 281cd55..5ec192e 100644 --- a/node/tests/t2.js +++ b/node/tests/t2.js @@ -269,7 +269,7 @@ module.exports.testCMeta = function(test) { test.equal(dm["file"], "var/tdbt2"); test.ok(dm["collections"]); test.ok(dm["collections"].constructor == Array); - var parrots = dm["collections"][0]; + var parrots = dm["collections"][1]; test.ok(parrots); test.equal(parrots["name"], "parrots"); //todo... @@ -446,6 +446,17 @@ module.exports.testFPIssue = function(test) { test.done(); }; +module.exports.testEJDBCommand = function(test) { + jb.command({ + "ping" : {} + }, function(err, pong) { + test.ifError(err); + test.ok(pong); + test.equal("pong", pong["log"]); + test.done(); + }) +}; + module.exports.testClose = function(test) { test.ok(jb); diff --git a/package.json b/package.json index b432d8f..285e372 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name" : "ejdb", - "version" : "1.1.13-1", + "version" : "1.1.14-1", "config" : { - "windownloadurl_ia32" : "http://dl.dropboxusercontent.com/u/4709222/ejdb/tcejdb-1.1.13-mingw32-i686.zip", - "windownloadurl_x64" : "http://dl.dropboxusercontent.com/u/4709222/ejdb/tcejdb-1.1.13-mingw32-x86_64.zip" + "windownloadurl_ia32" : "http://dl.dropboxusercontent.com/u/4709222/ejdb/tcejdb-1.1.14-mingw32-i686.zip", + "windownloadurl_x64" : "http://dl.dropboxusercontent.com/u/4709222/ejdb/tcejdb-1.1.14-mingw32-x86_64.zip" }, "main" : "node/ejdb.js", "homepage" : "http://ejdb.org", diff --git a/pyejdb/debian/changelog b/pyejdb/debian/changelog index 5da7df7..18f7992 100644 --- a/pyejdb/debian/changelog +++ b/pyejdb/debian/changelog @@ -1,3 +1,9 @@ +python-ejdb (1.0.15) testing; urgency=low + + * EJDB 1.1.14 + + -- Anton Adamansky Thu, 18 Jul 2013 18:00:55 +0700 + python-ejdb (1.0.14) testing; urgency=low * Critical bugfix: error on saving docs. diff --git a/pyejdb/debian/control b/pyejdb/debian/control index d439761..78f039e 100644 --- a/pyejdb/debian/control +++ b/pyejdb/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Anton Adamansky Build-Depends: debhelper (>= 9), - libtcejdb9-dev (>= 1.1.3), + libtcejdb9-dev (>= 1.1.14), python3-dev, python3-setuptools, python3-pkg-resources @@ -21,7 +21,7 @@ Depends: ${misc:Depends}, python3 (>= 3.2.0), ${shlibs:Depends}, - libtcejdb9 (>= 1.1.3) + libtcejdb9 (>= 1.1.14) Provides: ${python3:Provides} Description: Python3 binding for EJDB diff --git a/pyejdb/pyejdb.iml b/pyejdb/pyejdb.iml index 25c0933..1b2905f 100644 --- a/pyejdb/pyejdb.iml +++ b/pyejdb/pyejdb.iml @@ -19,7 +19,7 @@ - + diff --git a/pyejdb/pyejdb/__init__.py b/pyejdb/pyejdb/__init__.py index 8f80df5..de7f9a5 100644 --- a/pyejdb/pyejdb/__init__.py +++ b/pyejdb/pyejdb/__init__.py @@ -51,7 +51,7 @@ __all__ = [ "libejdb_version" ] -version_tuple = (1, 0, 11) +version_tuple = (1, 0, 15) def get_version_string(): return '.'.join(map(str, version_tuple)) @@ -185,6 +185,52 @@ class EJDB(object): def sync(self): return self.__ejdb.sync() + def command(self, cmd): + """ Executes ejdb database command. + + Supported commands: + + 1) Exports database collections data. See ejdbexport() method. + + "export" : { + "path" : string, //Exports database collections data + "cnames" : [string array]|null, //List of collection names to export + "mode" : int|null //Values: null|`JBJSONEXPORT` See ejdbexport() method + } + + Command response: + { + "log" : string, //Diagnostic log about executing this command + "error" : string|null, //ejdb error message + "errorCode" : int|0, //ejdb error code + } + + 2) Imports previously exported collections data into ejdb. + + "import" : { + "path" : string //The directory path in which data resides + "cnames" : [string array]|null, //List of collection names to import + "mode" : int|null //Values: null|`JBIMPORTUPDATE`|`JBIMPORTREPLACE` See ejdbimport() method + } + + Command response: + { + "log" : string, //Diagnostic log about executing this command + "error" : string|null, //ejdb error message + "errorCode" : int|0, //ejdb error code + } + + :Parameters: + - `cmd` Command object dictionary + + :Returns: + Command response object dictionary + """ + bret = self.__ejdb.command(bson.serialize_to_bytes(cmd)) + if bret is not None: + return bson.parse_bytes(bret) + return None + def save(self, cname, *jsarr, **kwargs): """ Save/update specified `dict` documents into collection `cname`. diff --git a/pyejdb/setup.py b/pyejdb/setup.py old mode 100755 new mode 100644 index 620193f..e5d8e0e --- a/pyejdb/setup.py +++ b/pyejdb/setup.py @@ -14,6 +14,7 @@ from distutils.core import setup, Extension, Command from ctypes.util import find_library from ctypes import cdll, c_char_p +from distutils.version import StrictVersion import sys import os @@ -81,11 +82,12 @@ def check_extension(ext): raise SystemExit(err_msg.format(ext.name, ext.min_ver, ext.url)) elif lib: curr_ver = c_char_p.in_dll(cdll.LoadLibrary(lib), ext.ver_char_p).value - if curr_ver.decode() < ext.min_ver: + if StrictVersion(curr_ver.decode()) < StrictVersion(ext.min_ver): raise SystemExit(err_msg.format(ext.name, ext.min_ver, ext.url)) + return lib -ejdb_ext = EJDBPythonExt(True, "tcejdb", "EJDB", "1.1", +ejdb_ext = EJDBPythonExt(True, "tcejdb", "EJDB", "1.1.14", "tcversion", "http://ejdb.org", "_pyejdb", ["src/pyejdb.c"], libraries=["tcejdb", "z", "pthread", "m", "c"], @@ -99,7 +101,7 @@ class build_ext(_build_ext): setup( name="pyejdb", - version="1.0.14", + version="1.0.15", url="http://ejdb.org", keywords=["ejdb", "tokyocabinet", "nosql", "database", "storage", "embedded", "mongodb", "json"], description="Python 2.7/3.x binding for EJDB database engine.", diff --git a/pyejdb/src/pejdb.c b/pyejdb/src/pejdb.c index e656c1a..ef02732 100644 --- a/pyejdb/src/pejdb.c +++ b/pyejdb/src/pejdb.c @@ -119,6 +119,30 @@ static PyObject* EJDB_ensureCollection(PEJDB *self, PyObject *args, PyObject *kw Py_RETURN_NONE; } +static PyObject* EJDB_command(PEJDB *self, PyObject *args) { + bson bscmd; + void *bsonbuf = NULL; + int bsonbufz; + PyObject *bsonbufpy; + bson *cmdret = NULL; + if (!PyArg_ParseTuple(args, "O:command", &bsonbufpy)) { + return NULL; + } + if (bytes_to_void(bsonbufpy, &bsonbuf, &bsonbufz)) { + return NULL; + } + bson_init_finished_data(&bscmd, bsonbuf); + bscmd.flags |= BSON_FLAG_STACK_ALLOCATED; + Py_BEGIN_ALLOW_THREADS + cmdret = ejdbcommand(self->ejdb, &bscmd); + Py_END_ALLOW_THREADS + + bson_destroy(&bscmd); + PyObject *docbytes = PyBytes_FromStringAndSize(bson_data(cmdret), bson_size(cmdret)); + bson_del(cmdret); + return docbytes; +} + static PyObject* EJDB_save(PEJDB *self, PyObject *args, PyObject *kwargs) { const char *cname; PyObject *merge = Py_False; @@ -588,6 +612,7 @@ static PyMethodDef EJDB_tp_methods[] = { {"setIndex", (PyCFunction) EJDB_setIndex, METH_VARARGS, NULL}, {"txcontrol", (PyCFunction) EJDB_txcontrol, METH_VARARGS, NULL}, {"dbmeta", (PyCFunction) EJDB_dbmeta, METH_VARARGS, NULL}, + {"command", (PyCFunction) EJDB_command, METH_VARARGS, NULL}, {NULL} }; diff --git a/pyejdb/test/test_one.py b/pyejdb/test/test_one.py index d53a3a1..d3901f0 100644 --- a/pyejdb/test/test_one.py +++ b/pyejdb/test/test_one.py @@ -186,6 +186,14 @@ class TestOne(unittest.TestCase): self.assertTrue(ejdb.findOne("upsertcoll", {"foo": "bar"}) is not None) + cmd = { + "ping" : {} + } + cmdret = ejdb.command(cmd) + self.assertIsNotNone(cmdret) + self.assertEquals(cmdret["log"], "pong") + + @classmethod def tearDownClass(cls): if cls._ejdb: diff --git a/tcejdb/Changelog b/tcejdb/Changelog index 2db1ca3..2754184 100644 --- a/tcejdb/Changelog +++ b/tcejdb/Changelog @@ -1,3 +1,10 @@ +libtcejdb (1.1.14) testing; urgency=low + + * Supports generic ejdb commands interface + * Export/Import database data implemented + + -- Anton Adamansky Thu, 18 Jul 2013 15:44:31 +0700 + libtcejdb (1.1.13) testing; urgency=low * .Net binding diff --git a/tcejdb/Makefile.in b/tcejdb/Makefile.in index a98d2f9..7de49f1 100644 --- a/tcejdb/Makefile.in +++ b/tcejdb/Makefile.in @@ -126,7 +126,8 @@ install : mkdir -p `dirname $(DESTDIR)$(INCLUDEDIR)/$(PACKAGE)/$(HF)`; \ $(INSTALL) -m 644 $(HF) $(DESTDIR)$(INCLUDEDIR)/$(PACKAGE)/$(HF); \ ) - $(INSTALL) -m 755 $(LIBRARYFILES) $(DESTDIR)$(LIBDIR) + chmod -R 755 $(LIBRARYFILES) + cp -Rf $(LIBRARYFILES) $(DESTDIR)$(LIBDIR) $(INSTALL) -m 644 $(DOCUMENTFILES) $(DESTDIR)$(DATADIR) $(INSTALL) -m 644 $(PCFILES) $(DESTDIR)$(PCDIR) ## mkdir -p $(DESTDIR)$(BINDIR) diff --git a/tcejdb/configure b/tcejdb/configure index 5d50661..8778233 100755 --- a/tcejdb/configure +++ b/tcejdb/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tcejdb 1.1.13. +# Generated by GNU Autoconf 2.69 for tcejdb 1.1.14. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tcejdb' PACKAGE_TARNAME='tcejdb' -PACKAGE_VERSION='1.1.13' -PACKAGE_STRING='tcejdb 1.1.13' +PACKAGE_VERSION='1.1.14' +PACKAGE_STRING='tcejdb 1.1.14' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1268,7 +1268,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tcejdb 1.1.13 to adapt to many kinds of systems. +\`configure' configures tcejdb 1.1.14 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1333,7 +1333,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tcejdb 1.1.13:";; + short | recursive ) echo "Configuration of tcejdb 1.1.14:";; esac cat <<\_ACEOF @@ -1439,7 +1439,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tcejdb configure 1.1.13 +tcejdb configure 1.1.14 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1737,7 +1737,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tcejdb $as_me 1.1.13, which was +It was created by tcejdb $as_me 1.1.14, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -5273,7 +5273,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tcejdb $as_me 1.1.13, which was +This file was extended by tcejdb $as_me 1.1.14, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5326,7 +5326,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tcejdb config.status 1.1.13 +tcejdb config.status 1.1.14 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/tcejdb/configure.ac b/tcejdb/configure.ac index 28e23ab..91b53f1 100644 --- a/tcejdb/configure.ac +++ b/tcejdb/configure.ac @@ -10,7 +10,7 @@ test -n "$CPPFLAGS" && MYCPPFLAGS="$CPPFLAGS $MYCPPFLAGS" test -n "$LDFLAGS" && MYLDFLAGS="$LDFLAGS $MYLDFLAGS" # Package name -AC_INIT(tcejdb, 1.1.13) +AC_INIT(tcejdb, 1.1.14) AC_CANONICAL_HOST # Package information diff --git a/tcejdb/debian/changelog b/tcejdb/debian/changelog index 2db1ca3..2754184 100644 --- a/tcejdb/debian/changelog +++ b/tcejdb/debian/changelog @@ -1,3 +1,10 @@ +libtcejdb (1.1.14) testing; urgency=low + + * Supports generic ejdb commands interface + * Export/Import database data implemented + + -- Anton Adamansky Thu, 18 Jul 2013 15:44:31 +0700 + libtcejdb (1.1.13) testing; urgency=low * .Net binding diff --git a/tcejdb/debian/libtcejdb9.symbols b/tcejdb/debian/libtcejdb9.symbols index 81e3024..63a468f 100644 --- a/tcejdb/debian/libtcejdb9.symbols +++ b/tcejdb/debian/libtcejdb9.symbols @@ -12,6 +12,7 @@ libtcejdb.so.9 libtcejdb9 #MINVER# _tc_md5_init@Base 1.1.8 _tc_recdecode@Base 1.1.8 _tc_recencode@Base 1.1.8 + bson2json@Base 1.1.14 bson_append32@Base 1.1.8 bson_append64@Base 1.1.8 bson_append@Base 1.1.8 @@ -161,14 +162,17 @@ libtcejdb.so.9 libtcejdb9 #MINVER# ejcollockmethod@Base 1.1.8 ejcollunlockmethod@Base 1.1.8 ejdbclose@Base 1.1.8 + ejdbcommand@Base 1.1.14 ejdbcreatecoll@Base 1.1.8 ejdbcreatequery2@Base 1.1.13 ejdbcreatequery@Base 1.1.8 ejdbdel@Base 1.1.8 ejdbecode@Base 1.1.8 ejdberrmsg@Base 1.1.8 + ejdbexport@Base 1.1.14 ejdbgetcoll@Base 1.1.8 ejdbgetcolls@Base 1.1.8 + ejdbimport@Base 1.1.14 ejdbisopen@Base 1.1.8 ejdbisvalidoidstr@Base 1.1.8 ejdbloadbson@Base 1.1.8 @@ -201,6 +205,13 @@ libtcejdb.so.9 libtcejdb9 #MINVER# hashmurmur32@Base 1.1.8 hashmurmur64@Base 1.1.8 initialBufferSize@Base 1.1.8 + json2bson@Base 1.1.14 + nx_json_free@Base 1.1.14 + nx_json_get@Base 1.1.14 + nx_json_item@Base 1.1.14 + nx_json_parse@Base 1.1.14 + nx_json_parse_utf8@Base 1.1.14 + nx_json_unicode_to_utf8@Base 1.1.14 set_bson_err_handler@Base 1.1.8 tcadbadddouble@Base 1.1.8 tcadbaddint@Base 1.1.8 @@ -533,6 +544,7 @@ libtcejdb.so.9 libtcejdb9 #MINVER# tchdbsetcodecfunc@Base 1.1.8 tchdbsetdbgfd@Base 1.1.8 tchdbsetdfunit@Base 1.1.8 + tchdbsetecode2@Base 1.1.14 tchdbsetecode@Base 1.1.8 tchdbsetmutex@Base 1.1.8 tchdbsettype@Base 1.1.8 @@ -892,6 +904,7 @@ libtcejdb.so.9 libtcejdb9 #MINVER# tctdbsetcodecfunc@Base 1.1.8 tctdbsetdbgfd@Base 1.1.8 tctdbsetdfunit@Base 1.1.8 + tctdbsetecode2@Base 1.1.14 tctdbsetecode@Base 1.1.8 tctdbsetindex@Base 1.1.8 tctdbsetindexrldr@Base 1.1.8 diff --git a/tcejdb/ejdb.c b/tcejdb/ejdb.c index a2ec5b1..d54d1c9 100644 --- a/tcejdb/ejdb.c +++ b/tcejdb/ejdb.c @@ -547,16 +547,16 @@ EJQRESULT ejdbqryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *count, int qflag _ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__); return NULL; } - JBCLOCKMETHOD(jcoll, (q->flags & EJQUPDATING) ? true : false); - _ejdbsetecode(jcoll->jb, TCESUCCESS, __FILE__, __LINE__, __func__); - if (ejdbecode(jcoll->jb) != TCESUCCESS) { //we are not in fatal state + JBCLOCKMETHOD(jcoll, (q->flags & EJQUPDATING) ? true : false); + _ejdbsetecode(jcoll->jb, TCESUCCESS, __FILE__, __LINE__, __func__); + if (ejdbecode(jcoll->jb) != TCESUCCESS) { //we are not in fatal state + JBCUNLOCKMETHOD(jcoll); + return NULL; + } + TCLIST *res = _qryexecute(jcoll, q, count, qflags, log); JBCUNLOCKMETHOD(jcoll); - return NULL; + return res; } - TCLIST *res = _qryexecute(jcoll, q, count, qflags, log); - JBCUNLOCKMETHOD(jcoll); - return res; -} int ejdbqresultnum(EJQRESULT qr) { return qr ? tclistnum(qr) : 0; @@ -900,6 +900,9 @@ bson* ejdbcommand(EJDB *jb, bson *cmd) { err = ejdberrmsg(ecode); } TCFREE(path); + } else if (!strcmp("ping", key)) { + xlog = tcxstrnew(); + tcxstrprintf(xlog, "pong"); } else { err = "Unknown command"; ecode = JBEINVALIDCMD; diff --git a/tcejdb/ejdb.h b/tcejdb/ejdb.h index 814f75d..d527f14 100644 --- a/tcejdb/ejdb.h +++ b/tcejdb/ejdb.h @@ -436,8 +436,10 @@ EJDB_EXPORT bool ejdbsetindex(EJCOLL *coll, const char *ipath, int flags); * @param jcoll EJDB database * @param q Query handle created with ejdbcreatequery() * @param count Output count pointer. Result set size will be stored into it. - * @param qflags Execution flag. If JBQRYCOUNT is set the only count of matching records will be computed - * without resultset, this operation is analog of count(*) in SQL and can be faster than operations with resultsets. + * @param qflags Execution flag. + * * `JBQRYCOUNT` The only count of matching records will be computed + * without resultset, this operation is analog of count(*) + * in SQL and can be faster than operations with resultsets. * @param log Optional extended string to collect debug information during query execution, can be NULL. * @return TCLIST with matched bson records data. * If (qflags & JBQRYCOUNT) then NULL will be returned diff --git a/tcejdb/tcutil.h b/tcejdb/tcutil.h index 6c40852..ec9acd6 100644 --- a/tcejdb/tcutil.h +++ b/tcejdb/tcutil.h @@ -3733,7 +3733,7 @@ typedef unsigned char TCBITMAP; /* type of a bit map object */ #include -#define _TC_VERSION "1.1.13" +#define _TC_VERSION "1.1.14" #define _TC_LIBVER 911 #define _TC_FORMATVER "1.0" -- 2.7.4