MongoDB C++ Driver legacy-1.0.5
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
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 : _b(baseBuilder)
77 , _buf(0)
78 , _offset(baseBuilder.len())
79 , _s(this)
80 , _tracker(0)
81 , _doneCalled(false) {
82 // Skip over space for the object length, which is filled in by _done. We don't need a
83 // holder since we are a sub-builder, and some parent builder has already made the
84 // reservation.
85 _b.skip(sizeof(int));
86
87 // Reserve space for the EOO byte. This means _done() can't fail.
88 _b.reserveBytes(1);
89 }
90
91 BSONObjBuilder( const BSONSizeTracker & tracker )
92 : _b(_buf)
93 , _buf(sizeof(BSONObj::Holder) + tracker.getSize())
94 , _offset(sizeof(BSONObj::Holder))
95 , _s(this)
96 , _tracker(const_cast<BSONSizeTracker*>(&tracker))
97 , _doneCalled(false) {
98 // See the comments in the first constructor for details.
99 _b.skip(sizeof(BSONObj::Holder));
100 _b.skip(sizeof(int));
101
102 // Reserve space for the EOO byte. This means _done() can't fail.
103 _b.reserveBytes(1);
104 }
105
106 ~BSONObjBuilder() {
107 // If 'done' has not already been called, and we have a reference to an owning
108 // BufBuilder but do not own it ourselves, then we must call _done to write in the
109 // length. Otherwise, we own this memory and its lifetime ends with us, therefore
110 // we can elide the write.
111 if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
112 _done();
113 }
114 }
115
118
121
124 checkFieldName(e.fieldNameStringData());
125 verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
126 _b.appendBuf((void*) e.rawdata(), e.size());
127 return *this;
128 }
129
131 BSONObjBuilder& appendAs(const BSONElement& e, const StringData& fieldName) {
132 checkFieldName(fieldName);
133 verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
134 _b.appendNum((char) e.type());
135 _b.appendStr(fieldName);
136 _b.appendBuf((void *) e.value(), e.valuesize());
137 return *this;
138 }
139
141 BSONObjBuilder& append(const StringData& fieldName, BSONObj subObj) {
142 checkFieldName(fieldName);
143 _b.appendNum((char) Object);
144 _b.appendStr(fieldName);
145 _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
146 return *this;
147 }
148
150 BSONObjBuilder& appendObject(const StringData& fieldName, const char * objdata , int size = 0 ) {
151 checkFieldName(fieldName);
152 verify( objdata );
153 if ( size == 0 ) {
154 size = ConstDataView(objdata).readLE<int>();
155 }
156
157 verify( size > 4 && size < 100000000 );
158
159 _b.appendNum((char) Object);
160 _b.appendStr(fieldName);
161 _b.appendBuf((void*)objdata, size );
162 return *this;
163 }
164
176 BufBuilder &subobjStart(const StringData& fieldName) {
177 checkFieldName(fieldName);
178 _b.appendNum((char) Object);
179 _b.appendStr(fieldName);
180 return _b;
181 }
182
186 BSONObjBuilder& appendArray(const StringData& fieldName, const BSONObj &subObj) {
187 checkFieldName(fieldName);
188 _b.appendNum((char) Array);
189 _b.appendStr(fieldName);
190 _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
191 return *this;
192 }
193 BSONObjBuilder& append(const StringData& fieldName, BSONArray arr) {
194 return appendArray(fieldName, arr);
195 }
196
199 BufBuilder &subarrayStart(const StringData& fieldName) {
200 checkFieldName(fieldName);
201 _b.appendNum((char) Array);
202 _b.appendStr(fieldName);
203 return _b;
204 }
205
207 BSONObjBuilder& appendBool(const StringData& fieldName, int val) {
208 checkFieldName(fieldName);
209 _b.appendNum((char) Bool);
210 _b.appendStr(fieldName);
211 _b.appendNum((char) (val?1:0));
212 return *this;
213 }
214
216 BSONObjBuilder& append(const StringData& fieldName, bool val) {
217 checkFieldName(fieldName);
218 _b.appendNum((char) Bool);
219 _b.appendStr(fieldName);
220 _b.appendNum((char) (val?1:0));
221 return *this;
222 }
223
225 BSONObjBuilder& append(const StringData& fieldName, int n) {
226 checkFieldName(fieldName);
227 _b.appendNum((char) NumberInt);
228 _b.appendStr(fieldName);
229 _b.appendNum(n);
230 return *this;
231 }
232
234 BSONObjBuilder& append(const StringData& fieldName, unsigned n) {
235 return append(fieldName, (int) n);
236 }
237
239 BSONObjBuilder& append(const StringData& fieldName, long long n) {
240 checkFieldName(fieldName);
241 _b.appendNum((char) NumberLong);
242 _b.appendStr(fieldName);
243 _b.appendNum(n);
244 return *this;
245 }
246
248 BSONObjBuilder& appendIntOrLL( const StringData& fieldName , long long n ) {
249 // extra () to avoid max macro on windows
250 static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
251 static const long long minInt = -maxInt;
252 if ( minInt < n && n < maxInt ) {
253 append( fieldName , static_cast<int>( n ) );
254 }
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 }
292 else if ( minDouble < llNumber && llNumber < maxDouble ) {
293 append( fieldName, static_cast<double>( llNumber ) );
294 }
295 else {
296 append( fieldName, llNumber );
297 }
298
299 return *this;
300 }
301
303 BSONObjBuilder& append(const StringData& fieldName, double n) {
304 checkFieldName(fieldName);
305 _b.appendNum((char) NumberDouble);
306 _b.appendStr(fieldName);
307 _b.appendNum(n);
308 return *this;
309 }
310
314 bool appendAsNumber( const StringData& fieldName , const std::string& data );
315
320 BSONObjBuilder& appendOID(const StringData& fieldName, OID *oid = 0 , 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
382 BSONObjBuilder& appendRegex(const StringData& fieldName, const StringData& regex, const StringData& options = "") {
383 checkFieldName(fieldName);
384 uassert(0, "regex cannot contain null bytes", regex.find('\0') == std::string::npos);
385 _b.appendNum((char) RegEx);
386 _b.appendStr(fieldName);
387 _b.appendStr(regex);
388 _b.appendStr(options);
389 return *this;
390 }
391
392 BSONObjBuilder& append(const StringData& fieldName, const BSONRegEx& regex) {
393 return appendRegex(fieldName, regex.pattern, regex.flags);
394 }
395
396 BSONObjBuilder& appendCode(const StringData& fieldName, const StringData& code) {
397 checkFieldName(fieldName);
398 _b.appendNum((char) Code);
399 _b.appendStr(fieldName);
400 _b.appendNum((int) code.size()+1);
401 _b.appendStr(code);
402 return *this;
403 }
404
405 BSONObjBuilder& append(const StringData& fieldName, const BSONCode& code) {
406 return appendCode(fieldName, code.code);
407 }
408
411 BSONObjBuilder& append(const StringData& fieldName, const char *str, int sz) {
412 checkFieldName(fieldName);
413 _b.appendNum((char) String);
414 _b.appendStr(fieldName);
415 _b.appendNum((int)sz);
416 _b.appendBuf(str, sz);
417 return *this;
418 }
420 BSONObjBuilder& append(const StringData& fieldName, const char *str) {
421 return append(fieldName, str, (int) strlen(str)+1);
422 }
424 BSONObjBuilder& append(const StringData& fieldName, const std::string& str) {
425 return append(fieldName, str.c_str(), (int) str.size()+1);
426 }
428 BSONObjBuilder& append(const StringData& fieldName, const StringData& str) {
429 checkFieldName(fieldName);
430 _b.appendNum((char) String);
431 _b.appendStr(fieldName);
432 _b.appendNum((int)str.size()+1);
433 _b.appendStr(str, true);
434 return *this;
435 }
436
437 BSONObjBuilder& appendSymbol(const StringData& fieldName, const StringData& symbol) {
438 checkFieldName(fieldName);
439 _b.appendNum((char) Symbol);
440 _b.appendStr(fieldName);
441 _b.appendNum((int) symbol.size()+1);
442 _b.appendStr(symbol);
443 return *this;
444 }
445
446 BSONObjBuilder& append(const StringData& fieldName, const BSONSymbol& symbol) {
447 return appendSymbol(fieldName, symbol.symbol);
448 }
449
451 void appendNull() {
452 msgasserted(16234, "Invalid call to appendNull in BSONObj Builder.");
453 }
454
456 BSONObjBuilder& appendNull( const StringData& fieldName ) {
457 checkFieldName(fieldName);
458 _b.appendNum( (char) jstNULL );
459 _b.appendStr( fieldName );
460 return *this;
461 }
462
463 // Append an element that is less than all other keys.
464 BSONObjBuilder& appendMinKey( const StringData& fieldName ) {
465 checkFieldName(fieldName);
466 _b.appendNum( (char) MinKey );
467 _b.appendStr( fieldName );
468 return *this;
469 }
470 // Append an element that is greater than all other keys.
471 BSONObjBuilder& appendMaxKey( const StringData& fieldName ) {
472 checkFieldName(fieldName);
473 _b.appendNum( (char) MaxKey );
474 _b.appendStr( fieldName );
475 return *this;
476 }
477
479 BSONObjBuilder& appendTimestamp( const StringData& fieldName , const Timestamp_t& ts = Timestamp_t() ) {
480 checkFieldName(fieldName);
481 _b.appendNum( (char) Timestamp );
482 _b.appendStr( fieldName );
483
484 char buf[2 * sizeof(uint32_t)];
485 DataCursor cur(buf);
486 cur.writeLEAndAdvance<>(ts.increment());
487 cur.writeLEAndAdvance<>(ts.seconds());
488
489 _b.appendBuf(buf, sizeof(buf));
490 return *this;
491 }
492
493 BSONObjBuilder& append( const StringData& fieldName, const Timestamp_t& ts ) {
494 return appendTimestamp(fieldName, ts);
495 }
496
497 /*
498 Append an element of the deprecated DBRef type.
499 @deprecated
500 */
501 BSONObjBuilder& appendDBRef( const StringData& fieldName, const StringData& ns, const OID &oid ) {
502 checkFieldName(fieldName);
503 _b.appendNum( (char) DBRef );
504 _b.appendStr( fieldName );
505 _b.appendNum( (int) ns.size() + 1 );
506 _b.appendStr( ns );
507 _b.appendBuf( oid.view().view(), OID::kOIDSize );
508 return *this;
509 }
510
511 BSONObjBuilder& append(const StringData& fieldName, const BSONDBRef& dbref) {
512 return appendDBRef(fieldName, dbref.ns, dbref.oid);
513 }
514
522 BSONObjBuilder& appendBinData( const StringData& fieldName, int len, BinDataType type, const void *data ) {
523 checkFieldName(fieldName);
524 _b.appendNum( (char) BinData );
525 _b.appendStr( fieldName );
526 _b.appendNum( len );
527 _b.appendNum( (char) type );
528 _b.appendBuf( data, len );
529 return *this;
530 }
531
532 BSONObjBuilder& append(const StringData& fieldName, const BSONBinData& bd) {
533 return appendBinData(fieldName, bd.length, bd.type, bd.data);
534 }
535
542 BSONObjBuilder& appendBinDataArrayDeprecated( const char * fieldName , const void * data , int len ) {
543 checkFieldName(fieldName);
544 _b.appendNum( (char) BinData );
545 _b.appendStr( fieldName );
546 _b.appendNum( len + 4 );
547 _b.appendNum( (char)0x2 );
548 _b.appendNum( len );
549 _b.appendBuf( data, len );
550 return *this;
551 }
552
556 BSONObjBuilder& appendCodeWScope( const StringData& fieldName, const StringData& code, const BSONObj &scope ) {
557 checkFieldName(fieldName);
558 _b.appendNum( (char) CodeWScope );
559 _b.appendStr( fieldName );
560 _b.appendNum( ( int )( 4 + 4 + code.size() + 1 + scope.objsize() ) );
561 _b.appendNum( ( int ) code.size() + 1 );
562 _b.appendStr( code );
563 _b.appendBuf( ( void * )scope.objdata(), scope.objsize() );
564 return *this;
565 }
566
567 BSONObjBuilder& append(const StringData& fieldName, const BSONCodeWScope& cws) {
568 return appendCodeWScope(fieldName, cws.code, cws.scope);
569 }
570
571 void appendUndefined( const StringData& fieldName ) {
572 _b.appendNum( (char) Undefined );
573 _b.appendStr( fieldName );
574 }
575
576 /* helper function -- see Query::where() for primary way to do this. */
577 void appendWhere( const StringData& code, const BSONObj &scope ) {
578 appendCodeWScope( "$where" , code , scope );
579 }
580
584 void appendMinForType( const StringData& fieldName , int type );
585 void appendMaxForType( const StringData& fieldName , int type );
586
588 template < class T >
589 BSONObjBuilder& append( const StringData& fieldName, const std::vector< T >& vals );
590
591 template < class T >
592 BSONObjBuilder& append( const StringData& fieldName, const std::list< T >& vals );
593
595 template < class T >
596 BSONObjBuilder& append( const StringData& fieldName, const std::set< T >& vals );
597
602 template < class K, class T >
603 BSONObjBuilder& append( const StringData& fieldName, const std::map< K, T >& vals );
604
611 massert( 10335 , "builder does not own memory", owned() );
612 doneFast();
613 char* buf = _b.buf();
614 decouple();
615 return BSONObj::takeOwnership(buf);
616 }
617
624 return BSONObj(_done());
625 }
626
627 // Like 'done' above, but does not construct a BSONObj to return to the caller.
628 void doneFast() {
629 (void)_done();
630 }
631
637 BSONObj temp(_done());
638 _b.setlen(_b.len()-1); //next append should overwrite the EOO
639 _b.reserveBytes(1); // Rereserve room for the real EOO
640 _doneCalled = false;
641 return temp;
642 }
643
651 void abandon() {
652 _doneCalled = true;
653 }
654
655 void decouple() {
656 _b.decouple(); // post done() call version. be sure jsobj frees...
657 }
658
659 void appendKeys( const BSONObj& keyPattern , const BSONObj& values );
660
661 static std::string MONGO_CLIENT_FUNC numStr( int i ) {
662 if (i>=0 && i<100 && numStrsReady)
663 return numStrs[i];
664 StringBuilder o;
665 o << i;
666 return o.str();
667 }
668
670 BSONObjBuilderValueStream &operator<<( const StringData& name ) {
671 _s.endField( name );
672 return _s;
673 }
674
676 BSONObjBuilder& operator<<( GENOIDLabeler ) { return genOID(); }
677
678 Labeler operator<<( const Labeler::Label &l ) {
679 massert( 10336 , "No subobject started", _s.subobjStarted() );
680 return _s << l;
681 }
682
683 template<typename T>
684 BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
685 _s.endField( f.name() );
686 return _s;
687 }
688
689 template<typename T>
690 BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
691 append( v.name(), v.value() );
692 return *this;
693 }
694
695 BSONObjBuilder& operator<<( const BSONElement& e ){
696 append( e );
697 return *this;
698 }
699
700 bool isArray() const {
701 return false;
702 }
703
705 bool owned() const { return &_b == &_buf; }
706
707 BSONObjIterator iterator() const ;
708
709 bool hasField( const StringData& name ) const ;
710
711 int len() const { return _b.len(); }
712
713 BufBuilder& bb() { return _b; }
714
715 private:
716 char* _done() {
717 if ( _doneCalled )
718 return _b.buf() + _offset;
719
720 _doneCalled = true;
721
722 // TODO remove this or find some way to prevent it from failing. Since this is intended
723 // for use with BSON() literal queries, it is less likely to result in oversized BSON.
724 _s.endField();
725
726 _b.claimReservedBytes(1); // Prevents adding EOO from failing.
727 _b.appendNum((char) EOO);
728
729 char *data = _b.buf() + _offset;
730 int size = _b.len() - _offset;
731 DataView(data).writeLE(size);
732 if ( _tracker )
733 _tracker->got( size );
734 return data;
735 }
736
737 BufBuilder &_b;
738 BufBuilder _buf;
739 int _offset;
740 BSONObjBuilderValueStream _s;
741 BSONSizeTracker * _tracker;
742 bool _doneCalled;
743
744 static const std::string numStrs[100]; // cache of 0 to 99 inclusive
745 static bool numStrsReady; // for static init safety.
746 };
747
748 class BSONArrayBuilder : boost::noncopyable {
749 public:
750 BSONArrayBuilder() : _i(0), _b() {}
751 BSONArrayBuilder( BufBuilder &_b ) : _i(0), _b(_b) {}
752 BSONArrayBuilder( int initialSize ) : _i(0), _b(initialSize) {}
753
754 template <typename T>
755 BSONArrayBuilder& append(const T& x) {
756 _b.append(num(), x);
757 return *this;
758 }
759
760 BSONArrayBuilder& append(const BSONElement& e) {
761 _b.appendAs(e, num());
762 return *this;
763 }
764
765 BSONArrayBuilder& operator<<(const BSONElement& e) {
766 return append(e);
767 }
768
769 template <typename T>
770 BSONArrayBuilder& operator<<(const T& x) {
771 _b << num().c_str() << x;
772 return *this;
773 }
774
775 void appendNull() {
776 _b.appendNull(num());
777 }
778
779 void appendUndefined() {
780 _b.appendUndefined(num());
781 }
782
787 BSONArray arr() { return BSONArray(_b.obj()); }
788 BSONObj obj() { return _b.obj(); }
789
790 BSONObj done() { return _b.done(); }
791
792 void doneFast() { _b.doneFast(); }
793
794 template < class T >
795 BSONArrayBuilder& append( const std::list< T >& vals );
796
797 template < class T >
798 BSONArrayBuilder& append( const std::set< T >& vals );
799
800 // These two just use next position
801 BufBuilder &subobjStart() { return _b.subobjStart( num() ); }
802 BufBuilder &subarrayStart() { return _b.subarrayStart( num() ); }
803
804 BSONArrayBuilder& appendRegex(const StringData& regex, const StringData& options = "") {
805 uassert(0, "regex cannot contain null bytes", regex.find('\0') == std::string::npos);
806 _b.appendRegex(num(), regex, options);
807 return *this;
808 }
809
810 BSONArrayBuilder& appendBinData(int len, BinDataType type, const void* data) {
811 _b.appendBinData(num(), len, type, data);
812 return *this;
813 }
814
815 BSONArrayBuilder& appendCode(const StringData& code) {
816 _b.appendCode(num(), code);
817 return *this;
818 }
819
820 BSONArrayBuilder& appendCodeWScope(const StringData& code, const BSONObj& scope) {
821 _b.appendCodeWScope(num(), code, scope);
822 return *this;
823 }
824
825 BSONArrayBuilder& appendTimeT(time_t dt) {
826 _b.appendTimeT(num(), dt);
827 return *this;
828 }
829
830 BSONArrayBuilder& appendDate(Date_t dt) {
831 _b.appendDate(num(), dt);
832 return *this;
833 }
834
835 BSONArrayBuilder& appendBool(bool val) {
836 _b.appendBool(num(), val);
837 return *this;
838 }
839
840 bool isArray() const {
841 return true;
842 }
843
844 int len() const { return _b.len(); }
845 int arrSize() const { return _i; }
846
847 BufBuilder& bb() { return _b.bb(); }
848
849 private:
850
851 std::string num() { return _b.numStr(_i++); }
852 int _i;
853 BSONObjBuilder _b;
854 };
855
856 template < class T >
857 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::vector< T >& vals ) {
858 BSONObjBuilder arrBuilder;
859 for ( unsigned int i = 0; i < vals.size(); ++i )
860 arrBuilder.append( numStr( i ), vals[ i ] );
861 appendArray( fieldName, arrBuilder.done() );
862 return *this;
863 }
864
865 template < class L >
866 inline BSONObjBuilder& _appendIt( BSONObjBuilder& _this, const StringData& fieldName, const L& vals ) {
867 BSONObjBuilder arrBuilder;
868 int n = 0;
869 for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
870 arrBuilder.append( BSONObjBuilder::numStr(n++), *i );
871 _this.appendArray( fieldName, arrBuilder.done() );
872 return _this;
873 }
874
875 template < class T >
876 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::list< T >& vals ) {
877 return _appendIt< std::list< T > >( *this, fieldName, vals );
878 }
879
880 template < class T >
881 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::set< T >& vals ) {
882 return _appendIt< std::set< T > >( *this, fieldName, vals );
883 }
884
885 template < class K, class T >
886 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::map< K, T >& vals ) {
887 BSONObjBuilder bob;
888 for( typename std::map<K,T>::const_iterator i = vals.begin(); i != vals.end(); ++i ){
889 bob.append(i->first, i->second);
890 }
891 append(fieldName, bob.obj());
892 return *this;
893 }
894
895
896 template < class L >
897 inline BSONArrayBuilder& _appendArrayIt( BSONArrayBuilder& _this, const L& vals ) {
898 for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
899 _this.append( *i );
900 return _this;
901 }
902
903 template < class T >
904 inline BSONArrayBuilder& BSONArrayBuilder::append( const std::list< T >& vals ) {
905 return _appendArrayIt< std::list< T > >( *this, vals );
906 }
907
908 template < class T >
909 inline BSONArrayBuilder& BSONArrayBuilder::append( const std::set< T >& vals ) {
910 return _appendArrayIt< std::set< T > >( *this, vals );
911 }
912
913 template<typename T>
914 inline BSONFieldValue<BSONObj> BSONField<T>::query( const char * q , const T& t ) const {
915 BSONObjBuilder b;
916 b.append( q , t );
917 return BSONFieldValue<BSONObj>( _name , b.obj() );
918 }
919
920 // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
921 inline BSONObj OR(const BSONObj& a, const BSONObj& b)
922 { return BSON( "$or" << BSON_ARRAY(a << b) ); }
923 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c)
924 { return BSON( "$or" << BSON_ARRAY(a << b << c) ); }
925 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d)
926 { return BSON( "$or" << BSON_ARRAY(a << b << c << d) ); }
927 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e)
928 { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e) ); }
929 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f)
930 { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e << f) ); }
931
932}
Definition bsonobjbuilder.h:748
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition bsonobjbuilder.h:787
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:166
const char * value() const
raw data of the element's value (so be careful).
Definition bsonelement.h:162
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:125
BSONType type() const
Returns the type of the element.
Definition bsonelement.h:109
Definition bsonmisc.h:197
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
BSONObjBuilder(BufBuilder &baseBuilder)
Definition bsonobjbuilder.h:75
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition bsonobjbuilder.h:651
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition bsonobjbuilder.h:424
bool owned() const
Definition bsonobjbuilder.h:705
BSONObjBuilder & append(const StringData &fieldName, BSONObj subObj)
add a subobject as a member
Definition bsonobjbuilder.h:141
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition bsonobjbuilder.h:123
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:225
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition bsonobjbuilder.h:303
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition bsonobjbuilder.h:239
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition bsonobjbuilder.h:636
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition bsonobjbuilder.h:320
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition bsonobjbuilder.h:451
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition bsonobjbuilder.h:234
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition bsonobjbuilder.h:150
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:216
BSONObjBuilder & appendCodeWScope(const StringData &fieldName, const StringData &code, const BSONObj &scope)
Append to the BSON object a field of type CodeWScope.
Definition bsonobjbuilder.h:556
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition bsonobjbuilder.h:411
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition bsonobjbuilder.h:420
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition bsonobjbuilder.h:456
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition bsonobjbuilder.h:479
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:199
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition bsonobjbuilder.h:428
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:670
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition bsonobjbuilder.h:131
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:542
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition bsonobjbuilder.h:522
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition bsonobjbuilder.h:207
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:610
BSONObj done()
Fetch the object we have built.
Definition bsonobjbuilder.h:623
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:176
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition bsonobjbuilder.h:186
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:676
BSONObjBuilder(int initsize=512)
Definition bsonobjbuilder.h:56
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition bsonobjbuilder.h:248
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:304
const char * objdata() const
Definition bsonobj.h:299
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage
Definition bsonmisc.h:240
Definition bsonmisc.h:116
Object ID type.
Definition oid.h:60
void clear()
initialize to 'null'
Definition oid.h:92
void init()
sets the contents to a new oid / randomized value
Definition shared_buffer.h:67
Definition timestamp.h:23
int len() const
Definition builder.h:202
the main MongoDB namespace
Definition bulk_operation_builder.h:24
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:559
Definition bsonmisc.h:164
Definition bsonmisc.h:150
Definition bsonmisc.h:157
Definition time_support.h:39
Definition bsonmisc.h:82
Definition bsonmisc.h:118