22 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
31 #include "bsonnoncopyable.h"
32 #include "bsonDecimal.h"
41 #pragma warning( disable : 4355 )
52 const T& value()
const {
return _t; }
53 const string& name()
const {
return _name; }
63 BSONField(
const string& name ,
const string& longName=
"" )
64 : _name(name), _longName(longName) {}
65 const string& name()
const {
return _name; }
66 operator string()
const {
return _name; }
73 {
return query(
"$gt" , t ); }
75 {
return query(
"$lt" , t ); }
91 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
99 BSONObjBuilder(
int initsize=512) : _b(_buf), _buf(initsize + sizeof(unsigned)),
100 _offset( sizeof(unsigned) ), _s( this ) , _tracker(0) , _doneCalled(false) {
101 _b.appendNum((
unsigned)0);
113 _offset( baseBuilder.len() ), _s( this ) , _tracker(0) , _doneCalled(false) {
120 _buf(tracker.getSize() + sizeof(unsigned) ), _offset( sizeof(unsigned) ),
121 _s( this ) , _tracker( (
BSONSizeTracker*)(&tracker) ) , _doneCalled(false) {
122 _b.appendNum((
unsigned)0);
129 if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
135 BSONObjBuilder& appendElements(BSONObj x);
139 BSONObjBuilder& appendElementsWithoutName(BSONObj x);
143 BSONObjBuilder& appendElementsUnique( BSONObj x );
149 _b.appendBuf((
void*) e.rawdata(), e.
size());
155 const StringData& fieldName) {
158 _b.appendNum((
char) e.
type());
159 _b.appendStr(fieldName);
166 _b.appendNum((
char) Object);
167 _b.appendStr(fieldName);
174 const char * objdata ,
int size = 0 ) {
177 size = *((
int*)objdata);
180 assert( size > 4 && size < 100000000 );
182 _b.appendNum((
char) Object);
183 _b.appendStr(fieldName);
184 _b.appendBuf((
void*)objdata, size );
200 _b.appendNum((
char) Object);
201 _b.appendStr(fieldName);
210 _b.appendNum((
char) Array);
211 _b.appendStr(fieldName);
216 return appendArray(fieldName, arr);
222 _b.appendNum((
char) Array);
223 _b.appendStr(fieldName);
229 _b.appendNum((
char) Bool);
230 _b.appendStr(fieldName);
231 _b.appendNum((
char) (val?1:0));
237 _b.appendNum((
char) Bool);
238 _b.appendStr(fieldName);
239 _b.appendNum((
char) (val?1:0));
245 _b.appendNum((
char) NumberInt);
246 _b.appendStr(fieldName);
253 return append(fieldName, (
int) n);
258 _b.appendNum((
char) NumberLong);
259 _b.appendStr(fieldName);
270 if ( x > -( (numeric_limits<int>::max)() / 2 ) )
271 append( fieldName , (
int)n );
273 append( fieldName , n );
282 return append( fieldName , n );
285 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
double d ) {
286 return append( fieldName , d );
289 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
size_t n ) {
290 static size_t maxInt = (size_t)pow( 2.0 , 30.0 );
293 append( fieldName , (
int)n );
295 append( fieldName , (
long long)n );
299 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
301 static long long maxInt = (int)pow( 2.0 , 30.0 );
302 static long long maxDouble = (
long long)pow( 2.0 , 40.0 );
303 long long x = l > 0 ? -l : l;
305 append( fieldName , (
int)l );
306 else if ( x > -maxDouble )
307 append( fieldName , (
double)l );
309 append( fieldName , l );
315 _b.appendNum((
char) NumberDouble);
316 _b.appendStr(fieldName);
322 const bsonDecimal& decimal )
330 const short *digits = NULL ;
332 weight = decimal.getWeight() ;
333 typemod = decimal.getTypemod() ;
334 scale = decimal.getStorageScale() ;
335 ndigit = decimal.getNdigit() ;
336 digits = decimal.getDigits() ;
337 size = decimal.getSize() ;
340 _b.appendNum( (
char) NumberDecimal ) ;
341 _b.appendStr( fieldName ) ;
342 _b.appendNum( size ) ;
343 _b.appendNum( typemod ) ;
344 _b.appendNum( scale ) ;
345 _b.appendNum( weight ) ;
347 for ( i = 0 ; i < ndigit ; i++ )
349 _b.appendNum( digits[i] ) ;
355 bool appendDecimal(
const StringData& fieldName,
356 const StringData& strDecimal,
357 int precision,
int scale ) ;
359 bool appendDecimal(
const StringData& fieldName,
360 const StringData& strDecimal ) ;
365 bool appendAsNumber(
const StringData& fieldName ,
const string& data );
372 bool generateIfBlank =
false ) {
373 _b.appendNum((
char) jstOID);
374 _b.appendStr(fieldName);
376 _b.appendBuf( (
void *) oid, 12 );
379 if ( generateIfBlank )
383 _b.appendBuf( (
void *) &tmp, 12 );
394 _b.appendNum((
char) jstOID);
395 _b.appendStr(fieldName);
396 _b.appendBuf( (
void *) &oid, 12 );
405 return append(
"_id", OID::gen());
413 _b.appendNum((
char) Date);
414 _b.appendStr(fieldName);
415 _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
425 #if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
426 if( dt > 0 && dt <= 0xffffffff ) {
429 log() <<
"DEV WARNING appendDate() called with a tiny "
430 "(but nonzero) date" << endl;
433 _b.appendNum((
char) Date);
434 _b.appendStr(fieldName);
439 return appendDate(fieldName, dt);
447 const StringData& regex,
const StringData& options =
"") {
448 _b.appendNum((
char) RegEx);
449 _b.appendStr(fieldName);
451 _b.appendStr(options);
456 const StringData& code) {
457 _b.appendNum((
char) Code);
458 _b.appendStr(fieldName);
459 _b.appendNum((
int) code.size()+1);
468 _b.appendNum((
char) String);
469 _b.appendStr(fieldName);
470 _b.appendNum((
int)sz);
471 _b.appendBuf(str, sz);
477 BSONObjBuilder& appendStrWithNoTerminating(
const StringData& fieldName,
const char *str,
480 _b.appendNum((
char) String);
481 _b.appendStr(fieldName);
482 _b.appendNum((
int)sz + 1);
483 _b.appendBuf(str, sz);
491 return append(fieldName, str, (
int) strlen(str)+1);
495 return append(fieldName, str.c_str(), (int) str.size()+1);
499 const StringData& symbol) {
500 _b.appendNum((
char) Symbol);
501 _b.appendStr(fieldName);
502 _b.appendNum((
int) symbol.size()+1);
503 _b.appendStr(symbol);
509 _b.appendNum( (
char) jstNULL );
510 _b.appendStr( fieldName );
516 _b.appendNum( (
char) MinKey );
517 _b.appendStr( fieldName );
523 _b.appendNum( (
char) Undefined );
524 _b.appendStr( fieldName );
530 _b.appendNum( (
char) MaxKey );
531 _b.appendStr( fieldName );
537 BSONObjBuilder& appendTimestamp(
const StringData& fieldName ) {
538 _b.appendNum( (
char) Timestamp );
539 _b.appendStr( fieldName );
540 _b.appendNum( (
long long) 0 );
555 _b.appendNum( (
char) Timestamp );
556 _b.appendStr( fieldName );
572 long long time ,
unsigned int inc );
579 const StringData& ns,
const OID &oid ) {
580 _b.appendNum( (
char) DBRef );
581 _b.appendStr( fieldName );
582 _b.appendNum( (
int) ns.size() + 1 );
584 _b.appendBuf( (
void *) &oid, 12 );
597 BinDataType type,
const char *data ) {
598 if ( type == ByteArrayDeprecated ) {
599 return appendBinDataArrayDeprecated( fieldName.data(), data, len );
602 _b.appendNum( (
char) BinData );
603 _b.appendStr( fieldName );
605 _b.appendNum( (
char) type );
606 _b.appendBuf( (
void *) data, len );
610 BSONObjBuilder& appendBinData(
const StringData& fieldName,
int len,
611 BinDataType type,
const unsigned char *data ) {
612 return appendBinData(fieldName, len, type, (
const char *) data);
622 const char * data ,
int len ) {
623 _b.appendNum( (
char) BinData );
624 _b.appendStr( fieldName );
625 _b.appendNum( len + 4 );
626 _b.appendNum( (
char)0x2 );
628 _b.appendBuf( (
void *) data, len );
636 const StringData& code,
const BSONObj &scope ) {
637 _b.appendNum( (
char) CodeWScope );
638 _b.appendStr( fieldName );
639 _b.appendNum( (
int )( 4 + 4 + code.size() + 1 + scope.
objsize() ));
640 _b.appendNum( (
int ) code.size() + 1 );
641 _b.appendStr( code );
652 void appendWhere(
const StringData& code,
const BSONObj &scope ) {
653 appendCodeWScope(
"$where" , code , scope );
660 void appendMinForType(
const StringData& fieldName ,
int type );
661 void appendMaxForType(
const StringData& fieldName ,
int type );
665 BSONObjBuilder& append(
const StringData& fieldName,
666 const vector< T >& vals );
669 BSONObjBuilder& append(
const StringData& fieldName,
670 const list< T >& vals );
674 BSONObjBuilder& append(
const StringData& fieldName,
const set< T >& vals );
683 massert( 10335 ,
"builder does not own memory", own );
712 _b.setlen(_b.len()-1);
720 char* decouple(
int& l) {
731 void appendKeys(
const BSONObj& keyPattern ,
const BSONObj& values );
733 static string numStr(
int i ) {
762 massert( 10336 ,
"No subobject started", _s.subobjStarted() );
767 BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
768 _s.endField( f.name().c_str() );
773 BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
774 append( v.name().c_str() , v.value() );
781 bool owned()
const {
return &_b == &_buf; }
785 bool hasField(
const StringData& name )
const ;
787 int len()
const {
return _b.len(); }
789 BufBuilder& bb() {
return _b; }
794 return _b.buf() + _offset;
799 _b.claimReservedBytes(1);
800 _b.appendNum((
char) EOO);
801 char *data = _b.buf() + _offset;
802 int size = _b.len() - _offset;
803 *((
int*)data) = size;
805 _tracker->got( size );
812 BSONObjBuilderValueStream _s;
813 BSONSizeTracker * _tracker;
816 static const string numStrs[100];
819 #if defined (SDB_ENGINE) || defined (SDB_CLIENT)
820 class BSONArrayBuilder : bsonnoncopyable,
public SDBObject {
829 template <
typename T>
836 _b.appendTimestamp(num(),val);
841 _b.appendAs(e, num());
845 template <
typename T>
851 _b.appendNull(num());
860 BSONObj done() {
return _b.done(); }
862 void doneFast() { _b.doneFast(); }
864 template <
typename T>
865 BSONArrayBuilder& append(
const StringData& name,
const T& x) {
872 BufBuilder &subobjStart() {
return _b.subobjStart( num() ); }
873 BufBuilder &subarrayStart() {
return _b.subarrayStart( num() ); }
876 BufBuilder &subobjStart(
int pos) {
878 return _b.subobjStart( num() );
880 BufBuilder &subarrayStart(
int pos) {
882 return _b.subarrayStart( num() );
887 BufBuilder &subobjStart(
const StringData& name ) {
889 return _b.subobjStart( num() );
892 BufBuilder &subarrayStart(
const char *name ) {
894 return _b.subarrayStart( num() );
897 void appendArray(
const StringData& name, BSONObj subObj ) {
899 _b.appendArray( num(), subObj );
902 void appendAs(
const BSONElement &e,
const char *name) {
907 int len()
const {
return _b.len(); }
910 void fill(
const StringData& name ) {
912 long int n = strtol( name.data(), &r, 10 );
914 uasserted( 13048, (
string)
"can't append to array using string"
915 " field name [" + name.data() +
"]" );
919 void fill (
int upTo){
924 static BSONElement nullElt() {
925 static BSONObj n = nullObj();
926 return n.firstElement();
929 static BSONObj nullObj() {
935 string num() {
return _b.numStr(_i++); }
942 const vector< T >& vals ) {
944 for (
unsigned int i = 0; i < vals.size(); ++i )
945 arrBuilder.
append( numStr( i ), vals[ i ] );
946 appendArray( fieldName, arrBuilder.
done() );
954 for(
typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
955 arrBuilder.
append( BSONObjBuilder::numStr(n++), *i );
961 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const list< T >& vals ) {
962 return _appendIt< list< T > >( *
this, fieldName, vals );
966 inline BSONObjBuilder& BSONObjBuilder::append(
const StringData& fieldName,
const set< T >& vals ) {
967 return _appendIt< set< T > >( *
this, fieldName, vals );
974 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c)
976 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
979 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
980 const BSONObj& d,
const BSONObj& e)
982 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
983 const BSONObj& d,
const BSONObj& e,
const BSONObj& f)
984 {
return BSON(
"$or" <<
BSON_ARRAY(a << b << c << d << e << f) ); }