case JBEINVALIDBSONPK: return "invalid bson _id field";
case JBEQONEEMATCH: return "only one $elemMatch allowed in the fieldpath"; //todo remove
case JBEQINCEXCL: return "$fields hint cannot mix include and exclude fields";
+ case JBEQACTKEY: return "action key in $do block can only be one of: $join";
default: return tcerrmsg(ecode);
}
if (pqf) {
qf.elmatchgrp = pqf->elmatchgrp;
qf.elmatchpos = pqf->elmatchpos;
+ qf.flags = pqf->flags;
}
if (!isckey) {
break;
}
- if (qf.flags & EJCONDOIT) { //$do
- assert(qf.updateobj == NULL);
+ if (!strcmp("$elemMatch", fkey)) {
+ if (qf.elmatchgrp) { //only one $elemMatch allowed in query field
+ ret = JBEQERROR;
+ _ejdbsetecode(jb, ret, __FILE__, __LINE__, __func__);
+ break;
+ }
+ qf.elmatchgrp = ++elmatchgrp;
+ char *fpath = tcstrjoin(pathStack, '.');
+ qf.elmatchpos = strlen(fpath) + 1; //+ 1 to skip next dot '.'
+ free(fpath);
+ }
+ } else {
+ if (qf.flags & EJCONDOIT) {
qf.updateobj = bson_create();
bson_init_as_query(qf.updateobj);
bson_type sbt;
bson_iterator sit;
bson_iterator_subiterator(it, &sit);
+ int ac = 0;
while ((sbt = bson_iterator_next(&sit)) != BSON_EOO) {
- bson_append_field_from_iterator(&sit, qf.updateobj);
+ const char *akey = bson_iterator_key(&sit);
+ if (!strcmp("$join", akey)) {
+ bson_append_field_from_iterator(&sit, qf.updateobj);
+ ++ac;
+ }
}
bson_finish(qf.updateobj);
if (qf.updateobj->err) {
_ejdbsetecode(jb, ret, __FILE__, __LINE__, __func__);
break;
}
+ if (ac == 0) {
+ ret = JBEQACTKEY;
+ _ejdbsetecode(jb, ret, __FILE__, __LINE__, __func__);
+ break;
+ }
qf.fpath = strdup(fkey);
qf.fpathsz = strlen(qf.fpath);
qf.tcop = TDBQTRUE;
TCLISTPUSH(qlist, &qf, sizeof (qf));
break;
}
-
- if (!strcmp("$elemMatch", fkey)) {
- if (qf.elmatchgrp) { //only one $elemMatch allowed in query field
- ret = JBEQERROR;
- _ejdbsetecode(jb, ret, __FILE__, __LINE__, __func__);
- break;
- }
- qf.elmatchgrp = ++elmatchgrp;
- char *fpath = tcstrjoin(pathStack, '.');
- qf.elmatchpos = strlen(fpath) + 1; //+ 1 to skip next dot '.'
- free(fpath);
- }
}
bson_iterator sit;
bson_iterator_subiterator(it, &sit);
JBEQERROR = 9009, /**< Query generic error. */
JBEQUPDFAILED = 9010, /**< Updating failed. */
JBEQONEEMATCH = 9011, /**< Only one $elemMatch allowed in the fieldpath. */
- JBEQINCEXCL = 9012 /**< $fields hint cannot mix include and exclude fields */
+ JBEQINCEXCL = 9012, /**< $fields hint cannot mix include and exclude fields */
+ JBEQACTKEY = 9013 /**< action key in $do block can only be one of: $join */
};
enum { /** Database open modes */
objects with matching oids from collectionname
{..., $do : {fpath : {$join : 'collectionname'}} }
-
+ Second form:
+ {..., $do : {fpath : {$join : {$ref : 'collectionname', $fields : {foo:1}} }} }
*/
+
+ bson bsq1;
+ bson_init_as_query(&bsq1);
+ bson_append_start_object(&bsq1, "$do");
+ bson_append_start_object(&bsq1, "homeref");
+ bson_append_start_object(&bsq1, "$join");
+ bson_append_string(&bsq1, "$join", "home");
+ bson_append_finish_object(&bsq1);
+ bson_append_finish_object(&bsq1);
+ bson_append_finish_object(&bsq1);
+ bson_finish(&bsq1);
+ CU_ASSERT_FALSE_FATAL(bsq1.err);
+
+
+ EJQ *q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(q1);
+ ejdbquerydel(q1);
+
+ bson_destroy(&bsq1);
}
int main() {