MongoDB C++ Driver legacy-1.1.1
Loading...
Searching...
No Matches
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
39namespace mongo {
40
41#if defined(_WIN32)
42// warning: 'this' : used in base member initializer list
43#pragma warning(disable : 4355)
44#endif
45
46inline void checkFieldName(StringData fieldName) {
47 uassert(0, "field name cannot contain null bytes", fieldName.find('\0') == std::string::npos);
48}
49
53class MONGO_CLIENT_API BSONObjBuilder : boost::noncopyable {
54public:
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
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
119
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
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 }
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
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
732private:
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
765class BSONArrayBuilder : boost::noncopyable {
766public:
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
884private:
885 std::string num() {
886 return _b.numStr(_i++);
887 }
888 int _i;
889 BSONObjBuilder _b;
890};
891
892template <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
902template <class L>
903inline 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
914template <class T>
915inline BSONObjBuilder& BSONObjBuilder::append(const StringData& fieldName,
916 const std::list<T>& vals) {
917 return _appendIt<std::list<T> >(*this, fieldName, vals);
918}
919
920template <class T>
922 const std::set<T>& vals) {
923 return _appendIt<std::set<T> >(*this, fieldName, vals);
924}
925
926template <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
938template <class L>
939inline 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
945template <class T>
946inline BSONArrayBuilder& BSONArrayBuilder::append(const std::list<T>& vals) {
947 return _appendArrayIt<std::list<T> >(*this, vals);
948}
949
950template <class T>
951inline BSONArrayBuilder& BSONArrayBuilder::append(const std::set<T>& vals) {
952 return _appendArrayIt<std::set<T> >(*this, vals);
953}
954
955template <typename T>
956inline 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));
963inline BSONObj OR(const BSONObj& a, const BSONObj& b) {
964 return BSON("$or" << BSON_ARRAY(a << b));
965}
966inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c) {
967 return BSON("$or" << BSON_ARRAY(a << b << c));
968}
969inline 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}
972inline 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}
976inline 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}
Definition bsonobjbuilder.h:765
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition bsonobjbuilder.h:804
BSONElement represents an "element" in a BSONObj.
Definition bsonelement.h:55
int valuesize() const
size in bytes of the element's value (when applicable).
Definition bsonelement.h:216
const char * value() const
raw data of the element's value (so be careful).
Definition bsonelement.h:212
int size(int maxLen) const
Size of the element.
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
BSONType type() const
Returns the type of the element.
Definition bsonelement.h:154
Definition bsonmisc.h:208
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
BSONObjBuilder(BufBuilder &baseBuilder)
Definition bsonobjbuilder.h:76
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition bsonobjbuilder.h:659
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition bsonobjbuilder.h:426
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 & append(const BSONElement &e)
append element to the object we are building
Definition bsonobjbuilder.h:124
BSONObjBuilder & appendElements(BSONObj x)
add all the fields from the object specified to this object
BSONObjBuilder & append(const StringData &fieldName, OID oid)
Append a BSON Object ID.
Definition bsonobjbuilder.h:342
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition bsonobjbuilder.h:226
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition bsonobjbuilder.h:301
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition bsonobjbuilder.h:240
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition bsonobjbuilder.h:644
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition bsonobjbuilder.h:318
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition bsonobjbuilder.h:453
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition bsonobjbuilder.h:235
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition bsonobjbuilder.h:151
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
BSONObjBuilder & appendDate(const StringData &fieldName, Date_t dt)
Append a date.
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition bsonobjbuilder.h:217
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
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition bsonobjbuilder.h:413
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition bsonobjbuilder.h:422
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition bsonobjbuilder.h:458
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition bsonobjbuilder.h:481
BSONObjBuilder & appendElementsUnique(BSONObj x)
add all the fields from the object specified to this object if they don't exist already
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 StringData &str)
Append a string element.
Definition bsonobjbuilder.h:430
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:678
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition bsonobjbuilder.h:132
bool appendAsNumber(const StringData &fieldName, const std::string &data)
tries to append the data as a number
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition bsonobjbuilder.h:548
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition bsonobjbuilder.h:525
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition bsonobjbuilder.h:208
BSONObjBuilder & appendRegex(const StringData &fieldName, const StringData &regex, const StringData &options="")
Append a regular expression value.
Definition bsonobjbuilder.h:382
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition bsonobjbuilder.h:618
BSONObj done()
Fetch the object we have built.
Definition bsonobjbuilder.h:631
BSONObjBuilder & appendTimeT(const StringData &fieldName, time_t dt)
Append a time_t date.
Definition bsonobjbuilder.h:362
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 & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition bsonobjbuilder.h:187
BSONObjBuilder & genOID()
Generate and assign an object id for the _id field.
Definition bsonobjbuilder.h:354
void appendMinForType(const StringData &fieldName, int type)
these are the min/max when comparing, not strict min/max elements for a given type
BSONObjBuilder & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:684
BSONObjBuilder(int initsize=512)
Definition bsonobjbuilder.h:56
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition bsonobjbuilder.h:249
iterator for a BSONObj
Definition bsonobjiterator.h:37
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition bsonobj.h:78
int objsize() const
Definition bsonobj.h:308
const char * objdata() const
Definition bsonobj.h:303
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage
Definition bsonmisc.h:259
Definition data_view.h:30
Definition data_cursor.h:101
Definition bsonmisc.h:120
Object ID type.
Definition oid.h:60
void clear()
initialize to 'null'
Definition oid.h:86
void init()
sets the contents to a new oid / randomized value
Definition shared_buffer.h:67
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents.
Definition string_data.h:43
Definition timestamp.h:23
int len() const
Definition builder.h:222
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:32
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
@ CodeWScope
javascript code that can execute on the database server, with SavedContext
Definition bsontypes.h:72
@ String
character string, stored in utf8
Definition bsontypes.h:46
@ BinData
binary data
Definition bsontypes.h:52
@ Array
an embedded array
Definition bsontypes.h:50
@ Bool
boolean type
Definition bsontypes.h:58
@ Timestamp
Updated to a Date with value next OpTime on insert.
Definition bsontypes.h:76
@ RegEx
regular expression, a pattern with options
Definition bsontypes.h:64
@ jstOID
ObjectId.
Definition bsontypes.h:56
@ Object
an embedded object
Definition bsontypes.h:48
@ NumberLong
64 bit integer
Definition bsontypes.h:78
@ jstNULL
null type
Definition bsontypes.h:62
@ NumberInt
32 bit signed integer
Definition bsontypes.h:74
@ NumberDouble
double precision floating point value
Definition bsontypes.h:44
@ Date
date type
Definition bsontypes.h:60
Definition bsonobj.h:581
Definition bsonmisc.h:169
Definition bsonmisc.h:155
Definition bsonmisc.h:162
Definition time_support.h:39
Definition bsonmisc.h:86
Definition bsonmisc.h:122