#51
authoradam <adamansky@gmail.com>
Sun, 10 Mar 2013 16:46:49 +0000 (23:46 +0700)
committeradam <adamansky@gmail.com>
Sun, 10 Mar 2013 16:46:49 +0000 (23:46 +0700)
.gitignore
luaejdb/luabson.c [new file with mode: 0644]
luaejdb/luabson.h [new file with mode: 0644]
luaejdb/luaejdb-1.0-1.rockspec
luaejdb/luaejdb.c

index e429056..df447b3 100644 (file)
@@ -97,3 +97,4 @@ tcejdb/debian/*.debhelper
 
 
 luaejdb/Makefile
+luaejdb/test/testdb*
diff --git a/luaejdb/luabson.c b/luaejdb/luabson.c
new file mode 100644 (file)
index 0000000..b05bc25
--- /dev/null
@@ -0,0 +1,139 @@
+
+#include "luabson.h"
+#include <lualib.h>
+#include <lauxlib.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);
+
+void lua_init_bson(lua_State *L) {
+    if (!lua_istable(L, -1)) {
+        return luaL_error(L, "luainitbson: Table must be on top of lua stack");
+    }
+    lua_pushcfunction(L, lua_from_bson);
+    lua_setfield(L, -2, "lua_from_bson");
+
+    lua_pushcfunction(L, lua_to_bson);
+    lua_setfield(L, -2, "lua_to_bson");
+}
+
+static int null_value(lua_State *L) {
+    lua_pushnil(L);
+    return 1;
+}
+
+void lua_push_bsontype_table(lua_State* L, int bsontype) {
+    lua_newtable(L); //table
+    lua_newtable(L); //metatable
+    lua_pushstring(L, "__bsontype");
+    lua_pushinteger(L, bsontype);
+    lua_settable(L, -3);
+    lua_setmetatable(L, -2);
+}
+
+static void lua_push_bson_value(lua_State *L, bson_iterator *it) {
+    bson_type bt = bson_iterator_type(it);
+    switch (bt) {
+        case BSON_OID:
+        {
+            char xoid[25];
+            bson_oid_to_string(bson_iterator_oid(it), xoid);
+            lua_pushstring(L, xoid);
+            break;
+        }
+        case BSON_STRING:
+        case BSON_SYMBOL:
+            lua_pushstring(L, bson_iterator_string(it));
+            break;
+        case BSON_NULL:
+        case BSON_UNDEFINED:
+            lua_pushnil(L);
+            break;
+        case BSON_INT:
+            lua_pushinteger(L, bson_iterator_int(it));
+            break;
+        case BSON_LONG:
+        case BSON_DOUBLE:
+            lua_pushnumber(L, (lua_Number) bson_iterator_double(it));
+            break;
+        case BSON_BOOL:
+            lua_pushboolean(L, bson_iterator_bool(it));
+            break;
+        case BSON_OBJECT:
+        case BSON_ARRAY:
+        {
+            bson_iterator nit;
+            bson_iterator_subiterator(it, &nit);
+            if (bt == BSON_OBJECT) {
+                lua_push_bson_table(L, &nit);
+            } else {
+                lua_push_bson_array(L, &nit);
+            }
+            break;
+        }
+        case BSON_DATE:
+        {
+            lua_push_bsontype_table(L, bt);
+            lua_pushnumber(L, bson_iterator_date(it));
+            lua_rawseti(L, -2, 1);
+            break;
+        }
+        case BSON_BINDATA:
+        {
+            lua_push_bsontype_table(L, bt);
+            lua_pushlstring(L, bson_iterator_bin_data(it), bson_iterator_bin_len(it));
+            break;
+        }
+        case BSON_REGEX:
+        {
+            const char *re = bson_iterator_regex(it);
+            const char *ro = bson_iterator_regex_opts(it);
+            lua_push_bsontype_table(L, bt);
+            lua_pushstring(L, re);
+            lua_rawseti(L, -2, 1);
+            lua_pushstring(L, ro);
+            lua_rawseti(L, -2, 2);
+            break;
+        }
+        default:
+            break;
+
+    }
+}
+
+static 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_pushstring(L, bson_iterator_key(it));
+        lua_push_bson_value(L, it);
+        lua_rawset(L, -3);
+    }
+}
+
+static void lua_push_bson_array(lua_State *L, bson_iterator *it) {
+    bson_type bt;
+    lua_push_bsontype_table(L, BSON_ARRAY);
+    for (int i = 1; (bt = bson_iterator_next(it)) != BSON_EOO; ++i) {
+        lua_push_bson_value(L, it);
+        lua_rawseti(L, -2, i);
+    }
+}
+
+int lua_from_bson(lua_State *L) {
+    const void *bsdata = lua_tostring(L, -1);
+    if (!bsdata) {
+        return luaL_error(L, "luafrombson: BSON binary string must be on top of stack");
+    }
+    bson_iterator it;
+    bson_iterator_from_buffer(&it, bsdata);
+    lua_push_bson_table(L, &it);
+    return 0;
+}
+
+int lua_to_bson(lua_State *L) {
+    return 0;
+}
+
+
diff --git a/luaejdb/luabson.h b/luaejdb/luabson.h
new file mode 100644 (file)
index 0000000..4a97d53
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * File:   luabson.h
+ * Author: adam
+ *
+ * Created on March 10, 2013, 5:11 PM
+ */
+
+#ifndef LUABSON_H
+#define        LUABSON_H
+
+#include <lua.h>
+#include <tcejdb/bson.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    void lua_init_bson(lua_State *L);
+    int lua_from_bson(lua_State *L);
+    int lua_to_bson(lua_State *L);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LUABSON_H */
+
index cf0778b..f0c87c7 100644 (file)
@@ -29,7 +29,7 @@ build = {
     ["ejdb"]  = "ejdb.lua",
     ["bson"] = "bson.lua",
     ["luaejdb"] = {
-       sources = {"luaejdb.c"},
+       sources = {"luaejdb.c", "luabson.c"},
        libraries = {"tcejdb"} ,
        incdirs = {"$(LIBTCEJDB_INCDIR)"},
        libdirs = {"$(LIBTCEJDB_LIBDIR)"}
index f3c21b6..4bf3b18 100644 (file)
@@ -4,9 +4,12 @@
 #include <lauxlib.h>
 #include <tcejdb/ejdb.h>
 
+#include "luabson.h"
+
 #define EJDBLIBNAME    "luaejdb"
 #define EJDBUDATAKEY "__ejdb__"
 #define EJDBUDATAMT "mt.ejdb.db"
+#define EJDBCURSORMT "mt.ejdb.cur"
 
 #define DEFAULT_OPEN_MODE (JBOWRITER | JBOCREAT | JBOTSYNC)
 
@@ -28,10 +31,14 @@ typedef struct {
     EJDB *db;
 } EJDBDATA;
 
+typedef struct {
+    TCLIST *res;
+} CURSORDATA;
+
 #define EJDBERR(_L, _DB) \
     return luaL_error((_L), "EJDB ERROR %d|%s", ejdbecode(_DB), ejdberrmsg(ejdbecode(_DB)))
 
-static void initdbconsts(lua_State *L) {
+static void init_db_consts(lua_State *L) {
     if (!lua_istable(L, -1)) {
         luaL_error(L, "Table must be on top of lua stack");
     }
@@ -54,7 +61,28 @@ static void initdbconsts(lua_State *L) {
     TBLSETNUMCONST(DEFAULT_OPEN_MODE);
 }
 
-int dbdel(lua_State *L) {
+static int cursor_del(lua_State *L) {
+    CURSORDATA *cdata = luaL_checkudata(L, 1, EJDBCURSORMT);
+    if (cdata->res) {
+        tclistdel(cdata->res);
+        cdata->res = NULL;
+    }
+    return 0;
+}
+
+static int cursor_field(lua_State *L) {
+    return 0;
+}
+
+static int cursor_object(lua_State *L) {
+    return 0;
+}
+
+static int cursor_iter(lua_State *L) {
+    return 0;
+}
+
+static int db_del(lua_State *L) {
     EJDBDATA *data = luaL_checkudata(L, 1, EJDBUDATAMT);
     EJDB *db = data->db;
     if (db) {
@@ -64,7 +92,7 @@ int dbdel(lua_State *L) {
     return 0;
 }
 
-int dbclose(lua_State *L) {
+static int db_close(lua_State *L) {
     luaL_checktype(L, 1, LUA_TTABLE); //self
     lua_getfield(L, 1, EJDBUDATAKEY);
     EJDBDATA *data = luaL_checkudata(L, -1, EJDBUDATAMT);
@@ -77,33 +105,40 @@ int dbclose(lua_State *L) {
     return 0;
 }
 
-int find(lua_State *L) {
+static int db_find(lua_State *L) {
     //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);
     const char *cname = luaL_checkstring(L, 2); //collections name
-    const char *qbson = luaL_checkstring(L, 3); //Query bson
+    const char *qbsonbuf = luaL_checkstring(L, 3); //Query bson
     luaL_checktype(L, 4, LUA_TTABLE); //or joined
-    const char *hbson = luaL_checkstring(L, 5); //Hints bson
-    if (!data || !data->db || !qbson || !hbson) {
-        luaL_error(L, "Illegal arguments");
+    const char *hbsonbuf = luaL_checkstring(L, 5); //Hints bson
+    if (!data || !data->db || !qbsonbuf || !hbsonbuf) {
+        return luaL_error(L, "Illegal arguments");
     }
+    bson oqarrstack[8]; //max 8 $or bsons on stack
+    bson *oqarr = NULL;
+    bson qbson = {NULL};
+    bson hbson = {NULL};
+    EJQ *q = NULL;
     EJDB *db = data->db;
+    EJCOLL *coll = NULL;
+    uint32_t count = 0;
 
-
+    //lua_objlen(L, 4)
 
     //bson_print_raw(stderr, hbson, 0);
 
-
     return 0;
 }
 
-int dbopen(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;
 
+    //DB table
     lua_newtable(L);
     EJDB *db = ejdbnew();
     if (!db) {
@@ -117,23 +152,19 @@ int dbopen(lua_State *L) {
     EJDBDATA *udb = lua_newuserdata(L, sizeof (*udb));
     udb->db = db;
     luaL_newmetatable(L, EJDBUDATAMT);
-    lua_setmetatable(L, -2);
-    lua_setfield(L, -2, EJDBUDATAKEY); //pop userdata
-
-    //Metatable
-    lua_newtable(L);
-    lua_pushcfunction(L, dbdel);
+    lua_pushcfunction(L, db_del);
     lua_setfield(L, -2, "__gc");
     lua_setmetatable(L, -2);
+    lua_setfield(L, -2, EJDBUDATAKEY); //pop userdata
 
     //Add constants
-    initdbconsts(L);
+    init_db_consts(L);
 
     //Add methods
-    lua_pushcfunction(L, dbclose);
+    lua_pushcfunction(L, db_close);
     lua_setfield(L, -2, "close");
 
-    lua_pushcfunction(L, find);
+    lua_pushcfunction(L, db_find);
     lua_setfield(L, -2, "_find");
 
     if (lua_gettop(L) - argc != 1) {
@@ -141,17 +172,37 @@ int dbopen(lua_State *L) {
         udb->db = NULL;
         return luaL_error(L, "Invalid stack state %d", lua_gettop(L));
     }
+    if (!lua_istable(L, -1)) {
+        ejdbdel(db);
+        udb->db = NULL;
+        return luaL_error(L, "Table must be on top of lua stack");
+    }
     return 1;
 }
 
 /* Init */
 int luaopen_luaejdb(lua_State *L) {
     lua_settop(L, 0);
+
+
+    lua_newtable(L);
+    lua_init_bson(L);
+    init_db_consts(L);
+
+    lua_pushcfunction(L, db_open);
+    lua_setfield(L, -2, "open");
+
+    //Push cursor methods into metatable
+    luaL_newmetatable(L, EJDBCURSORMT);
     lua_newtable(L);
-    initdbconsts(L);
-    lua_pushstring(L, "open");
-    lua_pushcfunction(L, dbopen);
-    lua_settable(L, -3);
+    lua_pushcfunction(L, cursor_object);
+    lua_setfield(L, -2, "object");
+    lua_pushcfunction(L, cursor_field);
+    lua_setfield(L, -2, "field");
+    lua_setfield(L, -2, "__index");
+    lua_settop(L, 1);
+
+
     return 1;
 }