MongoDB C++ Driver  legacy-1.0.5
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
75  BSONObjBuilder(BufBuilder &baseBuilder)
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 
117  BSONObjBuilder& appendElements(BSONObj x);
118 
120  BSONObjBuilder& appendElementsUnique( BSONObj x );
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 }
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition: bsonobjbuilder.h:651
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 & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition: bsonobjbuilder.h:239
Definition: timestamp.h:23
end of object
Definition: bsontypes.h:42
Definition: bsonmisc.h:150
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition: bsonobjbuilder.h:787
int objsize() const
Definition: bsonobj.h:304
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:320
the main MongoDB namespace
Definition: bulk_operation_builder.h:24
int size(int maxLen) const
Size of the element.
Definition: bsonmisc.h:118
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:524
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition: bsonobjbuilder.h:610
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:479
const char * objdata() const
Definition: bsonobj.h:299
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:123
Definition: bsonmisc.h:82
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:207
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 char *str)
Append a string element.
Definition: bsonobjbuilder.h:420
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition: bsonobjbuilder.h:542
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:240
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition: bsonobjbuilder.h:456
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:303
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:623
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition: bsonobjbuilder.h:636
const char * value() const
raw data of the element's value (so be careful).
Definition: bsonelement.h:162
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:109
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:411
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
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:164
Definition: builder.h:89
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:166
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:157
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
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:556
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition: bsonobjbuilder.h:451
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:186
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:131
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:234
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:150
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:670
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition: bsonobjbuilder.h:225
Definition: bsonobj.h:559
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition: bsonobjbuilder.h:522
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition: bsonobjbuilder.h:248
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition: bsonobjbuilder.h:428
int len() const
Definition: builder.h:202
Definition: bsonmisc.h:116
Definition: bsonobjbuilder.h:748
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 & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:676
binary data
Definition: bsontypes.h:52
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition: bsonobjbuilder.h:216
void clear()
initialize to 'null'
Definition: oid.h:92
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:424
Definition: bsonmisc.h:197
BSONObjBuilder(BufBuilder &baseBuilder)
Definition: bsonobjbuilder.h:75
character string, stored in utf8
Definition: bsontypes.h:46