function luaejdb.toOID(val)
- assert(type(val) == "string" and #val == 24)
+ luaejdb.check_valid_oid_string(val)
return setmetatable({ val }, mtBSON_OID);
end
#include <lauxlib.h>
#include <math.h>
#include <string.h>
-#include <tcejdb/tcutil.h>
+#include <tcejdb/ejdb.h>
static void lua_push_bson_value(lua_State *L, bson_iterator *it);
-static void lua_push_bson_table(lua_State *L, bson_iterator *it);
static void lua_push_bson_array(lua_State *L, bson_iterator *it);
static void lua_to_bson_impl(lua_State *L, int spos, bson *bs);
static void bson_print_xstr(TCXSTR* xstr, const char *data, int depth);
lua_pushcfunction(L, print_bson);
lua_setfield(L, -2, "print_bson");
+ lua_pushcfunction(L, check_valid_oid_string);
+ lua_setfield(L, -2, "check_valid_oid_string");
+}
+
+int check_valid_oid_string(lua_State *L) {
+ bool ret = false;
+ if (lua_type(L, 1) == LUA_TSTRING) {
+ ret = ejdbisvalidoidstr(lua_tostring(L, -1));
+ }
+ if (!ret) {
+ return luaL_error(L, "OID is not valid");
+ }
+ return 0;
}
int print_bson(lua_State *L) {
}
}
-static void lua_push_bson_table(lua_State *L, bson_iterator *it) {
+void lua_push_bson_table(lua_State *L, bson_iterator *it) {
bson_type bt;
lua_push_bsontype_table(L, BSON_OBJECT);
while ((bt = bson_iterator_next(it)) != BSON_EOO) {
lua_pop(L, 1); //-oarr
} else {
if (key) bson_append_start_object(bs, key);
- for (lua_pushnil(L); lua_next(L, vpos); lua_pop(L, 1)) {
- int ktype = lua_type(L, -2);
- if (ktype == LUA_TNUMBER) {
- char vkey[TCNUMBUFSIZ];
- bson_numstrn(vkey, TCNUMBUFSIZ, (int64_t) lua_tointeger(L, -2));
- lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref);
- } else if (ktype == LUA_TSTRING) {
- size_t klen = 0;
- const char *vkey = lua_tolstring(L, -2, &klen);
- if (key == NULL && klen == JDBIDKEYNAMEL && !strcmp(JDBIDKEYNAME, vkey)) { //root level OID as string
- //pack OID as type table
- lua_push_bsontype_table(L, BSON_OID); //+type table
- lua_pushvalue(L, -2); //dup oid on stack
- lua_rawseti(L, -2, 1); //pop oid val
+ TCLIST *keys = tclistnew();
+ //we need to sort keys due to unordered nature of lua tables
+ for (lua_pushnil(L); lua_next(L, vpos);) {
+ lua_pop(L, 1); //-val
+ size_t ksize = 0;
+ int ktype = lua_type(L, -1);
+ if (ktype == LUA_TSTRING) { //accept only string keys
+ const char* key = lua_tolstring(L, -1, &ksize);
+ tclistpush(keys, key, ksize);
+ }
+ }
+ tclistsort(keys);
+ for (int i = 0; i < TCLISTNUM(keys); ++i) {
+ int vkeysz = TCLISTVALSIZ(keys, i);
+ const char *vkey = TCLISTVALPTR(keys, i);
+ lua_pushlstring(L, vkey, vkeysz);
+ lua_rawget(L, vpos); //+val
+ if (key == NULL && lua_type(L, -1) == LUA_TSTRING &&
+ vkeysz == JDBIDKEYNAMEL && !strcmp(JDBIDKEYNAME, vkey)) { //root level OID as string
+ //pack OID as type table
+ lua_push_bsontype_table(L, BSON_OID); //+type table
+ lua_pushvalue(L, -2); //dup oid(val) on stack
+ lua_rawseti(L, -2, 1); //pop oid val
+ if (ejdbisvalidoidstr(lua_tostring(L, -2))) {
+ lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref);
+ } else {
+ luaL_error(L, "OID _id='%s' is not valid", lua_tostring(L, -2));
}
+ lua_pop(L, 1); //-type table
+ } else {
lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref);
}
+ lua_pop(L, 1); //-val
}
+ tclistdel(keys);
if (key) bson_append_finish_object(bs);
}
} else { //metafield __bsontype on top
int lua_from_bson(lua_State *L);
int lua_to_bson(lua_State *L);
int print_bson(lua_State *L);
+ int check_valid_oid_string(lua_State *L);
void lua_push_bsontype_table(lua_State* L, int bsontype);
+ void lua_push_bson_table(lua_State *L, bson_iterator *it);
#ifdef __cplusplus
}
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;
+ EJDB *jb = ((EJDBDATA*) luaL_checkudata(L, -1, EJDBUDATAMT))->db;
+ lua_pop(L, 1);
const char *cname = luaL_checkstring(L, 2); //collections name
bson bsonval;
const char *bsonbuf = luaL_checkstring(L, 3); //Object to save
lua_pushstring(L, xoid);
bson_destroy(&bsonval);
- if (lua_gettop(L) - argc != 2) { //got +lua_getfield(L, 1, EJDBUDATAKEY)
+ if (lua_gettop(L) - argc != 1) { //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_load(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;
+ lua_pop(L, 1);
+
+ const char *cname = luaL_checkstring(L, 2);
+ bson_oid_t oid;
+ memset(&oid, 0, sizeof(oid));
+
+ if (lua_type(L, 3) == LUA_TSTRING) {
+ const char *soid = lua_tostring(L, 3);
+ if (ejdbisvalidoidstr(soid)) {
+ bson_oid_from_string(&oid, soid);
+ }
+ } else if (luaL_getmetafield(L, 3, "__bsontype") && lua_tointeger(L, -1) == BSON_OID) {
+ lua_pop(L, 1);
+ lua_rawgeti(L, 3, 1);
+ const char *soid = lua_tostring(L, -1);
+ if (ejdbisvalidoidstr(soid)) {
+ bson_oid_from_string(&oid, soid);
+ }
+ lua_pop(L, 1);
+ }
+ if (!oid.ints[0] && !oid.ints[1] && !oid.ints[2]) {
+ return luaL_error(L, "Invalid OID arg #2");
+ }
+ EJCOLL *coll = ejdbgetcoll(jb, cname);
+ if (!coll) {
+ lua_pushnil(L);
+ goto finish;
+ }
+ bson *bs = ejdbloadbson(coll, &oid);
+ 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_save: Invalid stack size: %d should be: %d", (lua_gettop(L) - argc), 1);
}
return 1;
//cname, q.toBSON(), orBsons, q.toHintsBSON(), flags
luaL_checktype(L, 1, LUA_TTABLE); //self
lua_getfield(L, 1, EJDBUDATAKEY);
- EJDBDATA *data = luaL_checkudata(L, -1, EJDBUDATAMT);
+ EJDB *jb = ((EJDBDATA*) luaL_checkudata(L, -1, EJDBUDATAMT))->db;
+ lua_pop(L, 1);
const char *cname = luaL_checkstring(L, 2); //collections name
const char *qbsonbuf = luaL_checkstring(L, 3); //Query bson
luaL_checktype(L, 4, LUA_TTABLE); //or joined
const char *hbsonbuf = luaL_checkstring(L, 5); //Hints bson
- if (!data || !data->db || !qbsonbuf || !hbsonbuf) {
+ if (!jb || !qbsonbuf || !hbsonbuf) {
return luaL_error(L, "Illegal arguments");
}
bson oqarrstack[8]; //max 8 $or bsons on stack
bson qbson = {NULL};
bson hbson = {NULL};
EJQ *q = NULL;
- EJDB *jb = data->db;
EJCOLL *coll = NULL;
uint32_t count = 0;
lua_pushcfunction(L, db_save);
lua_setfield(L, -2, "_save");
+ lua_pushcfunction(L, db_load);
+ lua_setfield(L, -2, "load");
+
lua_pushcfunction(L, db_find);
lua_setfield(L, -2, "_find");
local ejdb = require("ejdb")
assert(type(ejdb) == "table")
+assert(not pcall(function() ejdb.check_valid_oid_string("sss") end));
+assert(pcall(function() ejdb.check_valid_oid_string("510f7fa91ad6270a00000000") end));
+
local Q = ejdb.Q
local B = ejdb.B
assert(obj.bdate[1] == 1362835380447)
assert(type(obj.dst) == "table" and getmetatable(obj.dst).__bsontype == db.BSON_NULL)
+assert([[._id(7)=510f7fa91ad6270a00000000
+.a(16)=2
+.c(2)=d
+.dd(3)=
+..c(16)=1
+..f(2)=v1
+..gt(8)=true
+
+.ee(2)=t
+]] == ejdb.print_bson(ejdb.to_bson({ c = "d", a = 2, _id = "510f7fa91ad6270a00000000", dd = { f = "v1", gt = true, c = 1 }, ee = "t" })))
+
-- Test save
--
-local oid = db:save("mycoll", {foo="bar"});
+local oid = db:save("mycoll", { foo = "bar" });
assert(oid and #oid == 24)
-oid = db:save("mycoll", B("foo2","bar2"));
+oid = db:save("mycoll", B("foo2", "bar2"):KV("g", "d"):KV("e", 1):KV("a", "g"));
assert(oid and #oid == 24)
+obj = db:load("mycoll", oid)
+print(inspect(obj));
+
db:close()
#include <stdio.h>
-#define _TC_VERSION "1.0.65"
+#define _TC_VERSION "1.0.66"
#define _TC_LIBVER 911
#define _TC_FORMATVER "1.0"