/* bson.c */
/* Copyright 2009, 2010 10gen Inc.
+ * Copyright (C) 2012-2013 Softmotions Ltd <info@softmotions.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
/* Copyright 2009-2012 10gen Inc.
+ * Copyright (C) 2012-2013 Softmotions Ltd <info@softmotions.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
bson_del(q->hints);
q->hints = NULL;
}
+ if (q->$ifields) {
+ tcmapdel(q->$ifields);
+ q->$ifields = NULL;
+ }
q->hints = bs;
return q;
}
bson_del(q->hints);
q->hints = NULL;
}
+ if (q->$ifields) {
+ tcmapdel(q->$ifields);
+ q->$ifields = NULL;
+ }
if (q->colbuf) {
tcxstrdel(q->colbuf);
q->colbuf = NULL;
if (src->hints) {
target->hints = bson_dup(src->hints);
}
+ if (src->$ifields) {
+ target->$ifields = tcmapdup(src->$ifields);
+ }
if (src->orqlist) {
target->orqlist = tclistnew2(TCLISTNUM(src->orqlist));
for (int i = 0; i < TCLISTNUM(src->orqlist); ++i) {
_ejdbsetecode(jcoll->jb, JBEQINCEXCL, __FILE__, __LINE__, __func__);
return false;
}
+
*imode = inc;
const char *key = bson_iterator_key(&sit);
+
+ char *pptr;
+ //Checking the $(projection) operator.
+ if (inc && (pptr = strstr(key, ".$")) && (*(pptr + 2) == '\0' || *(pptr + 2) == '.')) {// '.$' || '.$.'
+ int dc = 0;
+ for (int i = 0; *(key + i) != '\0'; ++i) {
+ if (*(key + i) == '$' && (dc++ > 0)) break;
+ }
+ if (dc != 1) { //More than one '$' chars in projection it is invalid
+ continue;
+ }
+ for (int i = 0; i < TCLISTNUM(qlist); ++i) {
+ EJQF *qf = TCLISTVALPTR(qlist, i);
+ int j;
+ for (j = 0; *(key + j) != '\0' && *(key + j) == *(qf->fpath + j); ++j);
+ if (key + j == pptr || key + j == pptr + 1) { //existing QF matched $(projection) prefix
+ if (!ejq->$ifields) {
+ ejq->$ifields = tcmapnew2(TCMAPTINYBNUM);
+ }
+ tcmapput(ejq->$ifields, qf->fpath, qf->fpathsz, key, strlen(key));
+ break;
+ }
+ }
+ continue; //skip registering this fields in the fmap
+ }
tcmapputkeep(fmap, key, strlen(key), &yes, sizeof (yes));
}
if (TCMAPRNUM(fmap) == 0) { //if {$fields : {}} we will force {$fields : {_id:1}}
TCLIST *orqlist; /**> List of $or joined query objects *EJQ */
TCLIST *andqlist; /**> List of $and joined query objects *EJQ */
bson *hints; /**> Hints bson object */
+ /**> Include $(projection) fields char* names.
+ * Mapping EJQF fpath => $(projection) field name
+ * http://docs.mongodb.org/manual/reference/projection/positional/#proj._S_
+ */
+ TCMAP *$ifields;
uint32_t skip; /**> Number of records to skip. */
uint32_t max; /**> Max number of results */
uint32_t flags; /**> Control flags */