MongoDB  2.7.0
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/parse_number.h"
31 #include "mongo/bson/bsonelement.h"
32 #include "mongo/bson/bsonobj.h"
33 #include "mongo/bson/bsonmisc.h"
34 #include "mongo/bson/bson_builder_base.h"
35 #include "mongo/bson/bson_field.h"
36 #include "mongo/client/export_macros.h"
37 
38 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
39 #include "mongo/util/log.h"
40 #endif
41 
42 namespace mongo {
43 
44 #if defined(_WIN32)
45 // warning: 'this' : used in base member initializer list
46 #pragma warning( disable : 4355 )
47 #endif
48 
52  class MONGO_CLIENT_API BSONObjBuilder : public BSONBuilderBase, private boost::noncopyable {
53  public:
55  BSONObjBuilder(int initsize=512) : _b(_buf), _buf(initsize + sizeof(unsigned)), _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneCalled(false) {
56  _b.appendNum((unsigned)0); // ref-count
57  _b.skip(4); /*leave room for size field and ref-count*/
58  }
59 
63  BSONObjBuilder( BufBuilder &baseBuilder ) : _b( baseBuilder ), _buf( 0 ), _offset( baseBuilder.len() ), _s( this ) , _tracker(0) , _doneCalled(false) {
64  _b.skip( 4 );
65  }
66 
67  BSONObjBuilder( const BSONSizeTracker & tracker ) : _b(_buf) , _buf(tracker.getSize() + sizeof(unsigned) ), _offset( sizeof(unsigned) ), _s( this ) , _tracker( (BSONSizeTracker*)(&tracker) ) , _doneCalled(false) {
68  _b.appendNum((unsigned)0); // ref-count
69  _b.skip(4);
70  }
71 
72  ~BSONObjBuilder() {
73  if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
74  _done();
75  }
76  }
77 
79  BSONObjBuilder& appendElements(BSONObj x);
80 
82  BSONObjBuilder& appendElementsUnique( BSONObj x );
83 
86  verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
87  _b.appendBuf((void*) e.rawdata(), e.size());
88  return *this;
89  }
90 
92  BSONObjBuilder& appendAs(const BSONElement& e, const StringData& fieldName) {
93  verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
94  _b.appendNum((char) e.type());
95  _b.appendStr(fieldName);
96  _b.appendBuf((void *) e.value(), e.valuesize());
97  return *this;
98  }
99 
101  BSONObjBuilder& append(const StringData& fieldName, BSONObj subObj) {
102  _b.appendNum((char) Object);
103  _b.appendStr(fieldName);
104  _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
105  return *this;
106  }
107 
109  BSONObjBuilder& appendObject(const StringData& fieldName, const char * objdata , int size = 0 ) {
110  verify( objdata );
111  if ( size == 0 ) {
112  size = *((int*)objdata);
113  }
114 
115  verify( size > 4 && size < 100000000 );
116 
117  _b.appendNum((char) Object);
118  _b.appendStr(fieldName);
119  _b.appendBuf((void*)objdata, size );
120  return *this;
121  }
122 
134  BufBuilder &subobjStart(const StringData& fieldName) {
135  _b.appendNum((char) Object);
136  _b.appendStr(fieldName);
137  return _b;
138  }
139 
143  BSONObjBuilder& appendArray(const StringData& fieldName, const BSONObj &subObj) {
144  _b.appendNum((char) Array);
145  _b.appendStr(fieldName);
146  _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
147  return *this;
148  }
149  BSONObjBuilder& append(const StringData& fieldName, BSONArray arr) {
150  return appendArray(fieldName, arr);
151  }
152 
155  BufBuilder &subarrayStart(const StringData& fieldName) {
156  _b.appendNum((char) Array);
157  _b.appendStr(fieldName);
158  return _b;
159  }
160 
162  BSONObjBuilder& appendBool(const StringData& fieldName, int val) {
163  _b.appendNum((char) Bool);
164  _b.appendStr(fieldName);
165  _b.appendNum((char) (val?1:0));
166  return *this;
167  }
168 
170  BSONObjBuilder& append(const StringData& fieldName, bool val) {
171  _b.appendNum((char) Bool);
172  _b.appendStr(fieldName);
173  _b.appendNum((char) (val?1:0));
174  return *this;
175  }
176 
178  BSONObjBuilder& append(const StringData& fieldName, int n) {
179  _b.appendNum((char) NumberInt);
180  _b.appendStr(fieldName);
181  _b.appendNum(n);
182  return *this;
183  }
184 
186  BSONObjBuilder& append(const StringData& fieldName, unsigned n) {
187  return append(fieldName, (int) n);
188  }
189 
191  BSONObjBuilder& append(const StringData& fieldName, long long n) {
192  _b.appendNum((char) NumberLong);
193  _b.appendStr(fieldName);
194  _b.appendNum(n);
195  return *this;
196  }
197 
199  BSONObjBuilder& appendIntOrLL( const StringData& fieldName , long long n ) {
200  // extra () to avoid max macro on windows
201  static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
202  static const long long minInt = -maxInt;
203  if ( minInt < n && n < maxInt ) {
204  append( fieldName , static_cast<int>( n ) );
205  }
206  else {
207  append( fieldName , n );
208  }
209  return *this;
210  }
211 
216  BSONObjBuilder& appendNumber( const StringData& fieldName , int n ) {
217  return append( fieldName , n );
218  }
219 
220  BSONObjBuilder& appendNumber( const StringData& fieldName , double d ) {
221  return append( fieldName , d );
222  }
223 
224  BSONObjBuilder& appendNumber( const StringData& fieldName , size_t n ) {
225  static const size_t maxInt = ( 1 << 30 );
226 
227  if ( n < maxInt )
228  append( fieldName, static_cast<int>( n ) );
229  else
230  append( fieldName, static_cast<long long>( n ) );
231  return *this;
232  }
233 
234  BSONObjBuilder& appendNumber( const StringData& fieldName, long long llNumber ) {
235  static const long long maxInt = ( 1LL << 30 );
236  static const long long minInt = -maxInt;
237  static const long long maxDouble = ( 1LL << 40 );
238  static const long long minDouble = -maxDouble;
239 
240  if ( minInt < llNumber && llNumber < maxInt ) {
241  append( fieldName, static_cast<int>( llNumber ) );
242  }
243  else if ( minDouble < llNumber && llNumber < maxDouble ) {
244  append( fieldName, static_cast<double>( llNumber ) );
245  }
246  else {
247  append( fieldName, llNumber );
248  }
249 
250  return *this;
251  }
252 
254  BSONObjBuilder& append(const StringData& fieldName, double n) {
255  _b.appendNum((char) NumberDouble);
256  _b.appendStr(fieldName);
257  _b.appendNum(n);
258  return *this;
259  }
260 
264  bool appendAsNumber( const StringData& fieldName , const std::string& data );
265 
270  BSONObjBuilder& appendOID(const StringData& fieldName, OID *oid = 0 , bool generateIfBlank = false ) {
271  _b.appendNum((char) jstOID);
272  _b.appendStr(fieldName);
273  if ( oid )
274  _b.appendBuf( (void *) oid, 12 );
275  else {
276  OID tmp;
277  if ( generateIfBlank )
278  tmp.init();
279  else
280  tmp.clear();
281  _b.appendBuf( (void *) &tmp, 12 );
282  }
283  return *this;
284  }
285 
291  BSONObjBuilder& append( const StringData& fieldName, OID oid ) {
292  _b.appendNum((char) jstOID);
293  _b.appendStr(fieldName);
294  _b.appendBuf( (void *) &oid, 12 );
295  return *this;
296  }
297 
303  return append("_id", OID::gen());
304  }
305 
310  BSONObjBuilder& appendTimeT(const StringData& fieldName, time_t dt) {
311  _b.appendNum((char) Date);
312  _b.appendStr(fieldName);
313  _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
314  return *this;
315  }
320  BSONObjBuilder& appendDate(const StringData& fieldName, Date_t dt) {
321  /* easy to pass a time_t to this and get a bad result. thus this warning. */
322 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
323  if( dt > 0 && dt <= 0xffffffff ) {
324  static int n;
325  if( n++ == 0 )
326  log() << "DEV WARNING appendDate() called with a tiny (but nonzero) date" << std::endl;
327  }
328 #endif
329  _b.appendNum((char) Date);
330  _b.appendStr(fieldName);
331  _b.appendNum(dt);
332  return *this;
333  }
334  BSONObjBuilder& append(const StringData& fieldName, Date_t dt) {
335  return appendDate(fieldName, dt);
336  }
337 
342  BSONObjBuilder& appendRegex(const StringData& fieldName, const StringData& regex, const StringData& options = "") {
343  _b.appendNum((char) RegEx);
344  _b.appendStr(fieldName);
345  _b.appendStr(regex);
346  _b.appendStr(options);
347  return *this;
348  }
349 
350  BSONObjBuilder& append(const StringData& fieldName, const BSONRegEx& regex) {
351  return appendRegex(fieldName, regex.pattern, regex.flags);
352  }
353 
354  BSONObjBuilder& appendCode(const StringData& fieldName, const StringData& code) {
355  _b.appendNum((char) Code);
356  _b.appendStr(fieldName);
357  _b.appendNum((int) code.size()+1);
358  _b.appendStr(code);
359  return *this;
360  }
361 
362  BSONObjBuilder& append(const StringData& fieldName, const BSONCode& code) {
363  return appendCode(fieldName, code.code);
364  }
365 
368  BSONObjBuilder& append(const StringData& fieldName, const char *str, int sz) {
369  _b.appendNum((char) String);
370  _b.appendStr(fieldName);
371  _b.appendNum((int)sz);
372  _b.appendBuf(str, sz);
373  return *this;
374  }
376  BSONObjBuilder& append(const StringData& fieldName, const char *str) {
377  return append(fieldName, str, (int) strlen(str)+1);
378  }
380  BSONObjBuilder& append(const StringData& fieldName, const std::string& str) {
381  return append(fieldName, str.c_str(), (int) str.size()+1);
382  }
384  BSONObjBuilder& append(const StringData& fieldName, const StringData& str) {
385  _b.appendNum((char) String);
386  _b.appendStr(fieldName);
387  _b.appendNum((int)str.size()+1);
388  _b.appendStr(str, true);
389  return *this;
390  }
391 
392  BSONObjBuilder& appendSymbol(const StringData& fieldName, const StringData& symbol) {
393  _b.appendNum((char) Symbol);
394  _b.appendStr(fieldName);
395  _b.appendNum((int) symbol.size()+1);
396  _b.appendStr(symbol);
397  return *this;
398  }
399 
400  BSONObjBuilder& append(const StringData& fieldName, const BSONSymbol& symbol) {
401  return appendSymbol(fieldName, symbol.symbol);
402  }
403 
405  void appendNull() {
406  msgasserted(16234, "Invalid call to appendNull in BSONObj Builder.");
407  }
408 
410  BSONObjBuilder& appendNull( const StringData& fieldName ) {
411  _b.appendNum( (char) jstNULL );
412  _b.appendStr( fieldName );
413  return *this;
414  }
415 
416  // Append an element that is less than all other keys.
417  BSONObjBuilder& appendMinKey( const StringData& fieldName ) {
418  _b.appendNum( (char) MinKey );
419  _b.appendStr( fieldName );
420  return *this;
421  }
422  // Append an element that is greater than all other keys.
423  BSONObjBuilder& appendMaxKey( const StringData& fieldName ) {
424  _b.appendNum( (char) MaxKey );
425  _b.appendStr( fieldName );
426  return *this;
427  }
428 
429  // Append a Timestamp field -- will be updated to next OpTime on db insert.
430  BSONObjBuilder& appendTimestamp( const StringData& fieldName ) {
431  _b.appendNum( (char) Timestamp );
432  _b.appendStr( fieldName );
433  _b.appendNum( (unsigned long long) 0 );
434  return *this;
435  }
436 
441  BSONObjBuilder& append(const StringData& fieldName, OpTime optime);
442 
450  BSONObjBuilder& appendTimestamp( const StringData& fieldName , unsigned long long val ) {
451  _b.appendNum( (char) Timestamp );
452  _b.appendStr( fieldName );
453  _b.appendNum( val );
454  return *this;
455  }
456 
462  BSONObjBuilder& appendTimestamp( const StringData& fieldName , unsigned long long time , unsigned int inc );
463 
464  /*
465  Append an element of the deprecated DBRef type.
466  @deprecated
467  */
468  BSONObjBuilder& appendDBRef( const StringData& fieldName, const StringData& ns, const OID &oid ) {
469  _b.appendNum( (char) DBRef );
470  _b.appendStr( fieldName );
471  _b.appendNum( (int) ns.size() + 1 );
472  _b.appendStr( ns );
473  _b.appendBuf( (void *) &oid, 12 );
474  return *this;
475  }
476 
477  BSONObjBuilder& append(const StringData& fieldName, const BSONDBRef& dbref) {
478  return appendDBRef(fieldName, dbref.ns, dbref.oid);
479  }
480 
488  BSONObjBuilder& appendBinData( const StringData& fieldName, int len, BinDataType type, const void *data ) {
489  _b.appendNum( (char) BinData );
490  _b.appendStr( fieldName );
491  _b.appendNum( len );
492  _b.appendNum( (char) type );
493  _b.appendBuf( data, len );
494  return *this;
495  }
496 
497  BSONObjBuilder& append(const StringData& fieldName, const BSONBinData& bd) {
498  return appendBinData(fieldName, bd.length, bd.type, bd.data);
499  }
500 
507  BSONObjBuilder& appendBinDataArrayDeprecated( const char * fieldName , const void * data , int len ) {
508  _b.appendNum( (char) BinData );
509  _b.appendStr( fieldName );
510  _b.appendNum( len + 4 );
511  _b.appendNum( (char)0x2 );
512  _b.appendNum( len );
513  _b.appendBuf( data, len );
514  return *this;
515  }
516 
520  BSONObjBuilder& appendCodeWScope( const StringData& fieldName, const StringData& code, const BSONObj &scope ) {
521  _b.appendNum( (char) CodeWScope );
522  _b.appendStr( fieldName );
523  _b.appendNum( ( int )( 4 + 4 + code.size() + 1 + scope.objsize() ) );
524  _b.appendNum( ( int ) code.size() + 1 );
525  _b.appendStr( code );
526  _b.appendBuf( ( void * )scope.objdata(), scope.objsize() );
527  return *this;
528  }
529 
530  BSONObjBuilder& append(const StringData& fieldName, const BSONCodeWScope& cws) {
531  return appendCodeWScope(fieldName, cws.code, cws.scope);
532  }
533 
534  void appendUndefined( const StringData& fieldName ) {
535  _b.appendNum( (char) Undefined );
536  _b.appendStr( fieldName );
537  }
538 
539  /* helper function -- see Query::where() for primary way to do this. */
540  void appendWhere( const StringData& code, const BSONObj &scope ) {
541  appendCodeWScope( "$where" , code , scope );
542  }
543 
547  void appendMinForType( const StringData& fieldName , int type );
548  void appendMaxForType( const StringData& fieldName , int type );
549 
551  template < class T >
552  BSONObjBuilder& append( const StringData& fieldName, const std::vector< T >& vals );
553 
554  template < class T >
555  BSONObjBuilder& append( const StringData& fieldName, const std::list< T >& vals );
556 
558  template < class T >
559  BSONObjBuilder& append( const StringData& fieldName, const std::set< T >& vals );
560 
565  template < class K, class T >
566  BSONObjBuilder& append( const StringData& fieldName, const std::map< K, T >& vals );
567 
574  bool own = owned();
575  massert( 10335 , "builder does not own memory", own );
576  doneFast();
577  BSONObj::Holder* h = (BSONObj::Holder*)_b.buf();
578  decouple(); // sets _b.buf() to NULL
579  return BSONObj(h);
580  }
581 
588  return BSONObj(_done());
589  }
590 
591  // Like 'done' above, but does not construct a BSONObj to return to the caller.
592  void doneFast() {
593  (void)_done();
594  }
595 
601  BSONObj temp(_done());
602  _b.setlen(_b.len()-1); //next append should overwrite the EOO
603  _doneCalled = false;
604  return temp;
605  }
606 
614  void abandon() {
615  _doneCalled = true;
616  }
617 
618  void decouple() {
619  _b.decouple(); // post done() call version. be sure jsobj frees...
620  }
621 
622  void appendKeys( const BSONObj& keyPattern , const BSONObj& values );
623 
624  static std::string numStr( int i ) {
625  if (i>=0 && i<100 && numStrsReady)
626  return numStrs[i];
627  StringBuilder o;
628  o << i;
629  return o.str();
630  }
631 
633  BSONObjBuilderValueStream &operator<<( const StringData& name ) {
634  _s.endField( name );
635  return _s;
636  }
637 
639  BSONObjBuilder& operator<<( GENOIDLabeler ) { return genOID(); }
640 
641  Labeler operator<<( const Labeler::Label &l ) {
642  massert( 10336 , "No subobject started", _s.subobjStarted() );
643  return _s << l;
644  }
645 
646  template<typename T>
647  BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
648  _s.endField( f.name() );
649  return _s;
650  }
651 
652  template<typename T>
653  BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
654  append( v.name(), v.value() );
655  return *this;
656  }
657 
658  BSONObjBuilder& operator<<( const BSONElement& e ){
659  append( e );
660  return *this;
661  }
662 
663  bool isArray() const {
664  return false;
665  }
666 
668  bool owned() const { return &_b == &_buf; }
669 
670  BSONObjIterator iterator() const ;
671 
672  bool hasField( const StringData& name ) const ;
673 
674  int len() const { return _b.len(); }
675 
676  BufBuilder& bb() { return _b; }
677 
678  private:
679  char* _done() {
680  if ( _doneCalled )
681  return _b.buf() + _offset;
682 
683  _doneCalled = true;
684  _s.endField();
685  _b.appendNum((char) EOO);
686  char *data = _b.buf() + _offset;
687  int size = _b.len() - _offset;
688  *((int*)data) = size;
689  if ( _tracker )
690  _tracker->got( size );
691  return data;
692  }
693 
694  BufBuilder &_b;
695  BufBuilder _buf;
696  int _offset;
697  BSONObjBuilderValueStream _s;
698  BSONSizeTracker * _tracker;
699  bool _doneCalled;
700 
701  static const std::string numStrs[100]; // cache of 0 to 99 inclusive
702  static bool numStrsReady; // for static init safety. see comments in db/jsobj.cpp
703  };
704 
705  class BSONArrayBuilder : public BSONBuilderBase, private boost::noncopyable {
706  public:
707  BSONArrayBuilder() : _i(0), _b() {}
708  BSONArrayBuilder( BufBuilder &_b ) : _i(0), _b(_b) {}
709  BSONArrayBuilder( int initialSize ) : _i(0), _b(initialSize) {}
710 
711  template <typename T>
712  BSONArrayBuilder& append(const T& x) {
713  _b.append(num(), x);
714  return *this;
715  }
716 
717  BSONArrayBuilder& append(const BSONElement& e) {
718  _b.appendAs(e, num());
719  return *this;
720  }
721 
722  BSONArrayBuilder& operator<<(const BSONElement& e) {
723  return append(e);
724  }
725 
726  template <typename T>
727  BSONArrayBuilder& operator<<(const T& x) {
728  _b << num().c_str() << x;
729  return *this;
730  }
731 
732  void appendNull() {
733  _b.appendNull(num());
734  }
735 
736  void appendUndefined() {
737  _b.appendUndefined(num());
738  }
739 
744  BSONArray arr() { return BSONArray(_b.obj()); }
745  BSONObj obj() { return _b.obj(); }
746 
747  BSONObj done() { return _b.done(); }
748 
749  void doneFast() { _b.doneFast(); }
750 
751  BSONArrayBuilder& append(const StringData& name, int n) {
752  fill( name );
753  append( n );
754  return *this;
755  }
756 
757  BSONArrayBuilder& append(const StringData& name, long long n) {
758  fill( name );
759  append( n );
760  return *this;
761  }
762 
763  BSONArrayBuilder& append(const StringData& name, double n) {
764  fill( name );
765  append( n );
766  return *this;
767  }
768 
769  template <typename T>
770  BSONArrayBuilder& append(const StringData& name, const T& x) {
771  fill( name );
772  append( x );
773  return *this;
774  }
775 
776  template < class T >
777  BSONArrayBuilder& append( const std::list< T >& vals );
778 
779  template < class T >
780  BSONArrayBuilder& append( const std::set< T >& vals );
781 
782  // These two just use next position
783  BufBuilder &subobjStart() { return _b.subobjStart( num() ); }
784  BufBuilder &subarrayStart() { return _b.subarrayStart( num() ); }
785 
786  // These fill missing entries up to pos. if pos is < next pos is ignored
787  BufBuilder &subobjStart(int pos) {
788  fill(pos);
789  return _b.subobjStart( num() );
790  }
791  BufBuilder &subarrayStart(int pos) {
792  fill(pos);
793  return _b.subarrayStart( num() );
794  }
795 
796  // These should only be used where you really need interface compatibility with BSONObjBuilder
797  // Currently they are only used by update.cpp and it should probably stay that way
798  BufBuilder &subobjStart( const StringData& name ) {
799  fill( name );
800  return _b.subobjStart( num() );
801  }
802 
803  BufBuilder &subarrayStart( const StringData& name ) {
804  fill( name );
805  return _b.subarrayStart( num() );
806  }
807 
808  BSONArrayBuilder& appendArray( const StringData& name, const BSONObj& subObj ) {
809  fill( name );
810  _b.appendArray( num(), subObj );
811  return *this;
812  }
813 
814  BSONArrayBuilder& appendAs( const BSONElement &e, const StringData& name) {
815  fill( name );
816  append( e );
817  return *this;
818  }
819 
820  BSONArrayBuilder& appendTimestamp(unsigned int sec, unsigned int inc) {
821  _b.appendTimestamp(num(), sec, inc);
822  return *this;
823  }
824 
825  BSONArrayBuilder& appendTimestamp(unsigned long long ts) {
826  _b.appendTimestamp(num(), ts);
827  return *this;
828  }
829 
830  BSONArrayBuilder& append(const StringData& s) {
831  _b.append(num(), s);
832  return *this;
833  }
834 
835  bool isArray() const {
836  return true;
837  }
838 
839  int len() const { return _b.len(); }
840  int arrSize() const { return _i; }
841 
842  BufBuilder& bb() { return _b.bb(); }
843 
844  private:
845  // These two are undefined privates to prevent their accidental
846  // use as we don't support unsigned ints in BSON
847  BSONObjBuilder& append(const StringData& fieldName, unsigned int val);
848  BSONObjBuilder& append(const StringData& fieldName, unsigned long long val);
849 
850  void fill( const StringData& name ) {
851  long int n;
852  Status status = parseNumberFromStringWithBase( name, 10, &n );
853  uassert( 13048,
854  (string)"can't append to array using string field name: " + name.toString(),
855  status.isOK() );
856  fill(n);
857  }
858 
859  void fill (int upTo){
860  // if this is changed make sure to update error message and jstests/set7.js
861  const int maxElems = 1500000;
862  BOOST_STATIC_ASSERT(maxElems < (BSONObjMaxUserSize/10));
863  uassert(15891, "can't backfill array to larger than 1,500,000 elements", upTo <= maxElems);
864 
865  while( _i < upTo )
866  appendNull();
867  }
868 
869  std::string num() { return _b.numStr(_i++); }
870  int _i;
871  BSONObjBuilder _b;
872  };
873 
874  template < class T >
875  inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::vector< T >& vals ) {
876  BSONObjBuilder arrBuilder;
877  for ( unsigned int i = 0; i < vals.size(); ++i )
878  arrBuilder.append( numStr( i ), vals[ i ] );
879  appendArray( fieldName, arrBuilder.done() );
880  return *this;
881  }
882 
883  template < class L >
884  inline BSONObjBuilder& _appendIt( BSONObjBuilder& _this, const StringData& fieldName, const L& vals ) {
885  BSONObjBuilder arrBuilder;
886  int n = 0;
887  for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
888  arrBuilder.append( BSONObjBuilder::numStr(n++), *i );
889  _this.appendArray( fieldName, arrBuilder.done() );
890  return _this;
891  }
892 
893  template < class T >
894  inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::list< T >& vals ) {
895  return _appendIt< std::list< T > >( *this, fieldName, vals );
896  }
897 
898  template < class T >
899  inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::set< T >& vals ) {
900  return _appendIt< std::set< T > >( *this, fieldName, vals );
901  }
902 
903  template < class K, class T >
904  inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const std::map< K, T >& vals ) {
905  BSONObjBuilder bob;
906  for( typename std::map<K,T>::const_iterator i = vals.begin(); i != vals.end(); ++i ){
907  bob.append(i->first, i->second);
908  }
909  append(fieldName, bob.obj());
910  return *this;
911  }
912 
913 
914  template < class L >
915  inline BSONArrayBuilder& _appendArrayIt( BSONArrayBuilder& _this, const L& vals ) {
916  for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
917  _this.append( *i );
918  return _this;
919  }
920 
921  template < class T >
922  inline BSONArrayBuilder& BSONArrayBuilder::append( const std::list< T >& vals ) {
923  return _appendArrayIt< std::list< T > >( *this, vals );
924  }
925 
926  template < class T >
927  inline BSONArrayBuilder& BSONArrayBuilder::append( const std::set< T >& vals ) {
928  return _appendArrayIt< std::set< T > >( *this, vals );
929  }
930 
931 
932  // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
933  inline BSONObj OR(const BSONObj& a, const BSONObj& b)
934  { return BSON( "$or" << BSON_ARRAY(a << b) ); }
935  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c)
936  { return BSON( "$or" << BSON_ARRAY(a << b << c) ); }
937  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d)
938  { return BSON( "$or" << BSON_ARRAY(a << b << c << d) ); }
939  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e)
940  { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e) ); }
941  inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f)
942  { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e << f) ); }
943 
944 }
Definition: bsonobj.h:501
BSONObjBuilder(BufBuilder &baseBuilder)
Definition: bsonobjbuilder.h:63
end of object
Definition: bsontypes.h:47
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition: bsonobjbuilder.h:507
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:52
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition: bsonobjbuilder.h:186
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:85
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:587
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:112
int size(int maxLen) const
Size of the element.
Definition: bson-inl.h:491
BSONObjBuilder & appendRegex(const StringData &fieldName, const StringData &regex, const StringData &options="")
Append a regular expression value.
Definition: bsonobjbuilder.h:342
Definition: bsonmisc.h:161
const char * objdata() const
Definition: bsonobj.h:266
Definition: bsonmisc.h:86
larger than all other types
Definition: bsontypes.h:87
int len() const
Definition: builder.h:195
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition: bsonobjbuilder.h:600
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition: bsonobjbuilder.h:488
Definition: bsonmisc.h:201
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:633
BSONObjBuilder & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:639
int objsize() const
Definition: bsonobj.h:270
BufBuilder & subarrayStart(const StringData &fieldName)
add header for a new subarray and return bufbuilder for writing to the subarray's body ...
Definition: bsonobjbuilder.h:155
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition: bsonobjbuilder.h:376
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition: bsonobjbuilder.h:170
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition: bsonobjbuilder.h:573
BSONObjBuilder & appendCodeWScope(const StringData &fieldName, const StringData &code, const BSONObj &scope)
Append to the BSON object a field of type CodeWScope.
Definition: bsonobjbuilder.h:520
Definition: time_support.h:35
Updated to a Date with value next OpTime on insert.
Definition: bsontypes.h:81
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition: bsonobjbuilder.h:254
bool owned() const
Definition: bsonobjbuilder.h:668
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition: bsonobjbuilder.h:614
date type
Definition: bsontypes.h:65
const char * value() const
raw data of the element's value (so be careful).
Definition: bsonelement.h:162
boolean type
Definition: bsontypes.h:63
BSONObjBuilder(int initsize=512)
Definition: bsonobjbuilder.h:55
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition: bsonobjbuilder.h:380
smaller than all other types
Definition: bsontypes.h:45
BSONObjBuilder & appendDate(const StringData &fieldName, Date_t dt)
Append a date.
Definition: bsonobjbuilder.h:320
BSONObjBuilder & append(const StringData &fieldName, OID oid)
Append a BSON Object ID.
Definition: bsonobjbuilder.h:291
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
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:166
void init()
sets the contents to a new oid / randomized value
Definition: oid.cpp:99
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:244
BufBuilder & subobjStart(const StringData &fieldName)
add header for a new subobject and return bufbuilder for writing to the subobject's body ...
Definition: bsonobjbuilder.h:134
ObjectId.
Definition: bsontypes.h:61
an embedded object
Definition: bsontypes.h:53
32 bit signed integer
Definition: bsontypes.h:79
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition: bsonobjbuilder.h:405
double precision floating point value
Definition: bsontypes.h:49
null type
Definition: bsontypes.h:67
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:92
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition: bsonobjbuilder.h:178
BSONObjBuilder & append(const StringData &fieldName, BSONObj subObj)
add a subobject as a member
Definition: bsonobjbuilder.h:101
a programming language (e.g., Python) symbol
Definition: bsontypes.h:75
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition: bsonobjbuilder.h:199
javascript code that can execute on the database server, with SavedContext
Definition: bsontypes.h:77
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition: bsonobjbuilder.h:191
Definition: bsonmisc.h:122
Definition: bsonmisc.h:120
Definition: bsonmisc.h:168
Undefined type.
Definition: bsontypes.h:59
iterator for a BSONObj
Definition: bsonobjiterator.h:37
BSONObjBuilder & appendTimestamp(const StringData &fieldName, unsigned long long val)
Alternative way to store an OpTime in BSON.
Definition: bsonobjbuilder.h:450
Definition: bsonmisc.h:154
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition: bsonobjbuilder.h:270
LogstreamBuilder log()
Returns a LogstreamBuilder for logging a message with LogSeverity::Log().
Definition: log.h:69
regular expression, a pattern with options
Definition: bsontypes.h:69
64 bit integer
Definition: bsontypes.h:83
an embedded array
Definition: bsontypes.h:55
deprecated / use CodeWScope
Definition: bsontypes.h:73
void clear()
initialize to 'null'
Definition: oid.h:60
deprecated / will be redesigned
Definition: bsontypes.h:71
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:62
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition: bsonobjbuilder.h:410
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition: bsonobjbuilder.h:143
BSONObjBuilder & genOID()
Generate and assign an object id for the _id field.
Definition: bsonobjbuilder.h:302
Definition: bsonobjbuilder.h:705
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition: bsonobjbuilder.h:384
Definition: bsonobj.h:585
Object ID type.
Definition: oid.h:42
binary data
Definition: bsontypes.h:57
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition: bsonobjbuilder.h:162
Definition: bson_builder_base.h:29
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:216
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition: bsonobjbuilder.h:368
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition: bsonobjbuilder.h:744
BSONObjBuilder & appendTimeT(const StringData &fieldName, time_t dt)
Append a time_t date.
Definition: bsonobjbuilder.h:310
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition: bsonobjbuilder.h:109
character string, stored in utf8
Definition: bsontypes.h:51