From 9edbbb8a34f43691d65c488206235dca69c5842f Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 24 Dec 2012 12:42:57 +0700 Subject: [PATCH] better arrays handling, working for #10 --- Changelog | 4 +++ package.json | 2 +- tcejdb/configure | 18 ++++++------ tcejdb/configure.ac | 2 +- tcejdb/ejdb.c | 9 ++---- tcejdb/testejdb/t2.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 89 insertions(+), 25 deletions(-) diff --git a/Changelog b/Changelog index dff55a6..e481ebb 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +2012-12-24 Anton Adamansky. + * Better array query matching (ticket: #13) + - Release 1.0.32 + 2012-12-20 Anton Adamansky. * Initial version of EJDB CLI console * All db methods are synchronous if no callback provided diff --git a/package.json b/package.json index 83db8f2..f5ceeb5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name" : "ejdb", - "version" : "1.0.31", + "version" : "1.0.32", "main" : "node/ejdb.js", "homepage" : "http://ejdb.org", "description" : "EJDB - Embedded JSON Database engine", diff --git a/tcejdb/configure b/tcejdb/configure index ff86ba1..7b5d600 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.0.29. +# Generated by GNU Autoconf 2.69 for tcejdb 1.0.32. # # # 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.0.29' -PACKAGE_STRING='tcejdb 1.0.29' +PACKAGE_VERSION='1.0.32' +PACKAGE_STRING='tcejdb 1.0.32' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1257,7 +1257,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.0.29 to adapt to many kinds of systems. +\`configure' configures tcejdb 1.0.32 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1318,7 +1318,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tcejdb 1.0.29:";; + short | recursive ) echo "Configuration of tcejdb 1.0.32:";; esac cat <<\_ACEOF @@ -1424,7 +1424,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tcejdb configure 1.0.29 +tcejdb configure 1.0.32 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1722,7 +1722,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.0.29, which was +It was created by tcejdb $as_me 1.0.32, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4870,7 +4870,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.0.29, which was +This file was extended by tcejdb $as_me 1.0.32, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4923,7 +4923,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.0.29 +tcejdb config.status 1.0.32 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 d60a33d..a6c32fb 100644 --- a/tcejdb/configure.ac +++ b/tcejdb/configure.ac @@ -11,7 +11,7 @@ test -n "$CPPFLAGS" && MYCPPFLAGS="$CPPFLAGS $MYCPPFLAGS" test -n "$LDFLAGS" && MYLDFLAGS="$LDFLAGS $MYLDFLAGS" # Package name -AC_INIT(tcejdb, 1.0.31) +AC_INIT(tcejdb, 1.0.32) # Package information MYLIBVER=9 diff --git a/tcejdb/ejdb.c b/tcejdb/ejdb.c index 6e7e395..46b942e 100644 --- a/tcejdb/ejdb.c +++ b/tcejdb/ejdb.c @@ -1281,16 +1281,16 @@ static bool _qrybsvalmatch(const EJQF *qf, bson_iterator *it, bool expandarrays) #undef _FETCHSTRFVAL } + static bool _qrybsrecurrmatch(const EJQF *qf, FFPCTX *ffpctx) { assert(qf && ffpctx && ffpctx->stopnestedarr); bson_type bt = bson_find_fieldpath_value3(ffpctx); if (bt == BSON_ARRAY && ffpctx->stopos < ffpctx->fplen) { - //we just stopped on some array in our fieldpath, so have to perform recusive iterations + //we just stepped in some array in middle our fieldpath, so have to perform recusive nexted iterations int pos1 = ffpctx->stopos; while (ffpctx->fpath[pos1] == '.' && pos1 < ffpctx->fplen) pos1++; ffpctx->fplen = ffpctx->fplen - pos1; ffpctx->fpath = ffpctx->fpath + pos1; - bool fpnumber = tcstrisintnum(ffpctx->fpath, ffpctx->fplen); //check the suffix is the number (array index) bson_iterator sit; bson_iterator_subiterator(ffpctx->input, &sit); while ((bt = bson_iterator_next(&sit)) != BSON_EOO) { @@ -1301,11 +1301,6 @@ static bool _qrybsrecurrmatch(const EJQF *qf, FFPCTX *ffpctx) { if (_qrybsrecurrmatch(qf, ffpctx)) { return true; } - } else if (fpnumber) { - const char *key = bson_iterator_key(&sit); - if (!strncmp(key, ffpctx->fpath, ffpctx->fplen)) { - return _qrybsvalmatch(qf, &sit, false); - } } } return false; diff --git a/tcejdb/testejdb/t2.c b/tcejdb/testejdb/t2.c index d5519b8..32e70b4 100644 --- a/tcejdb/testejdb/t2.c +++ b/tcejdb/testejdb/t2.c @@ -3474,7 +3474,11 @@ void testFindInComplexArray() { TCXSTR *log = tcxstrnew(); TCLIST *q1res = ejdbqryexecute(coll, q1, &count, 0, log); CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); - fprintf(stderr, "%s", TCXSTRPTR(log)); + //fprintf(stderr, "%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + for (int i = 0; i < TCLISTNUM(q1res); ++i) { + CU_ASSERT_FALSE(bson_compare_string("bar", TCLISTVALPTR(q1res, i), "complexarr.0.foo")); + } bson_destroy(&bsq1); tclistdel(q1res); @@ -3485,13 +3489,16 @@ void testFindInComplexArray() { bson_init_as_query(&bsq1); bson_append_string(&bsq1, "complexarr.1.foo", "bar1"); bson_finish(&bsq1); - q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); CU_ASSERT_PTR_NOT_NULL_FATAL(q1); log = tcxstrnew(); q1res = ejdbqryexecute(coll, q1, &count, 0, log); CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); - fprintf(stderr, "\n%s", TCXSTRPTR(log)); + //fprintf(stderr, "\n%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + for (int i = 0; i < TCLISTNUM(q1res); ++i) { + CU_ASSERT_FALSE(bson_compare_string("bar1", TCLISTVALPTR(q1res, i), "complexarr.1.foo")); + } bson_destroy(&bsq1); tclistdel(q1res); @@ -3502,14 +3509,16 @@ void testFindInComplexArray() { bson_init_as_query(&bsq1); bson_append_int(&bsq1, "complexarr.2", 333); bson_finish(&bsq1); - q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); CU_ASSERT_PTR_NOT_NULL_FATAL(q1); log = tcxstrnew(); q1res = ejdbqryexecute(coll, q1, &count, 0, log); CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); - fprintf(stderr, "\n%s", TCXSTRPTR(log)); - + //fprintf(stderr, "\n%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + for (int i = 0; i < TCLISTNUM(q1res); ++i) { + CU_ASSERT_FALSE(bson_compare_long(333, TCLISTVALPTR(q1res, i), "complexarr.2")); + } bson_destroy(&bsq1); tclistdel(q1res); tcxstrdel(log); @@ -3519,14 +3528,70 @@ void testFindInComplexArray() { bson_init_as_query(&bsq1); bson_append_int(&bsq1, "complexarr", 333); bson_finish(&bsq1); + q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + log = tcxstrnew(); + q1res = ejdbqryexecute(coll, q1, &count, 0, log); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); + //fprintf(stderr, "\n%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + for (int i = 0; i < TCLISTNUM(q1res); ++i) { + CU_ASSERT_FALSE(bson_compare_long(333, TCLISTVALPTR(q1res, i), "complexarr.2")); + } + bson_destroy(&bsq1); + tclistdel(q1res); + tcxstrdel(log); + ejdbquerydel(q1); + + + //$exists + bson_init_as_query(&bsq1); + bson_append_start_object(&bsq1, "complexarr.foo"); + bson_append_bool(&bsq1, "$exists", true); + bson_append_finish_object(&bsq1); + bson_finish(&bsq1); + q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + log = tcxstrnew(); + q1res = ejdbqryexecute(coll, q1, &count, 0, log); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); + CU_ASSERT_EQUAL(count, 1); + bson_destroy(&bsq1); + tclistdel(q1res); + tcxstrdel(log); + ejdbquerydel(q1); + + //$exists 2 + bson_init_as_query(&bsq1); + bson_append_start_object(&bsq1, "complexarr.1"); + bson_append_bool(&bsq1, "$exists", true); + bson_append_finish_object(&bsq1); + bson_finish(&bsq1); q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); CU_ASSERT_PTR_NOT_NULL_FATAL(q1); log = tcxstrnew(); q1res = ejdbqryexecute(coll, q1, &count, 0, log); CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); - fprintf(stderr, "\n%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + bson_destroy(&bsq1); + tclistdel(q1res); + tcxstrdel(log); + ejdbquerydel(q1); + + //$exists 3 + bson_init_as_query(&bsq1); + bson_append_start_object(&bsq1, "complexarr.4"); + bson_append_bool(&bsq1, "$exists", true); + bson_append_finish_object(&bsq1); + bson_finish(&bsq1); + q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + log = tcxstrnew(); + q1res = ejdbqryexecute(coll, q1, &count, 0, log); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1res); + CU_ASSERT_EQUAL(count, 0); bson_destroy(&bsq1); tclistdel(q1res); tcxstrdel(log); -- 2.7.4