#51
authoradam <adamansky@gmail.com>
Wed, 13 Mar 2013 17:37:55 +0000 (00:37 +0700)
committeradam <adamansky@gmail.com>
Wed, 13 Mar 2013 17:37:55 +0000 (00:37 +0700)
luaejdb/ejdb.lua
luaejdb/luabson.c
luaejdb/luabson.h
luaejdb/test/t1.lua

index f1b7324..eb0a936 100644 (file)
@@ -4,7 +4,7 @@ local inspect = require("inspect")
 
 -- ------------ Misc -----------------------
 
-function strim(s)
+local function strim(s)
   local from = s:match("^%s*()")
   return from > #s and "" or s:match(".*%S", from)
 end
@@ -127,8 +127,11 @@ function DB:find(cname, q, ...)
     flags = 0
   end
   local orBsons = {}
-  for _, o in ipairs(q:getJoinedORs()) do
-    table.insert(orBsons, o.toBSON())
+  local ors = q:getJoinedORs()
+  if ors then
+    for _, o in ipairs(ors) do
+      table.insert(orBsons, o.toBSON())
+    end
   end
   return self:_find(cname, q:toBSON(), orBsons, q:toHintsBSON(), flags)
 end
@@ -141,6 +144,7 @@ function B:_init(fname, ...)
   self._hints = nil -- hints Q
   self._omap = {} -- field operations
   self._oarr = {} -- resulting array of field operations
+  self._bson = nil -- cached bson
   if fname then
     self:F(fname, ...)
   end
@@ -192,6 +196,7 @@ function B:_setop(op, val, ...)
   else
     table.insert(olist, { op, val })
   end
+  self._bson = nil
 end
 
 function B:_toOpVal(op, val)
@@ -281,6 +286,7 @@ function B:DropAll() return self:_rootOp("$dropall", true) end
 function B:Do(val) return self:_rootOp("$do", val) end
 
 function B:Or(...)
+  self._or = self._or or {}
   for i, v in ipairs({ ... }) do
     assert(getmetatable(v) == mtBObj, "Each 'or' argument must be instance of 'luaejdb.B' class")
     table.insert(self._or, v)
@@ -362,7 +368,12 @@ function B:toHintsBSON()
 end
 
 function B:toBSON()
-  return luaejdb.to_bson(self)
+  if self._bson then
+    return self._bson
+  else
+    self._bson = luaejdb.to_bson(self)
+    return self._bson
+  end
 end
 
 luaejdb.B = setmetatable(B, {
index eaf3a27..b540d0a 100644 (file)
@@ -4,11 +4,13 @@
 #include <lauxlib.h>
 #include <math.h>
 #include <string.h>
+#include <tcejdb/tcutil.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);
 
 void lua_init_bson(lua_State *L) {
     if (!lua_istable(L, -1)) {
@@ -21,6 +23,22 @@ void lua_init_bson(lua_State *L) {
     lua_pushcfunction(L, lua_to_bson);
     lua_setfield(L, -2, "to_bson");
 
+    lua_pushcfunction(L, print_bson);
+    lua_setfield(L, -2, "print_bson");
+
+}
+
+int print_bson(lua_State *L) {
+    size_t slen = 0;
+    const void *bsdata = luaL_checklstring(L, lua_gettop(L), &slen);
+    if (slen <= 4 || !bsdata) {
+        return luaL_error(L, "Invalid bson string at argument #1");
+    }
+    TCXSTR *xstr = tcxstrnew();
+    bson_print_xstr(xstr, bsdata, 0);
+    lua_pushstring(L, TCXSTRPTR(xstr));
+    tcxstrdel(xstr);
+    return 1;
 }
 
 //-0/+1
@@ -407,3 +425,87 @@ static void lua_to_bson_impl(lua_State *L, int tpos, bson *bs) {
     lua_val_to_bson(L, NULL, lua_gettop(L), bs, tref);
     lua_unref(L, tref);
 }
+
+static void bson_print_xstr(TCXSTR* xstr, const char *data, int depth) {
+    bson_iterator i;
+    const char *key;
+    int temp;
+    bson_timestamp_t ts;
+    char oidhex[25];
+    bson scope;
+    bson_iterator_from_buffer(&i, data);
+
+    while (bson_iterator_next(&i)) {
+        bson_type t = bson_iterator_type(&i);
+        if (t == 0)
+            break;
+        key = bson_iterator_key(&i);
+
+        for (temp = 0; temp <= depth; temp++) {
+            tcxstrprintf(xstr, ".");
+        }
+        tcxstrprintf(xstr, "%s(%d)=", key, t);
+        switch (t) {
+            case BSON_DOUBLE:
+                tcxstrprintf(xstr, "%f", bson_iterator_double(&i));
+                break;
+            case BSON_STRING:
+                tcxstrprintf(xstr, "%s", bson_iterator_string(&i));
+                break;
+            case BSON_SYMBOL:
+                tcxstrprintf(xstr, "SYMBOL: %s", bson_iterator_string(&i));
+                break;
+            case BSON_OID:
+                bson_oid_to_string(bson_iterator_oid(&i), oidhex);
+                tcxstrprintf(xstr, "%s", oidhex);
+                break;
+            case BSON_BOOL:
+                tcxstrprintf(xstr, "%s", bson_iterator_bool(&i) ? "true" : "false");
+                break;
+            case BSON_DATE:
+                tcxstrprintf(xstr, "%ld", (long int) bson_iterator_date(&i));
+                break;
+            case BSON_BINDATA:
+                tcxstrprintf(xstr, "BSON_BINDATA");
+                break;
+            case BSON_UNDEFINED:
+                tcxstrprintf(xstr, "BSON_UNDEFINED");
+                break;
+            case BSON_NULL:
+                tcxstrprintf(xstr, "BSON_NULL");
+                break;
+            case BSON_REGEX:
+                tcxstrprintf(xstr, "BSON_REGEX: %s", bson_iterator_regex(&i));
+                break;
+            case BSON_CODE:
+                tcxstrprintf(xstr, "BSON_CODE: %s", bson_iterator_code(&i));
+                break;
+            case BSON_CODEWSCOPE:
+                tcxstrprintf(xstr, "BSON_CODE_W_SCOPE: %s", bson_iterator_code(&i));
+                /* 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_destroy( &scope ); */ /* review - causes free error */
+                break;
+            case BSON_INT:
+                tcxstrprintf(xstr, "%d", bson_iterator_int(&i));
+                break;
+            case BSON_LONG:
+                tcxstrprintf(xstr, "%lld", (uint64_t) bson_iterator_long(&i));
+                break;
+            case BSON_TIMESTAMP:
+                ts = bson_iterator_timestamp(&i);
+                tcxstrprintf(xstr, "i: %d, t: %d", ts.i, ts.t);
+                break;
+            case BSON_OBJECT:
+            case BSON_ARRAY:
+                tcxstrprintf(xstr, "\n");
+                bson_print_xstr(xstr, bson_iterator_value(&i), depth + 1);
+                break;
+            default:
+                fprintf(stderr, "can't print type : %d\n", t);
+        }
+        tcxstrprintf(xstr, "\n");
+    }
+}
index ce94e47..842b093 100644 (file)
@@ -18,7 +18,8 @@ extern "C" {
     void lua_init_bson(lua_State *L);
     int lua_from_bson(lua_State *L);
     int lua_to_bson(lua_State *L);
-    
+    int print_bson(lua_State *L);
+
 #ifdef __cplusplus
 }
 #endif
index f57a979..6c869a4 100644 (file)
@@ -12,8 +12,31 @@ local Q = ejdb.Q
 local db = ejdb:open("testdb");
 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);
 
-print(inspect(q._oarr))
-print(db:find("mycoll", q))
+local sv = ejdb.print_bson(q:toBSON());
+local ev = [[.name(2)=Andy
+._id(7)=510f7fa91ad6270a00000000
+.age(3)=
+..$gt(16)=20
+..$lt(16)=40
+
+.score(3)=
+..$in(4)=
+...1(16)=11
+...2(1)=22.123330
+...3(18)=1362835380447
+...4(10)=BSON_NULL
+
+
+]]
+assert(sv == ev)
+
+sv = q:toBSON();
+print(inspect(ejdb.from_bson(sv)))
+
+
+
+--print(inspect(q._oarr))
+--print(db:find("mycoll", q))
 
 db:close()