#88
authoradam <adamansky@gmail.com>
Thu, 1 Aug 2013 16:24:32 +0000 (23:24 +0700)
committeradam <adamansky@gmail.com>
Thu, 1 Aug 2013 16:24:32 +0000 (23:24 +0700)
tcejdb/bson.c
tcejdb/ejdb.c
tcejdb/testejdb/t2.c

index ed2bfcc..93f7016 100644 (file)
@@ -1453,26 +1453,48 @@ static bson_visitor_cmd_t _bson_merge3_visitor(const char *ipath, int ipathlen,
     assert(ctx && ctx->bsout && ctx->mfields && ipath && key && it && op);
     const void *buf;
     int bufsz;
-    buf = TCMAPRNUM(ctx->mfields) == 0 ? NULL : tcmapget(ctx->mfields, ipath, ipathlen, &bufsz);
+    bson_type bt = bson_iterator_type(it);
+    buf = (TCMAPRNUM(ctx->mfields) == 0) ? NULL : tcmapget(ctx->mfields, ipath, ipathlen, &bufsz);
     if (buf) {
         bson_iterator it2;
         bson_iterator_from_buffer(&it2, ctx->bsdata2);
-        const char *it2start = it2.cur;
         off_t it2off;
         assert(bufsz == sizeof (it2off));
         memcpy(&it2off, buf, sizeof (it2off));
         assert(it2off >= 0);
-        it2.cur = it2start + it2off;
+        it2.cur = it2.cur + it2off;
         it2.first = (it2off == 0);
         tcmapout(ctx->mfields, ipath, ipathlen);
         bson_append_field_from_iterator2(key, &it2, ctx->bsout);
+        return (BSON_VCMD_SKIP_AFTER | BSON_VCMD_SKIP_NESTED);
     } else {
-        bson_append_field_from_iterator(it, ctx->bsout);
+        if (bt == BSON_OBJECT || bt == BSON_ARRAY) {
+            if (!after) {
+                ctx->nstack++;
+                if (bt == BSON_OBJECT) {
+                    bson_append_start_object2(ctx->bsout, key, keylen);
+                } else if (bt == BSON_ARRAY) {
+                    bson_append_start_array2(ctx->bsout, key, keylen);
+                }
+                return BSON_VCMD_OK;
+            } else {
+                if (ctx->nstack > 0) {
+                    ctx->nstack--;
+                    if (bt == BSON_OBJECT) {
+                        bson_append_finish_object(ctx->bsout);
+                    } else if (bt == BSON_ARRAY) {
+                        bson_append_finish_array(ctx->bsout);
+                    }
+                }
+                return BSON_VCMD_OK;
+            }
+        } else {
+            bson_append_field_from_iterator(it, ctx->bsout);
+            return BSON_VCMD_SKIP_AFTER;
+        }
     }
-    return (BSON_VCMD_SKIP_AFTER | BSON_VCMD_SKIP_NESTED);
 }
 
-
 //merge with fpath support
 
 int bson_merge3(const void *bsdata1, const void *bsdata2, bson *out) {
@@ -1490,7 +1512,7 @@ int bson_merge3(const void *bsdata1, const void *bsdata2, bson *out) {
         .matched = 0,
         .nstack = 0
     };
-    //collect fpaths of active bsons
+    //collect active fpaths
     while ((bt = bson_iterator_next(&it2)) != BSON_EOO) {
         const char* key = bson_iterator_key(&it2);
         off_t it2off = (it2.cur - it2start);
@@ -1525,7 +1547,7 @@ int bson_merge3(const void *bsdata1, const void *bsdata2, bson *out) {
             }
             keylen = (rp - fp);
             memcpy(key, fp, keylen);
-            key[keylen + 1] = '\0';
+            key[keylen] = '\0';
             rp++;
             fplen -= keylen;
 
@@ -1566,7 +1588,7 @@ int bson_merge3(const void *bsdata1, const void *bsdata2, bson *out) {
         }
     }
     tcmapdel(mfields);
-    return BSON_OK;
+    return out->err;
 }
 
 int bson_merge2(const void *b1data, const void *b2data, bson_bool_t overwrite, bson *out) {
index 5460fad..4158ce1 100644 (file)
@@ -2309,9 +2309,9 @@ static bson_visitor_cmd_t _bsonstripvisitor_exclude(const char *ipath, int ipath
                     if (i == ipathlen) { //ipath prefixes some exclude object field
                         ictx->nstack++;
                         if (bt == BSON_OBJECT) {
-                            bson_append_start_object(ictx->sbson, key);
+                            bson_append_start_object2(ictx->sbson, key, keylen);
                         } else if (bt == BSON_ARRAY) {
-                            bson_append_start_array(ictx->sbson, key);
+                            bson_append_start_array2(ictx->sbson, key, keylen);
                         }
                         return (BSON_VCMD_OK);
                     }
@@ -2378,9 +2378,9 @@ static bson_visitor_cmd_t _bsonstripvisitor_include(const char *ipath, int ipath
                     if (i == ipathlen) { //ipath prefixes some included field
                         ictx->nstack++;
                         if (bt == BSON_OBJECT) {
-                            bson_append_start_object(ictx->sbson, key);
+                            bson_append_start_object2(ictx->sbson, key, keylen);
                         } else if (bt == BSON_ARRAY) {
-                            bson_append_start_array(ictx->sbson, key);
+                            bson_append_start_array2(ictx->sbson, key, keylen);
                         } else {
                             assert(0);
                         }
@@ -2666,7 +2666,8 @@ static bool _qryupdate(EJCOLL *jcoll, const EJQ *ejq, void *bsbuf, int bsbufsz,
     if (setqf) { //$set
         update = true;
         bson_init_size(&bsout, bsbufsz);
-        if (bson_merge2(bsbuf, bson_data(setqf->updateobj), true, &bsout)) {
+        int err = bson_merge3(bsbuf, bson_data(setqf->updateobj), &bsout);
+        if (err) {
             rv = false;
             _ejdbsetecode(jcoll->jb, JBEQUPDFAILED, __FILE__, __LINE__, __func__);
         }
index 235178d..aaf4b38 100644 (file)
@@ -2983,10 +2983,12 @@ void testUpdate1() { //https://github.com/Softmotions/ejdb/issues/9
     CU_ASSERT_FALSE_FATAL(bsq1.err);
 
     EJQ *q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL);
+    CU_ASSERT_TRUE(ejdbecode(jb) == 0);
     CU_ASSERT_PTR_NOT_NULL_FATAL(q1);
     uint32_t count = 0;
     TCXSTR *log = tcxstrnew();
     TCLIST *q1res = ejdbqryexecute(coll, q1, &count, 0, log);
+    CU_ASSERT_TRUE(ejdbecode(jb) == 0);
     //fprintf(stderr, "%s", TCXSTRPTR(log));
     CU_ASSERT_EQUAL(1, count);
     CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "UPDATING MODE: YES"));