MongoDB C++ Driver  legacy-1.1.2
bsonobjbuilder.h
1 /* bsonobjbuilder.h
2 
3  Classes in this file:
4  BSONObjBuilder
5  BSONArrayBuilder
6 */
7 
8 /* Copyright 2009 10gen Inc.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22 
23 #pragma once
24 
25 #include <boost/static_assert.hpp>
26 #include <map>
27 #include <cmath>
28 #include <limits>
29 
30 #include "mongo/base/data_cursor.h"
31 #include "mongo/base/parse_number.h"
32 #include "mongo/bson/bson_field.h"
33 #include "mongo/bson/bsonelement.h"
34 #include "mongo/bson/bsonmisc.h"
35 #include "mongo/bson/bsonobj.h"
36 #include "mongo/bson/timestamp.h"
37 #include "mongo/client/export_macros.h"
38 
39 namespace mongo {
40 
41 #if defined(_WIN32)
42 // warning: 'this' : used in base member initializer list
43 #pragma warning(disable : 4355)
44 #endif
45 
46 inline void checkFieldName(StringData fieldName) {
47  uassert(0, "field name cannot contain null bytes", fieldName.find('\0') == std::string::npos);
48 }
49 
53 class MONGO_CLIENT_API BSONObjBuilder : boost::noncopyable {
54 public:
56  BSONObjBuilder(int initsize = 512)
57  : _b(_buf),
58  _buf(sizeof(BSONObj::Holder) + initsize),
59  _offset(sizeof(BSONObj::Holder)),
60  _s(this),
61  _tracker(0),
62  _doneCalled(false) {
63  // Skip over space for a holder object at the beginning of the buffer, followed by
64  // space for the object length. The length is filled in by _done.
65  _b.skip(sizeof(BSONObj::Holder));
66  _b.skip(sizeof(int));
67 
68  // Reserve space for the EOO byte. This means _done() can't fail.
69  _b.reserveBytes(1);
70  }
71 
76  BSONObjBuilder(BufBuilder& baseBuilder)
77  : _b(baseBuilder),
78  _buf(0),
79  _offset(baseBuilder.len()),
80  _s(this),
81  _tracker(0),
82  _doneCalled(false) {
83  // Skip over space for the object length, which is filled in by _done. We don't need a
84  // holder since we are a sub-builder, and some parent builder has already made the
85  // reservation.
86  _b.skip(sizeof(int));
87 
88  // Reserve space for the EOO byte. This means _done() can't fail.
89  _b.reserveBytes(1);
90  }
91 
92  BSONObjBuilder(const BSONSizeTracker& tracker)
93  : _b(_buf),
94  _buf(sizeof(BSONObj::Holder) + tracker.getSize()),
95  _offset(sizeof(BSONObj::Holder)),
96  _s(this),
97  _tracker(const_cast<BSONSizeTracker*>(&tracker)),
98  _doneCalled(false) {
99  // See the comments in the first constructor for details.
100  _b.skip(sizeof(BSONObj::Holder));
101  _b.skip(sizeof(int));
102 
103  // Reserve space for the EOO byte. This means _done() can't fail.
104  _b.reserveBytes(1);
105  }
106 
107  ~BSONObjBuilder() {
108  // If 'done' has not already been called, and we have a reference to an owning
109  // BufBuilder but do not own it ourselves, then we must call _done to write in the
110  // length. Otherwise, we own this memory and its lifetime ends with us, therefore
111  // we can elide the write.
112  if (!_doneCalled && _b.buf() && _buf.getSize() == 0) {
113  _done();
114  }
115  }
116 
118  BSONObjBuilder& appendElements(BSONObj x);
119 
121  BSONObjBuilder& appendElementsUnique(BSONObj x);
122 
125  // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
126  verify(!e.eoo());
127  _b.appendBuf((void*)e.rawdata(), e.size());
128  return *this;
129  }
130 
132  BSONObjBuilder& appendAs(const BSONElement& e, const StringData& fieldName) {
133  // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
134  verify(!e.eoo());
135  _b.appendNum((char)e.type());
136  _b.appendStr(fieldName);
137  _b.appendBuf((void*)e.value(), e.valuesize());
138  return *this;
139  }
140 
142  BSONObjBuilder& append(const StringData& fieldName, BSONObj subObj) {
143  checkFieldName(fieldName);
144  _b.appendNum((char)Object);
145  _b.appendStr(fieldName);
146  _b.appendBuf((void*)subObj.objdata(), subObj.objsize());
147  return *this;
148  }
149 
151  BSONObjBuilder& appendObject(const StringData& fieldName, const char* objdata, int size = 0) {
152  checkFieldName(fieldName);
153  verify(objdata);
154  if (size == 0) {
155  size = ConstDataView(objdata).readLE<int>();
156  }
157 
158  verify(size > 4 && size < 100000000);
159 
160  _b.appendNum((char)Object);
161  _b.appendStr(fieldName);
162  _b.appendBuf((void*)objdata, size);
163  return *this;
164  }
165 
177  BufBuilder& subobjStart(const StringData& fieldName) {
178  checkFieldName(fieldName);
179  _b.appendNum((char)Object);
180  _b.appendStr(fieldName);
181  return _b;
182  }
183 
187  BSONObjBuilder& appendArray(const StringData& fieldName, const BSONObj& subObj) {
188  checkFieldName(fieldName);
189  _b.appendNum((char)Array);
190  _b.appendStr(fieldName);
191  _b.appendBuf((void*)subObj.objdata(), subObj.objsize());
192  return *this;
193  }
194  BSONObjBuilder& append(const StringData& fieldName, BSONArray arr) {
195  return appendArray(fieldName, arr);
196  }
197 
200  BufBuilder& subarrayStart(const StringData& fieldName) {
201  checkFieldName(fieldName);
202  _b.appendNum((char)Array);
203  _b.appendStr(fieldName);
204  return _b;
205  }
206 
208  BSONObjBuilder& appendBool(const StringData& fieldName, int val) {
209  checkFieldName(fieldName);
210  _b.appendNum((char)Bool);
211  _b.appendStr(fieldName);
212  _b.appendNum((char)(val ? 1 : 0));
213  return *this;
214  }
215 
217  BSONObjBuilder& append(const StringData& fieldName, bool val) {
218  checkFieldName(fieldName);
219  _b.appendNum((char)Bool);
220  _b.appendStr(fieldName);
221  _b.appendNum((char)(val ? 1 : 0));
222  return *this;
223  }
224 
226  BSONObjBuilder& append(const StringData& fieldName, int n) {
227  checkFieldName(fieldName);
228  _b.appendNum((char)NumberInt);
229  _b.appendStr(fieldName);
230  _b.appendNum(n);
231  return *this;
232  }
233 
235  BSONObjBuilder& append(const StringData& fieldName, unsigned n) {
236  return append(fieldName, (int)n);
237  }
238 
240  BSONObjBuilder& append(const StringData& fieldName, long long n) {
241  checkFieldName(fieldName);
242  _b.appendNum((char)NumberLong);
243  _b.appendStr(fieldName);
244  _b.appendNum(n);
245  return *this;
246  }
247 
249  BSONObjBuilder& appendIntOrLL(const StringData& fieldName, long long n) {
250  // extra () to avoid max macro on windows
251  static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
252  static const long long minInt = -maxInt;
253  if (minInt < n && n < maxInt) {
254  append(fieldName, static_cast<int>(n));
255  } else {
256  append(fieldName, n);
257  }
258  return *this;
259  }
260 
265  BSONObjBuilder& appendNumber(const StringData& fieldName, int n) {
266  return append(fieldName, n);
267  }
268 
269  BSONObjBuilder& appendNumber(const StringData& fieldName, double d) {
270  return append(fieldName, d);
271  }
272 
273  BSONObjBuilder& appendNumber(const StringData& fieldName, size_t n) {
274  static const size_t maxInt = (1 << 30);
275 
276  if (n < maxInt)
277  append(fieldName, static_cast<int>(n));
278  else
279  append(fieldName, static_cast<long long>(n));
280  return *this;
281  }
282 
283  BSONObjBuilder& appendNumber(const StringData& fieldName, long long llNumber) {
284  static const long long maxInt = (1LL << 30);
285  static const long long minInt = -maxInt;
286  static const long long maxDouble = (1LL << 40);
287  static const long long minDouble = -maxDouble;
288 
289  if (minInt < llNumber && llNumber < maxInt) {
290  append(fieldName, static_cast<int>(llNumber));
291  } else if (minDouble < llNumber && llNumber < maxDouble) {
292  append(fieldName, static_cast<double>(llNumber));
293  } else {
294  append(fieldName, llNumber);
295  }
296 
297  return *this;
298  }
299 
301  BSONObjBuilder& append(const StringData& fieldName, double n) {
302  checkFieldName(fieldName);
303  _b.appendNum((char)NumberDouble);
304  _b.appendStr(fieldName);
305  _b.appendNum(n);
306  return *this;
307  }
308 
312  bool appendAsNumber(const StringData& fieldName, const std::string& data);
313 
319  OID* oid = 0,
320  bool generateIfBlank = false) {
321  checkFieldName(fieldName);
322  _b.appendNum((char)jstOID);
323  _b.appendStr(fieldName);
324  if (oid)
325  _b.appendBuf(oid->view().view(), OID::kOIDSize);
326  else {
327  OID tmp;
328  if (generateIfBlank)
329  tmp.init();
330  else
331  tmp.clear();
332  _b.appendBuf(tmp.view().view(), OID::kOIDSize);
333  }
334  return *this;
335  }
336 
342  BSONObjBuilder& append(const StringData& fieldName, OID oid) {
343  checkFieldName(fieldName);
344  _b.appendNum((char)jstOID);
345  _b.appendStr(fieldName);
346  _b.appendBuf(oid.view().view(), OID::kOIDSize);
347  return *this;
348  }
349 
355  return append("_id", OID::gen());
356  }
357 
362  BSONObjBuilder& appendTimeT(const StringData& fieldName, time_t dt) {
363  checkFieldName(fieldName);
364  _b.appendNum((char)Date);
365  _b.appendStr(fieldName);
366  _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
367  return *this;
368  }
373  BSONObjBuilder& appendDate(const StringData& fieldName, Date_t dt);
374  BSONObjBuilder& append(const StringData& fieldName, Date_t dt) {
375  return appendDate(fieldName, dt);
376  }
377 
383  const StringData& regex,
384  const StringData& options = "") {
385  checkFieldName(fieldName);
386  uassert(0, "regex cannot contain null bytes", regex.find('\0') == std::string::npos);
387  _b.appendNum((char)RegEx);
388  _b.appendStr(fieldName);
389  _b.appendStr(regex);
390  _b.appendStr(options);
391  return *this;
392  }
393 
394  BSONObjBuilder& append(const StringData& fieldName, const BSONRegEx& regex) {
395  return appendRegex(fieldName, regex.pattern, regex.flags);
396  }
397 
398  BSONObjBuilder& appendCode(const StringData& fieldName, const StringData& code) {
399  checkFieldName(fieldName);
400  _b.appendNum((char)Code);
401  _b.appendStr(fieldName);
402  _b.appendNum((int)code.size() + 1);
403  _b.appendStr(code);
404  return *this;
405  }
406 
407  BSONObjBuilder& append(const StringData& fieldName, const BSONCode& code) {
408  return appendCode(fieldName, code.code);
409  }
410 
413  BSONObjBuilder& append(const StringData& fieldName, const char* str, int sz) {
414  checkFieldName(fieldName);
415  _b.appendNum((char)String);
416  _b.appendStr(fieldName);
417  _b.appendNum((int)sz);
418  _b.appendBuf(str, sz);
419  return *this;
420  }
422  BSONObjBuilder& append(const StringData& fieldName, const char* str) {
423  return append(fieldName, str, (int)strlen(str) + 1);
424  }
426  BSONObjBuilder& append(const StringData& fieldName, const std::string& str) {
427  return append(fieldName, str.c_str(), (int)str.size() + 1);
428  }
430  BSONObjBuilder& append(const StringData& fieldName, const StringData& str) {
431  checkFieldName(fieldName);
432  _b.appendNum((char)String);
433  _b.appendStr(fieldName);
434  _b.appendNum((int)str.size() + 1);
435  _b.appendStr(str, true);
436  return *this;
437  }
438 
439  BSONObjBuilder& appendSymbol(const StringData& fieldName, const StringData& symbol) {
440  checkFieldName(fieldName);
441  _b.appendNum((char)Symbol);
442  _b.appendStr(fieldName);
443  _b.appendNum((int)symbol.size() + 1);
444  _b.appendStr(symbol);
445  return *this;
446  }
447 
448  BSONObjBuilder& append(const StringData& fieldName, const BSONSymbol& symbol) {
449  return appendSymbol(fieldName, symbol.symbol);
450  }
451 
453  void appendNull() {
454  msgasserted(16234, "Invalid call to appendNull in BSONObj Builder.");
455  }
456 
458  BSONObjBuilder& appendNull(const StringData& fieldName) {
459  checkFieldName(fieldName);
460  _b.appendNum((char)jstNULL);
461  _b.appendStr(fieldName);
462  return *this;
463  }
464 
465  // Append an element that is less than all other keys.
466  BSONObjBuilder& appendMinKey(const StringData& fieldName) {
467  checkFieldName(fieldName);
468  _b.appendNum((char)MinKey);
469  _b.appendStr(fieldName);
470  return *this;
471  }
472  // Append an element that is greater than all other keys.
473  BSONObjBuilder& appendMaxKey(const StringData& fieldName) {
474  checkFieldName(fieldName);
475  _b.appendNum((char)MaxKey);
476  _b.appendStr(fieldName);
477  return *this;
478  }
479 
482  const Timestamp_t& ts = Timestamp_t()) {
483  checkFieldName(fieldName);
484  _b.appendNum((char)Timestamp);
485  _b.appendStr(fieldName);
486 
487  char buf[2 * sizeof(uint32_t)];
488  DataCursor cur(buf);
489  cur.writeLEAndAdvance<>(ts.increment());
490  cur.writeLEAndAdvance<>(ts.seconds());
491 
492  _b.appendBuf(buf, sizeof(buf));
493  return *this;
494  }
495 
496  BSONObjBuilder& append(const StringData& fieldName, const Timestamp_t& ts) {
497  return appendTimestamp(fieldName, ts);
498  }
499 
500  /*
501  Append an element of the deprecated DBRef type.
502  @deprecated
503  */
504  BSONObjBuilder& appendDBRef(const StringData& fieldName, const StringData& ns, const OID& oid) {
505  checkFieldName(fieldName);
506  _b.appendNum((char)DBRef);
507  _b.appendStr(fieldName);
508  _b.appendNum((int)ns.size() + 1);
509  _b.appendStr(ns);
510  _b.appendBuf(oid.view().view(), OID::kOIDSize);
511  return *this;
512  }
513 
514  BSONObjBuilder& append(const StringData& fieldName, const BSONDBRef& dbref) {
515  return appendDBRef(fieldName, dbref.ns, dbref.oid);
516  }
517 
526  int len,
527  BinDataType type,
528  const void* data) {
529  checkFieldName(fieldName);
530  _b.appendNum((char)BinData);
531  _b.appendStr(fieldName);
532  _b.appendNum(len);
533  _b.appendNum((char)type);
534  _b.appendBuf(data, len);
535  return *this;
536  }
537 
538  BSONObjBuilder& append(const StringData& fieldName, const BSONBinData& bd) {
539  return appendBinData(fieldName, bd.length, bd.type, bd.data);
540  }
541 
548  BSONObjBuilder& appendBinDataArrayDeprecated(const char* fieldName, const void* data, int len) {
549  checkFieldName(fieldName);
550  _b.appendNum((char)BinData);
551  _b.appendStr(fieldName);
552  _b.appendNum(len + 4);
553  _b.appendNum((char)0x2);
554  _b.appendNum(len);
555  _b.appendBuf(data, len);
556  return *this;
557  }
558 
563  const StringData& code,
564  const BSONObj& scope) {
565  checkFieldName(fieldName);
566  _b.appendNum((char)CodeWScope);
567  _b.appendStr(fieldName);
568  _b.appendNum((int)(4 + 4 + code.size() + 1 + scope.objsize()));
569  _b.appendNum((int)code.size() + 1);
570  _b.appendStr(code);
571  _b.appendBuf((void*)scope.objdata(), scope.objsize());
572  return *this;
573  }
574 
575  BSONObjBuilder& append(const StringData& fieldName, const BSONCodeWScope& cws) {
576  return appendCodeWScope(fieldName, cws.code, cws.scope);
577  }
578 
579  void appendUndefined(const StringData& fieldName) {
580  _b.appendNum((char)Undefined);
581  _b.appendStr(fieldName);
582  }
583 
584  /* helper function -- see Query::where() for primary way to do this. */
585  void appendWhere(const StringData& code, const BSONObj& scope) {
586  appendCodeWScope("$where", code, scope);
587  }
588 
592  void appendMinForType(const StringData& fieldName, int type);
593  void appendMaxForType(const StringData& fieldName, int type);
594 
596  template <class T>
597  BSONObjBuilder& append(const StringData& fieldName, const std::vector<T>& vals);
598 
599  template <class T>
600  BSONObjBuilder& append(const StringData& fieldName, const std::list<T>& vals);
601 
603  template <class T>
604  BSONObjBuilder& append(const StringData& fieldName, const std::set<T>& vals);
605 
610  template <class K, class T>
611  BSONObjBuilder& append(const StringData& fieldName, const std::map<K, T>& vals);
612 
619  massert(10335, "builder does not own memory", owned());
620  doneFast();
621  char* buf = _b.buf();
622  decouple();
623  return BSONObj::takeOwnership(buf);
624  }
625 
632  return BSONObj(_done());
633  }
634 
635  // Like 'done' above, but does not construct a BSONObj to return to the caller.
636  void doneFast() {
637  (void)_done();
638  }
639 
645  BSONObj temp(_done());
646  _b.setlen(_b.len() - 1); // next append should overwrite the EOO
647  _b.reserveBytes(1); // Rereserve room for the real EOO
648  _doneCalled = false;
649  return temp;
650  }
651 
659  void abandon() {
660  _doneCalled = true;
661  }
662 
663  void decouple() {
664  _b.decouple(); // post done() call version. be sure jsobj frees...
665  }
666 
667  void appendKeys(const BSONObj& keyPattern, const BSONObj& values);
668 
669  static std::string MONGO_CLIENT_FUNC numStr(int i) {
670  if (i >= 0 && i < 100 && numStrsReady)
671  return numStrs[i];
672  StringBuilder o;
673  o << i;
674  return o.str();
675  }
676 
679  _s.endField(name);
680  return _s;
681  }
682 
685  return genOID();
686  }
687 
688  Labeler operator<<(const Labeler::Label& l) {
689  massert(10336, "No subobject started", _s.subobjStarted());
690  return _s << l;
691  }
692 
693  template <typename T>
694  BSONObjBuilderValueStream& operator<<(const BSONField<T>& f) {
695  _s.endField(f.name());
696  return _s;
697  }
698 
699  template <typename T>
700  BSONObjBuilder& operator<<(const BSONFieldValue<T>& v) {
701  append(v.name(), v.value());
702  return *this;
703  }
704 
705  BSONObjBuilder& operator<<(const BSONElement& e) {
706  append(e);
707  return *this;
708  }
709 
710  bool isArray() const {
711  return false;
712  }
713 
716  bool owned() const {
717  return &_b == &_buf;
718  }
719 
720  BSONObjIterator iterator() const;
721 
722  bool hasField(const StringData& name) const;
723 
724  int len() const {
725  return _b.len();
726  }
727 
728  BufBuilder& bb() {
729  return _b;
730  }
731 
732 private:
733  char* _done() {
734  if (_doneCalled)
735  return _b.buf() + _offset;
736 
737  _doneCalled = true;
738 
739  // TODO remove this or find some way to prevent it from failing. Since this is intended
740  // for use with BSON() literal queries, it is less likely to result in oversized BSON.
741  _s.endField();
742 
743  _b.claimReservedBytes(1); // Prevents adding EOO from failing.
744  _b.appendNum((char)EOO);
745 
746  char* data = _b.buf() + _offset;
747  int size = _b.len() - _offset;
748  DataView(data).writeLE(size);
749  if (_tracker)
750  _tracker->got(size);
751  return data;
752  }
753 
754  BufBuilder& _b;
755  BufBuilder _buf;
756  int _offset;
757  BSONObjBuilderValueStream _s;
758  BSONSizeTracker* _tracker;
759  bool _doneCalled;
760 
761  static const std::string numStrs[100]; // cache of 0 to 99 inclusive
762  static bool numStrsReady; // for static init safety.
763 };
764 
765 class BSONArrayBuilder : boost::noncopyable {
766 public:
767  BSONArrayBuilder() : _i(0), _b() {}
768  BSONArrayBuilder(BufBuilder& _b) : _i(0), _b(_b) {}
769  BSONArrayBuilder(int initialSize) : _i(0), _b(initialSize) {}
770 
771  template <typename T>
772  BSONArrayBuilder& append(const T& x) {
773  _b.append(num(), x);
774  return *this;
775  }
776 
777  BSONArrayBuilder& append(const BSONElement& e) {
778  _b.appendAs(e, num());
779  return *this;
780  }
781 
782  BSONArrayBuilder& operator<<(const BSONElement& e) {
783  return append(e);
784  }
785 
786  template <typename T>
787  BSONArrayBuilder& operator<<(const T& x) {
788  _b << num().c_str() << x;
789  return *this;
790  }
791 
792  void appendNull() {
793  _b.appendNull(num());
794  }
795 
796  void appendUndefined() {
797  _b.appendUndefined(num());
798  }
799 
805  return BSONArray(_b.obj());
806  }
807  BSONObj obj() {
808  return _b.obj();
809  }
810 
811  BSONObj done() {
812  return _b.done();
813  }
814 
815  void doneFast() {
816  _b.doneFast();
817  }
818 
819  template <class T>
820  BSONArrayBuilder& append(const std::list<T>& vals);
821 
822  template <class T>
823  BSONArrayBuilder& append(const std::set<T>& vals);
824 
825  // These two just use next position
826  BufBuilder& subobjStart() {
827  return _b.subobjStart(num());
828  }
829  BufBuilder& subarrayStart() {
830  return _b.subarrayStart(num());
831  }
832 
833  BSONArrayBuilder& appendRegex(const StringData& regex, const StringData& options = "") {
834  uassert(0, "regex cannot contain null bytes", regex.find('\0') == std::string::npos);
835  _b.appendRegex(num(), regex, options);
836  return *this;
837  }
838 
839  BSONArrayBuilder& appendBinData(int len, BinDataType type, const void* data) {
840  _b.appendBinData(num(), len, type, data);
841  return *this;
842  }
843 
844  BSONArrayBuilder& appendCode(const StringData& code) {
845  _b.appendCode(num(), code);
846  return *this;
847  }
848 
849  BSONArrayBuilder& appendCodeWScope(const StringData& code, const BSONObj& scope) {
850  _b.appendCodeWScope(num(), code, scope);
851  return *this;
852  }
853 
854  BSONArrayBuilder& appendTimeT(time_t dt) {
855  _b.appendTimeT(num(), dt);
856  return *this;
857  }
858 
859  BSONArrayBuilder& appendDate(Date_t dt) {
860  _b.appendDate(num(), dt);
861  return *this;
862  }
863 
864  BSONArrayBuilder& appendBool(bool val) {
865  _b.appendBool(num(), val);
866  return *this;
867  }
868 
869  bool isArray() const {
870  return true;
871  }
872 
873  int len() const {
874  return _b.len();
875  }
876  int arrSize() const {
877  return _i;
878  }
879 
880  BufBuilder& bb() {
881  return _b.bb();
882  }
883 
884 private:
885  std::string num() {
886  return _b.numStr(_i++);
887  }
888  int _i;
889  BSONObjBuilder _b;
890 };
891 
892 template <class T>
894  const std::vector<T>& vals) {
895  BSONObjBuilder arrBuilder;
896  for (unsigned int i = 0; i < vals.size(); ++i)
897  arrBuilder.append(numStr(i), vals[i]);
898  appendArray(fieldName, arrBuilder.done());
899  return *this;
900 }
901 
902 template <class L>
903 inline BSONObjBuilder& _appendIt(BSONObjBuilder& _this,
904  const StringData& fieldName,
905  const L& vals) {
906  BSONObjBuilder arrBuilder;
907  int n = 0;
908  for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
909  arrBuilder.append(BSONObjBuilder::numStr(n++), *i);
910  _this.appendArray(fieldName, arrBuilder.done());
911  return _this;
912 }
913 
914 template <class T>
915 inline BSONObjBuilder& BSONObjBuilder::append(const StringData& fieldName,
916  const std::list<T>& vals) {
917  return _appendIt<std::list<T> >(*this, fieldName, vals);
918 }
919 
920 template <class T>
922  const std::set<T>& vals) {
923  return _appendIt<std::set<T> >(*this, fieldName, vals);
924 }
925 
926 template <class K, class T>
928  const std::map<K, T>& vals) {
929  BSONObjBuilder bob;
930  for (typename std::map<K, T>::const_iterator i = vals.begin(); i != vals.end(); ++i) {
931  bob.append(i->first, i->second);
932  }
933  append(fieldName, bob.obj());
934  return *this;
935 }
936 
937 
938 template <class L>
939 inline BSONArrayBuilder& _appendArrayIt(BSONArrayBuilder& _this, const L& vals) {
940  for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
941  _this.append(*i);
942  return _this;
943 }
944 
945 template <class T>
946 inline BSONArrayBuilder& BSONArrayBuilder::append(const std::list<T>& vals) {
947  return _appendArrayIt<std::list<T> >(*this, vals);
948 }
949 
950 template <class T>
951 inline BSONArrayBuilder& BSONArrayBuilder::append(const std::set<T>& vals) {
952  return _appendArrayIt<std::set<T> >(*this, vals);
953 }
954 
955 template <typename T>
956 inline BSONFieldValue<BSONObj> BSONField<T>::query(const char* q, const T& t) const {
957  BSONObjBuilder b;
958  b.append(q, t);
959  return BSONFieldValue<BSONObj>(_name, b.obj());
960 }
961 
962 // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
963 inline BSONObj OR(const BSONObj& a, const BSONObj& b) {
964  return BSON("$or" << BSON_ARRAY(a << b));
965 }
966 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c) {
967  return BSON("$or" << BSON_ARRAY(a << b << c));
968 }
969 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d) {
970  return BSON("$or" << BSON_ARRAY(a << b << c << d));
971 }
972 inline BSONObj OR(
973  const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e) {
974  return BSON("$or" << BSON_ARRAY(a << b << c << d << e));
975 }
976 inline BSONObj OR(const BSONObj& a,
977  const BSONObj& b,
978  const BSONObj& c,
979  const BSONObj& d,
980  const BSONObj& e,
981  const BSONObj& f) {
982  return BSON("$or" << BSON_ARRAY(a << b << c << d << e << f));
983 }
984 }
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition: bsonobjbuilder.h:659
BufBuilder & subobjStart(const StringData &fieldName)
add header for a new subobject and return bufbuilder for writing to the subobject's body ...
Definition: bsonobjbuilder.h:177
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition: bsonobjbuilder.h:240
Definition: timestamp.h:23
end of object
Definition: bsontypes.h:42
Definition: bsonmisc.h:155
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition: bsonobjbuilder.h:804
int objsize() const
Definition: bsonobj.h:308
larger than all other types
Definition: bsontypes.h:82
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition: bsonobjbuilder.h:318
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents...
Definition: string_data.h:43
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
int size(int maxLen) const
Size of the element.
Definition: bsonmisc.h:122
static BSONObj takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned memory containing BSON data, prefixed by sufficient space for...
Definition: bsonobj.h:545
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition: bsonobjbuilder.h:618
Object ID type.
Definition: oid.h:60
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition: bsonobjbuilder.h:481
const char * objdata() const
Definition: bsonobj.h:303
Definition: data_view.h:30
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:124
Definition: bsonmisc.h:86
Updated to a Date with value next OpTime on insert.
Definition: bsontypes.h:76
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition: bsonobjbuilder.h:208
BufBuilder & subarrayStart(const StringData &fieldName)
add header for a new subarray and return bufbuilder for writing to the subarray's body ...
Definition: bsonobjbuilder.h:200
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition: bsonobjbuilder.h:422
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition: bsonobjbuilder.h:548
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:259
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition: bsonobjbuilder.h:458
date type
Definition: bsontypes.h:60
boolean type
Definition: bsontypes.h:58
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition: bsonobjbuilder.h:301
smaller than all other types
Definition: bsontypes.h:40
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:631
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition: bsonobjbuilder.h:644
const char * value() const
raw data of the element's value (so be careful).
Definition: bsonelement.h:212
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:154
Definition: time_support.h:39
ObjectId.
Definition: bsontypes.h:56
an embedded object
Definition: bsontypes.h:48
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition: bsonobjbuilder.h:413
32 bit signed integer
Definition: bsontypes.h:74
double precision floating point value
Definition: bsontypes.h:44
null type
Definition: bsontypes.h:62
a programming language (e.g., Python) symbol
Definition: bsontypes.h:70
Definition: data_cursor.h:101
javascript code that can execute on the database server, with SavedContext
Definition: bsontypes.h:72
iterator for a BSONObj
Definition: bsonobjiterator.h:37
void init()
sets the contents to a new oid / randomized value
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
Definition: shared_buffer.h:67
BSONObjBuilder & appendNumber(const StringData &fieldName, int n)
appendNumber is a series of method for appending the smallest sensible type mostly for JS ...
Definition: bsonobjbuilder.h:265
Definition: bsonmisc.h:169
Definition: builder.h:98
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:216
Undefined type.
Definition: bsontypes.h:54
BSONObjBuilder & append(const StringData &fieldName, OID oid)
Append a BSON Object ID.
Definition: bsonobjbuilder.h:342
BSONObjBuilder & genOID()
Generate and assign an object id for the _id field.
Definition: bsonobjbuilder.h:354
Definition: bsonmisc.h:162
bool eoo() const
Indicates if it is the end-of-object element, which is present at the end of every BSON object...
Definition: bsonelement.h:172
BSONObjBuilder & appendRegex(const StringData &fieldName, const StringData &regex, const StringData &options="")
Append a regular expression value.
Definition: bsonobjbuilder.h:382
BSONObjBuilder & appendTimeT(const StringData &fieldName, time_t dt)
Append a time_t date.
Definition: bsonobjbuilder.h:362
BSONObjBuilder & appendCodeWScope(const StringData &fieldName, const StringData &code, const BSONObj &scope)
Append to the BSON object a field of type CodeWScope.
Definition: bsonobjbuilder.h:562
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition: bsonobjbuilder.h:453
regular expression, a pattern with options
Definition: bsontypes.h:64
64 bit integer
Definition: bsontypes.h:78
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition: bsonobjbuilder.h:187
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:132
an embedded array
Definition: bsontypes.h:50
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition: bsonobjbuilder.h:235
deprecated / use CodeWScope
Definition: bsontypes.h:68
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition: bsonobjbuilder.h:151
BSONObjBuilder(int initsize=512)
Definition: bsonobjbuilder.h:56
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
deprecated / will be redesigned
Definition: bsontypes.h:66
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:678
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition: bsonobjbuilder.h:226
Definition: bsonobj.h:581
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition: bsonobjbuilder.h:525
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition: bsonobjbuilder.h:249
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition: bsonobjbuilder.h:430
int len() const
Definition: builder.h:222
Definition: bsonmisc.h:120
Definition: bsonobjbuilder.h:765
bool owned() const
Definition: bsonobjbuilder.h:716
BSONObjBuilder & append(const StringData &fieldName, BSONObj subObj)
add a subobject as a member
Definition: bsonobjbuilder.h:142
BSONObjBuilder & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:684
binary data
Definition: bsontypes.h:52
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition: bsonobjbuilder.h:217
void clear()
initialize to 'null'
Definition: oid.h:86
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition: bsonobjbuilder.h:426
Definition: bsonmisc.h:208
BSONObjBuilder(BufBuilder &baseBuilder)
Definition: bsonobjbuilder.h:76
character string, stored in utf8
Definition: bsontypes.h:46