00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include <limits>
00026 #include <cmath>
00027 using namespace std;
00028
00029 namespace mongo {
00030
00031 #if defined(_WIN32)
00032
00033 #pragma warning( disable : 4355 )
00034 #endif
00035
00036 template<typename T>
00037 class BSONFieldValue {
00038 public:
00039 BSONFieldValue( const string& name , const T& t ) {
00040 _name = name;
00041 _t = t;
00042 }
00043
00044 const T& value() const { return _t; }
00045 const string& name() const { return _name; }
00046
00047 private:
00048 string _name;
00049 T _t;
00050 };
00051
00052 template<typename T>
00053 class BSONField {
00054 public:
00055 BSONField( const string& name , const string& longName="" )
00056 : _name(name), _longName(longName) {}
00057 const string& name() const { return _name; }
00058 operator string() const { return _name; }
00059
00060 BSONFieldValue<T> make( const T& t ) const {
00061 return BSONFieldValue<T>( _name , t );
00062 }
00063
00064 BSONFieldValue<BSONObj> gt( const T& t ) const { return query( "$gt" , t ); }
00065 BSONFieldValue<BSONObj> lt( const T& t ) const { return query( "$lt" , t ); }
00066
00067 BSONFieldValue<BSONObj> query( const char * q , const T& t ) const;
00068
00069 BSONFieldValue<T> operator()( const T& t ) const {
00070 return BSONFieldValue<T>( _name , t );
00071 }
00072
00073 private:
00074 string _name;
00075 string _longName;
00076 };
00077
00081 class BSONObjBuilder : boost::noncopyable {
00082 public:
00084 BSONObjBuilder(int initsize=512) : _b(_buf), _buf(initsize), _offset( 0 ), _s( this ) , _tracker(0) , _doneCalled(false) {
00085 _b.skip(4);
00086 }
00087
00088
00090 BSONObjBuilder( BufBuilder &baseBuilder ) : _b( baseBuilder ), _buf( 0 ), _offset( baseBuilder.len() ), _s( this ) , _tracker(0) , _doneCalled(false) {
00091 _b.skip( 4 );
00092 }
00093
00094 BSONObjBuilder( const BSONSizeTracker & tracker ) : _b(_buf) , _buf(tracker.getSize() ), _offset(0), _s( this ) , _tracker( (BSONSizeTracker*)(&tracker) ) , _doneCalled(false) {
00095 _b.skip( 4 );
00096 }
00097
00098 ~BSONObjBuilder() {
00099 if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
00100 _done();
00101 }
00102 }
00103
00105 BSONObjBuilder& appendElements(BSONObj x);
00106
00108 BSONObjBuilder& appendElementsUnique( BSONObj x );
00109
00111 BSONObjBuilder& append( const BSONElement& e) {
00112 assert( !e.eoo() );
00113 _b.appendBuf((void*) e.rawdata(), e.size());
00114 return *this;
00115 }
00116
00118 BSONObjBuilder& appendAs(const BSONElement& e, const StringData& fieldName) {
00119 assert( !e.eoo() );
00120 _b.appendNum((char) e.type());
00121 _b.appendStr(fieldName);
00122 _b.appendBuf((void *) e.value(), e.valuesize());
00123 return *this;
00124 }
00125
00127 BSONObjBuilder& append(const StringData& fieldName, BSONObj subObj) {
00128 _b.appendNum((char) Object);
00129 _b.appendStr(fieldName);
00130 _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
00131 return *this;
00132 }
00133
00135 BSONObjBuilder& appendObject(const StringData& fieldName, const char * objdata , int size = 0 ) {
00136 assert( objdata );
00137 if ( size == 0 ) {
00138 size = *((int*)objdata);
00139 }
00140
00141 assert( size > 4 && size < 100000000 );
00142
00143 _b.appendNum((char) Object);
00144 _b.appendStr(fieldName);
00145 _b.appendBuf((void*)objdata, size );
00146 return *this;
00147 }
00148
00149
00152 BufBuilder &subobjStart(const StringData& fieldName) {
00153 _b.appendNum((char) Object);
00154 _b.appendStr(fieldName);
00155 return _b;
00156 }
00157
00161 BSONObjBuilder& appendArray(const StringData& fieldName, const BSONObj &subObj) {
00162 _b.appendNum((char) Array);
00163 _b.appendStr(fieldName);
00164 _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
00165 return *this;
00166 }
00167 BSONObjBuilder& append(const StringData& fieldName, BSONArray arr) {
00168 return appendArray(fieldName, arr);
00169 }
00170
00173 BufBuilder &subarrayStart(const StringData& fieldName) {
00174 _b.appendNum((char) Array);
00175 _b.appendStr(fieldName);
00176 return _b;
00177 }
00178
00180 BSONObjBuilder& appendBool(const StringData& fieldName, int val) {
00181 _b.appendNum((char) Bool);
00182 _b.appendStr(fieldName);
00183 _b.appendNum((char) (val?1:0));
00184 return *this;
00185 }
00186
00188 BSONObjBuilder& append(const StringData& fieldName, bool val) {
00189 _b.appendNum((char) Bool);
00190 _b.appendStr(fieldName);
00191 _b.appendNum((char) (val?1:0));
00192 return *this;
00193 }
00194
00196 BSONObjBuilder& append(const StringData& fieldName, int n) {
00197 _b.appendNum((char) NumberInt);
00198 _b.appendStr(fieldName);
00199 _b.appendNum(n);
00200 return *this;
00201 }
00202
00204 BSONObjBuilder& append(const StringData& fieldName, unsigned n) {
00205 return append(fieldName, (int) n);
00206 }
00207
00209 BSONObjBuilder& append(const StringData& fieldName, long long n) {
00210 _b.appendNum((char) NumberLong);
00211 _b.appendStr(fieldName);
00212 _b.appendNum(n);
00213 return *this;
00214 }
00215
00217 BSONObjBuilder& appendIntOrLL( const StringData& fieldName , long long n ) {
00218 long long x = n;
00219 if ( x < 0 )
00220 x = x * -1;
00221 if ( x < ( numeric_limits<int>::max() / 2 ) )
00222 append( fieldName , (int)n );
00223 else
00224 append( fieldName , n );
00225 return *this;
00226 }
00227
00232 BSONObjBuilder& appendNumber( const StringData& fieldName , int n ) {
00233 return append( fieldName , n );
00234 }
00235
00236 BSONObjBuilder& appendNumber( const StringData& fieldName , double d ) {
00237 return append( fieldName , d );
00238 }
00239
00240 BSONObjBuilder& appendNumber( const StringData& fieldName , size_t n ) {
00241 static size_t maxInt = (size_t)pow( 2.0 , 30.0 );
00242
00243 if ( n < maxInt )
00244 append( fieldName , (int)n );
00245 else
00246 append( fieldName , (long long)n );
00247 return *this;
00248 }
00249
00250
00251 BSONObjBuilder& appendNumber( const StringData& fieldName , long long l ) {
00252 static long long maxInt = (int)pow( 2.0 , 30.0 );
00253 static long long maxDouble = (long long)pow( 2.0 , 40.0 );
00254
00255 if ( l < maxInt )
00256 append( fieldName , (int)l );
00257 else if ( l < maxDouble )
00258 append( fieldName , (double)l );
00259 else
00260 append( fieldName , l );
00261 return *this;
00262 }
00263
00265 BSONObjBuilder& append(const StringData& fieldName, double n) {
00266 _b.appendNum((char) NumberDouble);
00267 _b.appendStr(fieldName);
00268 _b.appendNum(n);
00269 return *this;
00270 }
00271
00275 bool appendAsNumber( const StringData& fieldName , const string& data );
00276
00281 BSONObjBuilder& appendOID(const StringData& fieldName, OID *oid = 0 , bool generateIfBlank = false ) {
00282 _b.appendNum((char) jstOID);
00283 _b.appendStr(fieldName);
00284 if ( oid )
00285 _b.appendBuf( (void *) oid, 12 );
00286 else {
00287 OID tmp;
00288 if ( generateIfBlank )
00289 tmp.init();
00290 else
00291 tmp.clear();
00292 _b.appendBuf( (void *) &tmp, 12 );
00293 }
00294 return *this;
00295 }
00296
00302 BSONObjBuilder& append( const StringData& fieldName, OID oid ) {
00303 _b.appendNum((char) jstOID);
00304 _b.appendStr(fieldName);
00305 _b.appendBuf( (void *) &oid, 12 );
00306 return *this;
00307 }
00308
00313 BSONObjBuilder& genOID() {
00314 return append("_id", OID::gen());
00315 }
00316
00321 BSONObjBuilder& appendTimeT(const StringData& fieldName, time_t dt) {
00322 _b.appendNum((char) Date);
00323 _b.appendStr(fieldName);
00324 _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
00325 return *this;
00326 }
00331 BSONObjBuilder& appendDate(const StringData& fieldName, Date_t dt) {
00332
00333 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
00334 if( dt > 0 && dt <= 0xffffffff ) {
00335 static int n;
00336 if( n++ == 0 )
00337 log() << "DEV WARNING appendDate() called with a tiny (but nonzero) date" << endl;
00338 }
00339 #endif
00340 _b.appendNum((char) Date);
00341 _b.appendStr(fieldName);
00342 _b.appendNum(dt);
00343 return *this;
00344 }
00345 BSONObjBuilder& append(const StringData& fieldName, Date_t dt) {
00346 return appendDate(fieldName, dt);
00347 }
00348
00353 BSONObjBuilder& appendRegex(const StringData& fieldName, const StringData& regex, const StringData& options = "") {
00354 _b.appendNum((char) RegEx);
00355 _b.appendStr(fieldName);
00356 _b.appendStr(regex);
00357 _b.appendStr(options);
00358 return *this;
00359 }
00360
00361 BSONObjBuilder& appendCode(const StringData& fieldName, const StringData& code) {
00362 _b.appendNum((char) Code);
00363 _b.appendStr(fieldName);
00364 _b.appendNum((int) code.size()+1);
00365 _b.appendStr(code);
00366 return *this;
00367 }
00368
00370 BSONObjBuilder& append(const StringData& fieldName, const char *str, int len) {
00371 _b.appendNum((char) String);
00372 _b.appendStr(fieldName);
00373 _b.appendNum((int)len);
00374 _b.appendBuf(str, len);
00375 return *this;
00376 }
00378 BSONObjBuilder& append(const StringData& fieldName, const char *str) {
00379 return append(fieldName, str, (int) strlen(str)+1);
00380 }
00382 BSONObjBuilder& append(const StringData& fieldName, const string& str) {
00383 return append(fieldName, str.c_str(), (int) str.size()+1);
00384 }
00385
00386 BSONObjBuilder& appendSymbol(const StringData& fieldName, const StringData& symbol) {
00387 _b.appendNum((char) Symbol);
00388 _b.appendStr(fieldName);
00389 _b.appendNum((int) symbol.size()+1);
00390 _b.appendStr(symbol);
00391 return *this;
00392 }
00393
00395 BSONObjBuilder& appendNull( const StringData& fieldName ) {
00396 _b.appendNum( (char) jstNULL );
00397 _b.appendStr( fieldName );
00398 return *this;
00399 }
00400
00401
00402 BSONObjBuilder& appendMinKey( const StringData& fieldName ) {
00403 _b.appendNum( (char) MinKey );
00404 _b.appendStr( fieldName );
00405 return *this;
00406 }
00407
00408 BSONObjBuilder& appendMaxKey( const StringData& fieldName ) {
00409 _b.appendNum( (char) MaxKey );
00410 _b.appendStr( fieldName );
00411 return *this;
00412 }
00413
00414
00415 BSONObjBuilder& appendTimestamp( const StringData& fieldName ) {
00416 _b.appendNum( (char) Timestamp );
00417 _b.appendStr( fieldName );
00418 _b.appendNum( (unsigned long long) 0 );
00419 return *this;
00420 }
00421
00422 BSONObjBuilder& appendTimestamp( const StringData& fieldName , unsigned long long val ) {
00423 _b.appendNum( (char) Timestamp );
00424 _b.appendStr( fieldName );
00425 _b.appendNum( val );
00426 return *this;
00427 }
00428
00434 BSONObjBuilder& appendTimestamp( const StringData& fieldName , unsigned long long time , unsigned int inc );
00435
00436
00437
00438
00439
00440 BSONObjBuilder& appendDBRef( const StringData& fieldName, const StringData& ns, const OID &oid ) {
00441 _b.appendNum( (char) DBRef );
00442 _b.appendStr( fieldName );
00443 _b.appendNum( (int) ns.size() + 1 );
00444 _b.appendStr( ns );
00445 _b.appendBuf( (void *) &oid, 12 );
00446 return *this;
00447 }
00448
00456 BSONObjBuilder& appendBinData( const StringData& fieldName, int len, BinDataType type, const char *data ) {
00457 _b.appendNum( (char) BinData );
00458 _b.appendStr( fieldName );
00459 _b.appendNum( len );
00460 _b.appendNum( (char) type );
00461 _b.appendBuf( (void *) data, len );
00462 return *this;
00463 }
00464 BSONObjBuilder& appendBinData( const StringData& fieldName, int len, BinDataType type, const unsigned char *data ) {
00465 return appendBinData(fieldName, len, type, (const char *) data);
00466 }
00467
00474 BSONObjBuilder& appendBinDataArrayDeprecated( const char * fieldName , const char * data , int len ) {
00475 _b.appendNum( (char) BinData );
00476 _b.appendStr( fieldName );
00477 _b.appendNum( len + 4 );
00478 _b.appendNum( (char)0x2 );
00479 _b.appendNum( len );
00480 _b.appendBuf( (void *) data, len );
00481 return *this;
00482 }
00483
00487 BSONObjBuilder& appendCodeWScope( const StringData& fieldName, const StringData& code, const BSONObj &scope ) {
00488 _b.appendNum( (char) CodeWScope );
00489 _b.appendStr( fieldName );
00490 _b.appendNum( ( int )( 4 + 4 + code.size() + 1 + scope.objsize() ) );
00491 _b.appendNum( ( int ) code.size() + 1 );
00492 _b.appendStr( code );
00493 _b.appendBuf( ( void * )scope.objdata(), scope.objsize() );
00494 return *this;
00495 }
00496
00497 void appendUndefined( const StringData& fieldName ) {
00498 _b.appendNum( (char) Undefined );
00499 _b.appendStr( fieldName );
00500 }
00501
00502
00503 void appendWhere( const StringData& code, const BSONObj &scope ) {
00504 appendCodeWScope( "$where" , code , scope );
00505 }
00506
00510 void appendMinForType( const StringData& fieldName , int type );
00511 void appendMaxForType( const StringData& fieldName , int type );
00512
00514 template < class T >
00515 BSONObjBuilder& append( const StringData& fieldName, const vector< T >& vals );
00516
00517 template < class T >
00518 BSONObjBuilder& append( const StringData& fieldName, const list< T >& vals );
00519
00525 BSONObj obj() {
00526 bool own = owned();
00527 massert( 10335 , "builder does not own memory", own );
00528 int l;
00529 return BSONObj(decouple(l), true);
00530 }
00531
00537 BSONObj done() {
00538 return BSONObj(_done(), false);
00539 }
00540
00541
00542 void doneFast() {
00543 (void)_done();
00544 }
00545
00550 BSONObj asTempObj() {
00551 BSONObj temp(_done());
00552 _b.setlen(_b.len()-1);
00553 _doneCalled = false;
00554 return temp;
00555 }
00556
00557
00558 char* decouple(int& l) {
00559 char *x = _done();
00560 assert( x );
00561 l = _b.len();
00562 _b.decouple();
00563 return x;
00564 }
00565 void decouple() {
00566 _b.decouple();
00567 }
00568
00569 void appendKeys( const BSONObj& keyPattern , const BSONObj& values );
00570
00571 static string numStr( int i ) {
00572 if (i>=0 && i<100)
00573 return numStrs[i];
00574 StringBuilder o;
00575 o << i;
00576 return o.str();
00577 }
00578
00580 BSONObjBuilderValueStream &operator<<(const char * name ) {
00581 _s.endField( name );
00582 return _s;
00583 }
00584
00586 BSONObjBuilder& operator<<( GENOIDLabeler ) { return genOID(); }
00587
00588
00589 struct ForceExplicitString {
00590 ForceExplicitString( const string &str ) : str_( str ) {}
00591 string str_;
00592 };
00593
00595 BSONObjBuilderValueStream &operator<<( const ForceExplicitString& name ) {
00596 return operator<<( name.str_.c_str() );
00597 }
00598
00599 Labeler operator<<( const Labeler::Label &l ) {
00600 massert( 10336 , "No subobject started", _s.subobjStarted() );
00601 return _s << l;
00602 }
00603
00604 template<typename T>
00605 BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
00606 _s.endField( f.name().c_str() );
00607 return _s;
00608 }
00609
00610 template<typename T>
00611 BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
00612 append( v.name().c_str() , v.value() );
00613 return *this;
00614 }
00615
00616
00618 bool owned() const { return &_b == &_buf; }
00619
00620 BSONObjIterator iterator() const ;
00621
00622 bool hasField( const StringData& name ) const ;
00623
00624 int len() const { return _b.len(); }
00625
00626 private:
00627 char* _done() {
00628 if ( _doneCalled )
00629 return _b.buf() + _offset;
00630
00631 _doneCalled = true;
00632 _s.endField();
00633 _b.appendNum((char) EOO);
00634 char *data = _b.buf() + _offset;
00635 int size = _b.len() - _offset;
00636 *((int*)data) = size;
00637 if ( _tracker )
00638 _tracker->got( size );
00639 return data;
00640 }
00641
00642 BufBuilder &_b;
00643 BufBuilder _buf;
00644 int _offset;
00645 BSONObjBuilderValueStream _s;
00646 BSONSizeTracker * _tracker;
00647 bool _doneCalled;
00648
00649 static const string numStrs[100];
00650 };
00651
00652 class BSONArrayBuilder : boost::noncopyable {
00653 public:
00654 BSONArrayBuilder() : _i(0), _b() {}
00655 BSONArrayBuilder( BufBuilder &_b ) : _i(0), _b(_b) {}
00656 BSONArrayBuilder( int initialSize ) : _i(0), _b(initialSize) {}
00657
00658 template <typename T>
00659 BSONArrayBuilder& append(const T& x) {
00660 _b.append(num(), x);
00661 return *this;
00662 }
00663
00664 BSONArrayBuilder& append(const BSONElement& e) {
00665 _b.appendAs(e, num());
00666 return *this;
00667 }
00668
00669 template <typename T>
00670 BSONArrayBuilder& operator<<(const T& x) {
00671 return append(x);
00672 }
00673
00674 void appendNull() {
00675 _b.appendNull(num());
00676 }
00677
00682 BSONArray arr() { return BSONArray(_b.obj()); }
00683
00684 BSONObj done() { return _b.done(); }
00685
00686 void doneFast() { _b.doneFast(); }
00687
00688 template <typename T>
00689 BSONArrayBuilder& append(const StringData& name, const T& x) {
00690 fill( name );
00691 append( x );
00692 return *this;
00693 }
00694
00695 BufBuilder &subobjStart( const StringData& name = "0" ) {
00696 fill( name );
00697 return _b.subobjStart( num() );
00698 }
00699
00700 BufBuilder &subarrayStart( const char *name ) {
00701 fill( name );
00702 return _b.subarrayStart( num() );
00703 }
00704
00705 void appendArray( const StringData& name, BSONObj subObj ) {
00706 fill( name );
00707 _b.appendArray( num(), subObj );
00708 }
00709
00710 void appendAs( const BSONElement &e, const char *name) {
00711 fill( name );
00712 append( e );
00713 }
00714
00715 int len() const { return _b.len(); }
00716
00717 private:
00718 void fill( const StringData& name ) {
00719 char *r;
00720 long int n = strtol( name.data(), &r, 10 );
00721 if ( *r )
00722 uasserted( 13048, (string)"can't append to array using string field name [" + name.data() + "]" );
00723 while( _i < n )
00724 append( nullElt() );
00725 }
00726
00727 static BSONElement nullElt() {
00728 static BSONObj n = nullObj();
00729 return n.firstElement();
00730 }
00731
00732 static BSONObj nullObj() {
00733 BSONObjBuilder _b;
00734 _b.appendNull( "" );
00735 return _b.obj();
00736 }
00737
00738 string num() { return _b.numStr(_i++); }
00739 int _i;
00740 BSONObjBuilder _b;
00741 };
00742
00743 template < class T >
00744 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const vector< T >& vals ) {
00745 BSONObjBuilder arrBuilder;
00746 for ( unsigned int i = 0; i < vals.size(); ++i )
00747 arrBuilder.append( numStr( i ), vals[ i ] );
00748 appendArray( fieldName, arrBuilder.done() );
00749 return *this;
00750 }
00751
00752 template < class T >
00753 inline BSONObjBuilder& BSONObjBuilder::append( const StringData& fieldName, const list< T >& vals ) {
00754 BSONObjBuilder arrBuilder;
00755 int n = 0;
00756 for( typename list< T >::const_iterator i = vals.begin(); i != vals.end(); i++ )
00757 arrBuilder.append( numStr(n++), *i );
00758 appendArray( fieldName, arrBuilder.done() );
00759 return *this;
00760 }
00761
00762
00763 inline BSONObj OR(const BSONObj& a, const BSONObj& b)
00764 { return BSON( "$or" << BSON_ARRAY(a << b) ); }
00765 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c)
00766 { return BSON( "$or" << BSON_ARRAY(a << b << c) ); }
00767 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d)
00768 { return BSON( "$or" << BSON_ARRAY(a << b << c << d) ); }
00769 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e)
00770 { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e) ); }
00771 inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f)
00772 { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e << f) ); }
00773
00774 }