22 #if defined (SDB_ENGINE)
23 #include "utilPooledObject.hpp"
24 #elif defined( SDB_CLIENT )
34 #include "bsonnoncopyable.h"
35 #include "bsonDecimal.h"
44 #pragma warning( disable : 4355 )
55 const T& value()
const {
return _t; }
56 const string& name()
const {
return _name; }
66 BSONField(
const string& name ,
const string& longName=
"" )
67 : _name(name), _longName(longName) {}
68 const string& name()
const {
return _name; }
69 operator string()
const {
return _name; }
76 {
return query(
"$gt" , t ); }
78 {
return query(
"$lt" , t ); }
94 #if defined (SDB_ENGINE)
95 class BSONObjBuilder : bsonnoncopyable,
public engine::utilPooledObject{
96 #elif defined( SDB_CLIENT )
105 _buf(initsize + sizeof(unsigned), BSONObjMaxInternalSize, BSON_INFO_STR ),
106 _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneCalled(false) {
107 _orgReserve = _b.getReserveBytes() ;
112 _b.reserveBytes(1,
true);
120 _buf( 0, BSONObjMaxInternalSize, BSON_INFO_STR ),
121 _offset( baseBuilder.len() ), _s( this ) , _tracker(0) , _doneCalled(false) {
122 _orgReserve = _b.getReserveBytes() ;
125 _b.reserveBytes(1,
true);
129 _buf(tracker.getSize() + sizeof(unsigned), BSONObjMaxInternalSize, BSON_INFO_STR ),
130 _offset( sizeof(unsigned) ),
131 _s( this ) , _tracker( (
BSONSizeTracker*)(&tracker) ) , _doneCalled(false) {
132 _orgReserve = _b.getReserveBytes() ;
136 _b.reserveBytes(1,
true);
140 if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
144 _b.setlen( _offset ) ;
145 _b.setReserveBytes( _orgReserve ) ;
151 _b.setlen( _offset ) ;
152 _b.setReserveBytes( _orgReserve ) ;
156 _doneCalled = false ;
158 _b.reserveBytes(1,
true) ;
161 bool isEmpty()
const {
163 return _b.len() <= (int)(
sizeof(
unsigned) + 4) ?
true :
false ;
165 return _b.len() <= 4 ?
true : false ;
169 BSONObjBuilder& appendElements(BSONObj x);
173 BSONObjBuilder& appendElementsWithoutName(BSONObj x);
177 BSONObjBuilder& appendElementsUnique( BSONObj x );
183 _b.appendBuf((
void*) e.rawdata(), e.
size());
189 const StringData& fieldName) {
192 _b.appendNum((
char) e.
type());
193 _b.appendStr(fieldName);
200 _b.appendNum((
char) Object);
201 _b.appendStr(fieldName);
208 const char * objdata ,
int size = 0 ) {
211 size = *((
int*)objdata);
214 assert( size > 4 && size < 100000000 );
216 _b.appendNum((
char) Object);
217 _b.appendStr(fieldName);
218 _b.appendBuf((
void*)objdata, size );
234 _b.appendNum((
char) Object);
235 _b.appendStr(fieldName);
244 _b.appendNum((
char) Array);
245 _b.appendStr(fieldName);
250 return appendArray(fieldName, arr);
256 _b.appendNum((
char) Array);
257 _b.appendStr(fieldName);
263 _b.appendNum((
char) Bool);
264 _b.appendStr(fieldName);
265 _b.appendNum((
char) (val?1:0));
271 _b.appendNum((
char) Bool);
272 _b.appendStr(fieldName);
273 _b.appendNum((
char) (val?1:0));
279 _b.appendNum((
char) NumberInt);
280 _b.appendStr(fieldName);
287 return append(fieldName, (
int) n);
292 _b.appendNum((
char) NumberLong);
293 _b.appendStr(fieldName);
304 if ( x > -( (numeric_limits<int>::max)() / 2 ) )
305 append( fieldName , (
int)n );
307 append( fieldName , n );
316 return append( fieldName , n );
319 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
double d ) {
320 return append( fieldName , d );
323 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
size_t n ) {
324 static size_t maxInt = (size_t)pow( 2.0 , 30.0 );
327 append( fieldName , (
int)n );
329 append( fieldName , (
long long)n );
333 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
335 static long long maxInt = (int)pow( 2.0 , 30.0 );
336 static long long maxDouble = (
long long)pow( 2.0 , 40.0 );
337 long long x = l > 0 ? -l : l;
339 append( fieldName , (
int)l );
340 else if ( x > -maxDouble )
341 append( fieldName , (
double)l );
343 append( fieldName , l );
349 _b.appendNum((
char) NumberDouble);
350 _b.appendStr(fieldName);
356 const bsonDecimal& decimal )
364 const short *digits = NULL ;
366 weight = decimal.getWeight() ;
367 typemod = decimal.getTypemod() ;
368 scale = decimal.getStorageScale() ;
369 ndigit = decimal.getNdigit() ;
370 digits = decimal.getDigits() ;
371 size = decimal.getSize() ;
374 _b.appendNum( (
char) NumberDecimal ) ;
375 _b.appendStr( fieldName ) ;
376 _b.appendNum( size ) ;
377 _b.appendNum( typemod ) ;
378 _b.appendNum( scale ) ;
379 _b.appendNum( weight ) ;
381 for ( i = 0 ; i < ndigit ; i++ )
383 _b.appendNum( digits[i] ) ;
389 bool appendDecimal(
const StringData& fieldName,
390 const StringData& strDecimal,
391 int precision,
int scale ) ;
393 bool appendDecimal(
const StringData& fieldName,
394 const StringData& strDecimal ) ;
399 bool appendAsNumber(
const StringData& fieldName ,
const StringData& data );
406 bool generateIfBlank =
false ) {
407 _b.appendNum((
char) jstOID);
408 _b.appendStr(fieldName);
410 _b.appendBuf( (
void *) oid, 12 );
413 if ( generateIfBlank )
417 _b.appendBuf( (
void *) &tmp, 12 );
428 _b.appendNum((
char) jstOID);
429 _b.appendStr(fieldName);
430 _b.appendBuf( (
void *) &oid, 12 );
439 return append(
"_id", OID::gen());
447 _b.appendNum((
char) Date);
448 _b.appendStr(fieldName);
449 _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
459 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
460 if( dt > 0 && dt <= 0xffffffff ) {
463 log() <<
"DEV WARNING appendDate() called with a tiny "
464 "(but nonzero) date" << endl;
467 _b.appendNum((
char) Date);
468 _b.appendStr(fieldName);
473 return appendDate(fieldName, dt);
481 const StringData& regex,
const StringData& options =
"") {
482 _b.appendNum((
char) RegEx);
483 _b.appendStr(fieldName);
485 _b.appendStr(options);
490 const StringData& code) {
491 _b.appendNum((
char) Code);
492 _b.appendStr(fieldName);
493 _b.appendNum((
int) code.size()+1);
502 _b.appendNum((
char) String);
503 _b.appendStr(fieldName);
504 _b.appendNum((
int)sz);
505 _b.appendBuf(str, sz);
511 BSONObjBuilder& appendStrWithNoTerminating(
const StringData& fieldName,
const char *str,
514 _b.appendNum((
char) String);
515 _b.appendStr(fieldName);
516 _b.appendNum((
int)sz + 1);
517 _b.appendBuf(str, sz);
525 return append(fieldName, str, (
int) strlen(str)+1);
529 return append(fieldName, str.c_str(), (int) str.size()+1);
533 return append(fieldName, str.data(), (int) str.size()+1);
537 const StringData& symbol) {
538 _b.appendNum((
char) Symbol);
539 _b.appendStr(fieldName);
540 _b.appendNum((
int) symbol.size()+1);
541 _b.appendStr(symbol);
547 _b.appendNum( (
char) jstNULL );
548 _b.appendStr( fieldName );
554 _b.appendNum( (
char) MinKey );
555 _b.appendStr( fieldName );
561 _b.appendNum( (
char) Undefined );
562 _b.appendStr( fieldName );
568 _b.appendNum( (
char) MaxKey );
569 _b.appendStr( fieldName );
575 BSONObjBuilder& appendTimestamp(
const StringData& fieldName ) {
576 _b.appendNum( (
char) Timestamp );
577 _b.appendStr( fieldName );
578 _b.appendNum( (
long long) 0 );
593 _b.appendNum( (
char) Timestamp );
594 _b.appendStr( fieldName );
610 long long time ,
unsigned int inc );
617 const StringData& ns,
const OID &oid ) {
618 _b.appendNum( (
char) DBRef );
619 _b.appendStr( fieldName );
620 _b.appendNum( (
int) ns.size() + 1 );
622 _b.appendBuf( (
void *) &oid, 12 );
635 BinDataType type,
const char *data ) {
636 if ( type == ByteArrayDeprecated ) {
637 return appendBinDataArrayDeprecated( fieldName.data(), data, len );
640 _b.appendNum( (
char) BinData );
641 _b.appendStr( fieldName );
643 _b.appendNum( (
char) type );
644 _b.appendBuf( (
void *) data, len );
648 BSONObjBuilder& appendBinData(
const StringData& fieldName,
int len,
649 BinDataType type,
const unsigned char *data ) {
650 return appendBinData(fieldName, len, type, (
const char *) data);
660 const char * data ,
int len ) {
661 _b.appendNum( (
char) BinData );
662 _b.appendStr( fieldName );
663 _b.appendNum( len + 4 );
664 _b.appendNum( (
char)0x2 );
666 _b.appendBuf( (
void *) data, len );
674 const StringData& code,
const BSONObj &scope ) {
675 _b.appendNum( (
char) CodeWScope );
676 _b.appendStr( fieldName );
677 _b.appendNum( (
int )( 4 + 4 + code.size() + 1 + scope.
objsize() ));
678 _b.appendNum( (
int ) code.size() + 1 );
679 _b.appendStr( code );
690 void appendWhere(
const StringData& code,
const BSONObj &scope ) {
691 appendCodeWScope(
"$where" , code , scope );
698 void appendMinForType(
const StringData& fieldName ,
int type );
699 void appendMaxForType(
const StringData& fieldName ,
int type );
703 BSONObjBuilder& append(
const StringData& fieldName,
704 const vector< T >& vals );
707 BSONObjBuilder& append(
const StringData& fieldName,
708 const list< T >& vals );
712 BSONObjBuilder& append(
const StringData& fieldName,
const set< T >& vals );
721 massert( 10335 ,
"builder does not own memory", own );
723 bson_intrusive_ptr<BSONObj::Holder,BufBuilder::myAllocator> h ;
751 _b.setlen(_b.len()-1);
759 char* decouple(
int& l) {
770 void appendKeys(
const BSONObj& keyPattern ,
const BSONObj& values );
772 static string numStr(
int i ) {
801 massert( 10336 ,
"No subobject started", _s.subobjStarted() );
806 BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
807 _s.endField( f.name().c_str() );
812 BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
813 append( v.name().c_str() , v.value() );
820 bool owned()
const {
return &_b == &_buf; }
824 bool hasField(
const StringData& name )
const ;
826 int len()
const {
return _b.len(); }
828 BufBuilder& bb() {
return _b; }
833 return _b.buf() + _offset;
838 _b.claimReservedBytes(1);
839 _b.appendNum((
char) EOO);
841 *(
unsigned*)_b.buf() = 0 ;
843 char *data = _b.buf() + _offset;
844 int size = _b.len() - _offset;
845 *((
int*)data) = size;
847 _tracker->got( size );
855 BSONObjBuilderValueStream _s;
856 BSONSizeTracker * _tracker;
859 static const string numStrs[100];
862 #if defined (SDB_ENGINE)
863 class BSONArrayBuilder : bsonnoncopyable,
public engine::utilPooledObject {
864 #elif defined( SDB_CLIENT )
865 class BSONArrayBuilder : bsonnoncopyable,
public SDBObject {
874 template <
typename T>
881 _b.appendTimestamp(num(),val);
886 _b.appendAs(e, num());
890 template <
typename T>
896 _b.appendNull(num());
905 BSONObj done() {
return _b.done(); }
907 void doneFast() { _b.doneFast(); }
909 template <
typename T>
910 BSONArrayBuilder& append(
const StringData& name,
const T& x) {
917 BufBuilder &subobjStart() {
return _b.subobjStart( num() ); }
918 BufBuilder &subarrayStart() {
return _b.subarrayStart( num() ); }
921 BufBuilder &subobjStart(
int pos) {
923 return _b.subobjStart( num() );
925 BufBuilder &subarrayStart(
int pos) {
927 return _b.subarrayStart( num() );
932 BufBuilder &subobjStart(
const StringData& name ) {
934 return _b.subobjStart( num() );
937 BufBuilder &subarrayStart(
const char *name ) {
939 return _b.subarrayStart( num() );
942 void appendArray(
const StringData& name, BSONObj subObj ) {
944 _b.appendArray( num(), subObj );
947 void appendAs(
const BSONElement &e,
const char *name) {
952 int len()
const {
return _b.len(); }
955 void fill(
const StringData& name ) {
957 long int n = strtol( name.data(), &r, 10 );
959 uasserted( 13048, (
string)
"can't append to array using string"
960 " field name [" + name.data() +
"]" );
964 void fill (
int upTo){
969 static BSONElement nullElt() {
970 static BSONObj n = nullObj();
971 return n.firstElement();
974 static BSONObj nullObj() {
980 string num() {
return _b.numStr(_i++); }
987 const vector< T >& vals ) {
989 for (
unsigned int i = 0; i < vals.size(); ++i )
990 arrBuilder.
append( numStr( i ), vals[ i ] );
991 appendArray( fieldName, arrBuilder.
done() );
999 for(
typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
1000 arrBuilder.
append( BSONObjBuilder::numStr(n++), *i );
1005 template <
class T >
1006 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const list< T >& vals ) {
1007 return _appendIt< list< T > >( *
this, fieldName, vals );
1010 template <
class T >
1011 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const set< T >& vals ) {
1012 return _appendIt< set< T > >( *
this, fieldName, vals );
1019 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c)
1021 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1024 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1025 const BSONObj& d,
const BSONObj& e)
1027 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1028 const BSONObj& d,
const BSONObj& e,
const BSONObj& f)
1029 {
return BSON(
"$or" <<
BSON_ARRAY(a << b << c << d << e << f) ); }