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 ); }
98 : isClientReadable(
false ),
105 : isClientReadable( isClientReadable ),
106 isAbbrevMode( isAbbrevMode )
114 isClientReadable = false ;
115 isAbbrevMode = false ;
118 bool isEnabled()
const
120 return isClientReadable || isAbbrevMode ;
124 bool isClientReadable ;
131 #if defined (SDB_ENGINE)
132 class BSONObjBuilder : bsonnoncopyable,
public engine::utilPooledObject{
133 #elif defined( SDB_CLIENT )
142 _buf(initsize + sizeof(unsigned), BSONObjMaxInternalSize, BSON_INFO_STR ),
143 _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneCalled(false) {
144 _orgReserve = _b.getReserveBytes() ;
149 _b.reserveBytes(1,
true);
157 _buf( 0, BSONObjMaxInternalSize, BSON_INFO_STR ),
158 _offset( baseBuilder.len() ), _s( this ) , _tracker(0) , _doneCalled(false) {
159 _orgReserve = _b.getReserveBytes() ;
162 _b.reserveBytes(1,
true);
166 _buf(tracker.getSize() + sizeof(unsigned), BSONObjMaxInternalSize, BSON_INFO_STR ),
167 _offset( sizeof(unsigned) ),
168 _s( this ) , _tracker( (
BSONSizeTracker*)(&tracker) ) , _doneCalled(false) {
169 _orgReserve = _b.getReserveBytes() ;
173 _b.reserveBytes(1,
true);
180 if ( !_doneCalled && !owned() ) {
184 _b.setlen( _offset ) ;
185 _b.setReserveBytes( _orgReserve ) ;
191 _b.setlen( _offset ) ;
192 _b.setReserveBytes( _orgReserve ) ;
196 _doneCalled = false ;
198 _b.reserveBytes(1,
true) ;
212 bool isEmpty()
const {
214 return ( _b.len() - _offset ) <= (
int)(
sizeof(unsigned) + 4) ?
true : false ;
216 return ( _b.len() - _offset ) <= 4 ?
true :
false ;
220 BSONObjBuilder& appendElements(BSONObj x);
224 BSONObjBuilder& appendElementsWithoutName(BSONObj x);
228 BSONObjBuilder& appendElementsUnique( BSONObj x );
234 _b.appendBuf((
void*) e.rawdata(), e.
size());
240 const StringData& fieldName) {
243 _b.appendNum((
char) e.
type());
244 _b.appendStr(fieldName);
251 _b.appendNum((
char) Object);
252 _b.appendStr(fieldName);
261 return appendEx( element.
fieldName(), element, option ) ;
278 if ( option.isEnabled() )
281 subBuilder.
appendEx( subObject, option ) ;
282 subBuilder.doneFast() ;
286 append( fieldName, subObject ) ;
293 const char * objdata ,
int size = 0 ) {
296 size = *((
int*)objdata);
299 assert( size > 4 && size < 100000000 );
301 _b.appendNum((
char) Object);
302 _b.appendStr(fieldName);
303 _b.appendBuf((
void*)objdata, size );
319 _b.appendNum((
char) Object);
320 _b.appendStr(fieldName);
329 _b.appendNum((
char) Array);
330 _b.appendStr(fieldName);
335 return appendArray(fieldName, arr);
341 _b.appendNum((
char) Array);
342 _b.appendStr(fieldName);
348 _b.appendNum((
char) Bool);
349 _b.appendStr(fieldName);
350 _b.appendNum((
char) (val?1:0));
356 _b.appendNum((
char) Bool);
357 _b.appendStr(fieldName);
358 _b.appendNum((
char) (val?1:0));
364 _b.appendNum((
char) NumberInt);
365 _b.appendStr(fieldName);
372 return append(fieldName, (
int) n);
377 _b.appendNum((
char) NumberLong);
378 _b.appendStr(fieldName);
389 if ( x > -( (numeric_limits<int>::max)() / 2 ) )
390 append( fieldName , (
int)n );
392 append( fieldName , n );
401 return append( fieldName , n );
404 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
double d ) {
405 return append( fieldName , d );
408 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
size_t n ) {
409 static size_t maxInt = (size_t)pow( 2.0 , 30.0 );
412 append( fieldName , (
int)n );
414 append( fieldName , (
long long)n );
418 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
420 static long long maxInt = (int)pow( 2.0 , 30.0 );
421 static long long maxDouble = (
long long)pow( 2.0 , 40.0 );
422 long long x = l > 0 ? -l : l;
423 if ( OSS_SINT64_MIN == x )
424 append( fieldName , l );
425 else if ( x > -maxInt )
426 append( fieldName , (
int)l );
427 else if ( x > -maxDouble )
428 append( fieldName , (
double)l );
430 append( fieldName , l );
436 _b.appendNum((
char) NumberDouble);
437 _b.appendStr(fieldName);
443 const bsonDecimal& decimal )
451 const short *digits = NULL ;
453 weight = decimal.getWeight() ;
454 typemod = decimal.getTypemod() ;
455 scale = decimal.getStorageScale() ;
456 ndigit = decimal.getNdigit() ;
457 digits = decimal.getDigits() ;
458 size = decimal.getSize() ;
461 _b.appendNum( (
char) NumberDecimal ) ;
462 _b.appendStr( fieldName ) ;
463 _b.appendNum( size ) ;
464 _b.appendNum( typemod ) ;
465 _b.appendNum( scale ) ;
466 _b.appendNum( weight ) ;
468 for ( i = 0 ; i < ndigit ; i++ )
470 _b.appendNum( digits[i] ) ;
476 bool appendDecimal(
const StringData& fieldName,
477 const StringData& strDecimal,
478 int precision,
int scale ) ;
480 bool appendDecimal(
const StringData& fieldName,
481 const StringData& strDecimal ) ;
486 bool appendAsNumber(
const StringData& fieldName ,
const StringData& data );
493 bool generateIfBlank =
false ) {
494 _b.appendNum((
char) jstOID);
495 _b.appendStr(fieldName);
497 _b.appendBuf( (
void *) oid, 12 );
500 if ( generateIfBlank )
504 _b.appendBuf( (
void *) &tmp, 12 );
515 _b.appendNum((
char) jstOID);
516 _b.appendStr(fieldName);
517 _b.appendBuf( (
void *) &oid, 12 );
526 return append(
"_id", OID::gen());
534 _b.appendNum((
char) Date);
535 _b.appendStr(fieldName);
536 _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
546 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
547 if( dt > 0 && dt <= 0xffffffff ) {
550 log() <<
"DEV WARNING appendDate() called with a tiny "
551 "(but nonzero) date" << endl;
554 _b.appendNum((
char) Date);
555 _b.appendStr(fieldName);
560 return appendDate(fieldName, dt);
568 const StringData& regex,
const StringData& options =
"") {
569 _b.appendNum((
char) RegEx);
570 _b.appendStr(fieldName);
572 _b.appendStr(options);
577 const StringData& code) {
578 _b.appendNum((
char) Code);
579 _b.appendStr(fieldName);
580 _b.appendNum((
int) code.size()+1);
589 _b.appendNum((
char) String);
590 _b.appendStr(fieldName);
591 _b.appendNum((
int)sz);
592 _b.appendBuf(str, sz);
598 BSONObjBuilder& appendStrWithNoTerminating(
const StringData& fieldName,
const char *str,
601 _b.appendNum((
char) String);
602 _b.appendStr(fieldName);
603 _b.appendNum((
int)sz + 1);
604 _b.appendBuf(str, sz);
612 return append(fieldName, str, (
int) strlen(str)+1);
616 return append(fieldName, str.c_str(), (int) str.size()+1);
620 return append(fieldName, str.data(), (int) str.size()+1);
624 const StringData& symbol) {
625 _b.appendNum((
char) Symbol);
626 _b.appendStr(fieldName);
627 _b.appendNum((
int) symbol.size()+1);
628 _b.appendStr(symbol);
634 _b.appendNum( (
char) jstNULL );
635 _b.appendStr( fieldName );
641 _b.appendNum( (
char) MinKey );
642 _b.appendStr( fieldName );
648 _b.appendNum( (
char) Undefined );
649 _b.appendStr( fieldName );
655 _b.appendNum( (
char) MaxKey );
656 _b.appendStr( fieldName );
662 BSONObjBuilder& appendTimestamp(
const StringData& fieldName ) {
663 _b.appendNum( (
char) Timestamp );
664 _b.appendStr( fieldName );
665 _b.appendNum( (
long long) 0 );
680 _b.appendNum( (
char) Timestamp );
681 _b.appendStr( fieldName );
697 long long time ,
unsigned int inc );
704 const StringData& ns,
const OID &oid ) {
705 _b.appendNum( (
char) DBRef );
706 _b.appendStr( fieldName );
707 _b.appendNum( (
int) ns.size() + 1 );
709 _b.appendBuf( (
void *) &oid, 12 );
722 BinDataType type,
const char *data ) {
723 if ( type == ByteArrayDeprecated ) {
724 return appendBinDataArrayDeprecated( fieldName.data(), data, len );
727 _b.appendNum( (
char) BinData );
728 _b.appendStr( fieldName );
730 _b.appendNum( (
char) type );
731 _b.appendBuf( (
void *) data, len );
735 BSONObjBuilder& appendBinData(
const StringData& fieldName,
int len,
736 BinDataType type,
const unsigned char *data ) {
737 return appendBinData(fieldName, len, type, (
const char *) data);
747 const char * data ,
int len ) {
748 _b.appendNum( (
char) BinData );
749 _b.appendStr( fieldName );
750 _b.appendNum( len + 4 );
751 _b.appendNum( (
char)0x2 );
753 _b.appendBuf( (
void *) data, len );
761 const StringData& code,
const BSONObj &scope ) {
762 _b.appendNum( (
char) CodeWScope );
763 _b.appendStr( fieldName );
764 _b.appendNum( (
int )( 4 + 4 + code.size() + 1 + scope.
objsize() ));
765 _b.appendNum( (
int ) code.size() + 1 );
766 _b.appendStr( code );
777 void appendWhere(
const StringData& code,
const BSONObj &scope ) {
778 appendCodeWScope(
"$where" , code , scope );
785 void appendMinForType(
const StringData& fieldName ,
int type );
786 void appendMaxForType(
const StringData& fieldName ,
int type );
790 BSONObjBuilder& append(
const StringData& fieldName,
791 const vector< T >& vals );
794 BSONObjBuilder& append(
const StringData& fieldName,
795 const list< T >& vals );
799 BSONObjBuilder& append(
const StringData& fieldName,
const set< T >& vals );
808 massert( 10335 ,
"builder does not own memory", own );
810 bson_intrusive_ptr<BSONObj::Holder,BufBuilder::myAllocator> h ;
838 _b.setlen(_b.len()-1);
846 char* decouple(
int& l) {
857 void appendKeys(
const BSONObj& keyPattern ,
const BSONObj& values );
859 static string numStr(
int i ) {
888 massert( 10336 ,
"No subobject started", _s.subobjStarted() );
893 BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
894 _s.endField( f.name().c_str() );
899 BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
900 append( v.name().c_str() , v.value() );
907 bool owned()
const {
return &_b == &_buf; }
911 bool hasField(
const StringData& name )
const ;
913 int len()
const {
return _b.len(); }
915 BufBuilder& bb() {
return _b; }
920 return _b.buf() + _offset;
925 _b.claimReservedBytes(1);
926 _b.appendNum((
char) EOO);
928 *(
unsigned*)_b.buf() = 0 ;
930 char *data = _b.buf() + _offset;
931 int size = _b.len() - _offset;
932 *((
int*)data) = size;
934 _tracker->got( size );
938 StringData _genAbbrevStr( StackBufBuilder &builder,
939 const StringData &value ) ;
945 BSONObjBuilderValueStream _s;
946 BSONSizeTracker * _tracker;
949 static const string numStrs[100];
952 #if defined (SDB_ENGINE)
953 class BSONArrayBuilder : bsonnoncopyable,
public engine::utilPooledObject {
954 #elif defined( SDB_CLIENT )
955 class BSONArrayBuilder : bsonnoncopyable,
public SDBObject {
964 template <
typename T>
971 _b.appendTimestamp(num(),val);
976 _b.appendAs(e, num());
983 _b.appendEx( num(), e, option ) ;
987 template <
typename T>
993 _b.appendNull(num());
1002 BSONObj done() {
return _b.done(); }
1004 void doneFast() { _b.doneFast(); }
1006 void abandon() { _b.abandon() ; }
1008 bool isEmpty()
const {
return _b.
isEmpty() ; }
1010 template <
typename T>
1011 BSONArrayBuilder& append(
const StringData& name,
const T& x) {
1018 BufBuilder &subobjStart() {
return _b.subobjStart( num() ); }
1019 BufBuilder &subarrayStart() {
return _b.subarrayStart( num() ); }
1022 BufBuilder &subobjStart(
int pos) {
1024 return _b.subobjStart( num() );
1026 BufBuilder &subarrayStart(
int pos) {
1028 return _b.subarrayStart( num() );
1033 BufBuilder &subobjStart(
const StringData& name ) {
1035 return _b.subobjStart( num() );
1038 BufBuilder &subarrayStart(
const char *name ) {
1040 return _b.subarrayStart( num() );
1043 void appendArray(
const StringData& name, BSONObj subObj ) {
1045 _b.appendArray( num(), subObj );
1048 void appendAs(
const BSONElement &e,
const char *name) {
1053 int len()
const {
return _b.len(); }
1056 void fill(
const StringData& name ) {
1058 long int n = strtol( name.data(), &r, 10 );
1060 uasserted( 13048, (
string)
"can't append to array using string"
1061 " field name [" + name.data() +
"]" );
1065 void fill (
int upTo){
1067 append( nullElt() );
1070 static BSONElement nullElt() {
1071 static BSONObj n = nullObj();
1072 return n.firstElement();
1075 static BSONObj nullObj() {
1077 _b.appendNull(
"" );
1081 string num() {
return _b.numStr(_i++); }
1086 template <
class T >
1088 const vector< T >& vals ) {
1090 for (
unsigned int i = 0; i < vals.size(); ++i )
1091 arrBuilder.
append( numStr( i ), vals[ i ] );
1092 appendArray( fieldName, arrBuilder.
done() );
1096 template <
class L >
1100 for(
typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
1101 arrBuilder.
append( BSONObjBuilder::numStr(n++), *i );
1106 template <
class T >
1107 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const list< T >& vals ) {
1108 return _appendIt< list< T > >( *
this, fieldName, vals );
1111 template <
class T >
1112 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const set< T >& vals ) {
1113 return _appendIt< set< T > >( *
this, fieldName, vals );
1120 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c)
1122 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1125 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1126 const BSONObj& d,
const BSONObj& e)
1128 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
1129 const BSONObj& d,
const BSONObj& e,
const BSONObj& f)
1130 {
return BSON(
"$or" <<
BSON_ARRAY(a << b << c << d << e << f) ); }