summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/bson/bson-inl.h1010
-rw-r--r--src/mongo/bson/bson_db.h13
-rw-r--r--src/mongo/bson/bsonelement.cpp550
-rw-r--r--src/mongo/bson/bsonelement.h14
-rw-r--r--src/mongo/bson/bsonmisc.cpp46
-rw-r--r--src/mongo/bson/bsonmisc.h41
-rw-r--r--src/mongo/bson/bsonobj.cpp276
-rw-r--r--src/mongo/bson/bsonobjbuilder.cpp56
-rw-r--r--src/mongo/bson/bsonobjbuilder.h11
-rw-r--r--src/mongo/bson/bsontypes.h2
-rw-r--r--src/mongo/client/dbclientinterface.h1
-rw-r--r--src/mongo/client/examples/mongoperf.cpp1
-rw-r--r--src/mongo/db/auth/privilege_parser.h1
-rw-r--r--src/mongo/db/dbwebserver.cpp1
-rw-r--r--src/mongo/db/jsobj.h1
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp1
-rw-r--r--src/mongo/db/matcher/expression_parser_tree.cpp1
-rw-r--r--src/mongo/db/matcher/expression_tree.cpp1
-rw-r--r--src/mongo/db/query/type_explain.h1
-rw-r--r--src/mongo/db/repl/health.cpp1
-rw-r--r--src/mongo/db/repl/heartbeat.cpp2
-rw-r--r--src/mongo/db/repl/replset_commands.cpp2
-rw-r--r--src/mongo/db/repl/replset_web_handler.cpp1
-rw-r--r--src/mongo/db/repl/rs.cpp4
-rw-r--r--src/mongo/db/repl/rs_config.cpp2
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp1
-rw-r--r--src/mongo/db/repl/rs_initiate.cpp1
-rw-r--r--src/mongo/db/repl/rs_initiate.h3
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp2
-rw-r--r--src/mongo/db/repl/rs_sync.cpp2
-rw-r--r--src/mongo/db/restapi.cpp1
-rw-r--r--src/mongo/dbtests/jsobjtests.cpp11
-rw-r--r--src/mongo/dbtests/perftests.cpp2
-rw-r--r--src/mongo/s/type_chunk.h1
-rw-r--r--src/mongo/server.h2
35 files changed, 992 insertions, 1074 deletions
diff --git a/src/mongo/bson/bson-inl.h b/src/mongo/bson/bson-inl.h
deleted file mode 100644
index 8925192de27..00000000000
--- a/src/mongo/bson/bson-inl.h
+++ /dev/null
@@ -1,1010 +0,0 @@
-/** @file bsoninlines.h
- a goal here is that the most common bson methods can be used inline-only, a la boost.
- thus some things are inline that wouldn't necessarily be otherwise.
-*/
-
-/* Copyright 2009 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-#pragma once
-
-#include <map>
-#include <limits>
-
-namespace mongo {
-
- /* must be same type when called, unless both sides are #s
- this large function is in header to facilitate inline-only use of bson
- */
- inline int compareElementValues(const BSONElement& l, const BSONElement& r) {
- int f;
-
- switch ( l.type() ) {
- case EOO:
- case Undefined: // EOO and Undefined are same canonicalType
- case jstNULL:
- case MaxKey:
- case MinKey:
- f = l.canonicalType() - r.canonicalType();
- if ( f<0 ) return -1;
- return f==0 ? 0 : 1;
- case Bool:
- return *l.value() - *r.value();
- case Timestamp:
- // unsigned compare for timestamps - note they are not really dates but (ordinal + time_t)
- if ( l.date() < r.date() )
- return -1;
- return l.date() == r.date() ? 0 : 1;
- case Date:
- {
- long long a = (long long) l.Date().millis;
- long long b = (long long) r.Date().millis;
- if( a < b )
- return -1;
- return a == b ? 0 : 1;
- }
- case NumberLong:
- if( r.type() == NumberLong ) {
- long long L = l._numberLong();
- long long R = r._numberLong();
- if( L < R ) return -1;
- if( L == R ) return 0;
- return 1;
- }
- goto dodouble;
- case NumberInt:
- if( r.type() == NumberInt ) {
- int L = l._numberInt();
- int R = r._numberInt();
- if( L < R ) return -1;
- return L == R ? 0 : 1;
- }
- // else fall through
- case NumberDouble:
-dodouble:
- {
- double left = l.number();
- double right = r.number();
- if( left < right )
- return -1;
- if( left == right )
- return 0;
- if( isNaN(left) )
- return isNaN(right) ? 0 : -1;
- return 1;
- }
- case jstOID:
- return memcmp(l.value(), r.value(), 12);
- case Code:
- case Symbol:
- case String:
- /* todo: a utf sort order version one day... */
- {
- // we use memcmp as we allow zeros in UTF8 strings
- int lsz = l.valuestrsize();
- int rsz = r.valuestrsize();
- int common = std::min(lsz, rsz);
- int res = memcmp(l.valuestr(), r.valuestr(), common);
- if( res )
- return res;
- // longer std::string is the greater one
- return lsz-rsz;
- }
- case Object:
- case Array:
- return l.embeddedObject().woCompare( r.embeddedObject() );
- case DBRef: {
- int lsz = l.valuesize();
- int rsz = r.valuesize();
- if ( lsz - rsz != 0 ) return lsz - rsz;
- return memcmp(l.value(), r.value(), lsz);
- }
- case BinData: {
- int lsz = l.objsize(); // our bin data size in bytes, not including the subtype byte
- int rsz = r.objsize();
- if ( lsz - rsz != 0 ) return lsz - rsz;
- return memcmp(l.value()+4, r.value()+4, lsz+1 /*+1 for subtype byte*/);
- }
- case RegEx: {
- int c = strcmp(l.regex(), r.regex());
- if ( c )
- return c;
- return strcmp(l.regexFlags(), r.regexFlags());
- }
- case CodeWScope : {
- f = l.canonicalType() - r.canonicalType();
- if ( f )
- return f;
- f = strcmp( l.codeWScopeCode() , r.codeWScopeCode() );
- if ( f )
- return f;
- f = strcmp( l.codeWScopeScopeDataUnsafe() , r.codeWScopeScopeDataUnsafe() );
- if ( f )
- return f;
- return 0;
- }
- default:
- verify( false);
- }
- return -1;
- }
-
- /* wo = "well ordered"
- note: (mongodb related) : this can only change in behavior when index version # changes
- */
- inline int BSONElement::woCompare( const BSONElement &e,
- bool considerFieldName ) const {
- int lt = (int) canonicalType();
- int rt = (int) e.canonicalType();
- int x = lt - rt;
- if( x != 0 && (!isNumber() || !e.isNumber()) )
- return x;
- if ( considerFieldName ) {
- x = strcmp(fieldName(), e.fieldName());
- if ( x != 0 )
- return x;
- }
- x = compareElementValues(*this, e);
- return x;
- }
-
- inline BSONObjIterator BSONObj::begin() const {
- return BSONObjIterator(*this);
- }
-
- inline BSONObj BSONElement::embeddedObjectUserCheck() const {
- if ( MONGO_likely(isABSONObj()) )
- return BSONObj(value());
- std::stringstream ss;
- ss << "invalid parameter: expected an object (" << fieldName() << ")";
- uasserted( 10065 , ss.str() );
- return BSONObj(); // never reachable
- }
-
- inline BSONObj BSONElement::embeddedObject() const {
- verify( isABSONObj() );
- return BSONObj(value());
- }
-
- inline BSONObj BSONElement::codeWScopeObject() const {
- verify( type() == CodeWScope );
- int strSizeWNull = *(int *)( value() + 4 );
- return BSONObj( value() + 4 + 4 + strSizeWNull );
- }
-
- // deep (full) equality
- inline bool BSONObj::equal(const BSONObj &rhs) const {
- BSONObjIterator i(*this);
- BSONObjIterator j(rhs);
- BSONElement l,r;
- do {
- // so far, equal...
- l = i.next();
- r = j.next();
- if ( l.eoo() )
- return r.eoo();
- } while( l == r );
- return false;
- }
-
- inline NOINLINE_DECL void BSONObj::_assertInvalid() const {
- StringBuilder ss;
- int os = objsize();
- ss << "BSONObj size: " << os << " (0x" << integerToHex( os ) << ") is invalid. "
- << "Size must be between 0 and " << BSONObjMaxInternalSize
- << "(" << ( BSONObjMaxInternalSize/(1024*1024) ) << "MB)";
- try {
- BSONElement e = firstElement();
- ss << " First element: " << e.toString();
- }
- catch ( ... ) { }
- massert( 10334 , ss.str() , 0 );
- }
-
- /* the idea with NOINLINE_DECL here is to keep this from inlining in the
- getOwned() method. the presumption being that is better.
- */
- inline NOINLINE_DECL BSONObj BSONObj::copy() const {
- Holder *h = (Holder*) malloc(objsize() + sizeof(unsigned));
- h->zero();
- memcpy(h->data, objdata(), objsize());
- return BSONObj(h);
- }
-
- inline BSONObj BSONObj::getOwned() const {
- if ( isOwned() )
- return *this;
- return copy();
- }
-
- // wrap this element up as a singleton object.
- inline BSONObj BSONElement::wrap() const {
- BSONObjBuilder b(size()+6);
- b.append(*this);
- return b.obj();
- }
-
- inline BSONObj BSONElement::wrap( const StringData& newName ) const {
- BSONObjBuilder b(size() + 6 + newName.size());
- b.appendAs(*this,newName);
- return b.obj();
- }
-
- inline void BSONObj::getFields(unsigned n, const char **fieldNames, BSONElement *fields) const {
- BSONObjIterator i(*this);
- while ( i.more() ) {
- BSONElement e = i.next();
- const char *p = e.fieldName();
- for( unsigned i = 0; i < n; i++ ) {
- if( strcmp(p, fieldNames[i]) == 0 ) {
- fields[i] = e;
- break;
- }
- }
- }
- }
-
- inline BSONElement BSONObj::getField(const StringData& name) const {
- BSONObjIterator i(*this);
- while ( i.more() ) {
- BSONElement e = i.next();
- if ( name == e.fieldName() )
- return e;
- }
- return BSONElement();
- }
-
- inline int BSONObj::getIntField(const StringData& name) const {
- BSONElement e = getField(name);
- return e.isNumber() ? (int) e.number() : std::numeric_limits< int >::min();
- }
-
- inline bool BSONObj::getBoolField(const StringData& name) const {
- BSONElement e = getField(name);
- return e.type() == Bool ? e.boolean() : false;
- }
-
- inline const char * BSONObj::getStringField(const StringData& name) const {
- BSONElement e = getField(name);
- return e.type() == String ? e.valuestr() : "";
- }
-
- /* add all the fields from the object specified to this object */
- inline BSONObjBuilder& BSONObjBuilder::appendElements(BSONObj x) {
- if (!x.isEmpty())
- _b.appendBuf(
- x.objdata() + 4, // skip over leading length
- x.objsize() - 5); // ignore leading length and trailing \0
- return *this;
- }
-
- /* add all the fields from the object specified to this object if they don't exist */
- inline BSONObjBuilder& BSONObjBuilder::appendElementsUnique(BSONObj x) {
- std::set<std::string> have;
- {
- BSONObjIterator i = iterator();
- while ( i.more() )
- have.insert( i.next().fieldName() );
- }
-
- BSONObjIterator it(x);
- while ( it.more() ) {
- BSONElement e = it.next();
- if ( have.count( e.fieldName() ) )
- continue;
- append(e);
- }
- return *this;
- }
-
-
- inline bool BSONObj::isValid() const {
- int x = objsize();
- return x > 0 && x <= BSONObjMaxInternalSize;
- }
-
- inline bool BSONObj::getObjectID(BSONElement& e) const {
- BSONElement f = getField("_id");
- if( !f.eoo() ) {
- e = f;
- return true;
- }
- return false;
- }
-
- inline BSONObjBuilderValueStream::BSONObjBuilderValueStream( BSONObjBuilder * builder ) {
- _builder = builder;
- }
-
- template<class T>
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<( T value ) {
- _builder->append(_fieldName, value);
- _fieldName = StringData();
- return *_builder;
- }
-
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const BSONElement& e ) {
- _builder->appendAs( e , _fieldName );
- _fieldName = StringData();
- return *_builder;
- }
-
- inline BufBuilder& BSONObjBuilderValueStream::subobjStart() {
- StringData tmp = _fieldName;
- _fieldName = StringData();
- return _builder->subobjStart(tmp);
- }
-
- inline BufBuilder& BSONObjBuilderValueStream::subarrayStart() {
- StringData tmp = _fieldName;
- _fieldName = StringData();
- return _builder->subarrayStart(tmp);
- }
-
- inline Labeler BSONObjBuilderValueStream::operator<<( const Labeler::Label &l ) {
- return Labeler( l, this );
- }
-
- inline void BSONObjBuilderValueStream::endField( const StringData& nextFieldName ) {
- if ( haveSubobj() ) {
- verify( _fieldName.rawData() );
- _builder->append( _fieldName, subobj()->done() );
- _subobj.reset();
- }
- _fieldName = nextFieldName;
- }
-
- inline BSONObjBuilder *BSONObjBuilderValueStream::subobj() {
- if ( !haveSubobj() )
- _subobj.reset( new BSONObjBuilder() );
- return _subobj.get();
- }
-
- template<class T> inline
- BSONObjBuilder& Labeler::operator<<( T value ) {
- s_->subobj()->append( l_.l_, value );
- return *s_->_builder;
- }
-
- inline
- BSONObjBuilder& Labeler::operator<<( const BSONElement& e ) {
- s_->subobj()->appendAs( e, l_.l_ );
- return *s_->_builder;
- }
-
- inline BSONObjIterator BSONObjBuilder::iterator() const {
- const char * s = _b.buf() + _offset;
- const char * e = _b.buf() + _b.len();
- return BSONObjIterator( s , e );
- }
-
- inline bool BSONObjBuilder::hasField( const StringData& name ) const {
- BSONObjIterator i = iterator();
- while ( i.more() )
- if ( name == i.next().fieldName() )
- return true;
- return false;
- }
-
- typedef std::map<std::string, BSONElement> BSONMap;
- inline BSONMap bson2map(const BSONObj& obj) {
- BSONMap m;
- BSONObjIterator it(obj);
- while (it.more()) {
- BSONElement e = it.next();
- m[e.fieldName()] = e;
- }
- return m;
- }
-
- struct BSONElementFieldNameCmp {
- bool operator()( const BSONElement &l, const BSONElement &r ) const {
- return strcmp( l.fieldName() , r.fieldName() ) <= 0;
- }
- };
-
- typedef std::set<BSONElement, BSONElementFieldNameCmp> BSONSortedElements;
- inline BSONSortedElements bson2set( const BSONObj& obj ) {
- BSONSortedElements s;
- BSONObjIterator it(obj);
- while ( it.more() )
- s.insert( it.next() );
- return s;
- }
-
- inline std::string BSONObj::toString( bool isArray, bool full ) const {
- if ( isEmpty() ) return (isArray ? "[]" : "{}");
- StringBuilder s;
- toString(s, isArray, full);
- return s.str();
- }
- inline void BSONObj::toString( StringBuilder& s, bool isArray, bool full, int depth ) const {
- if ( isEmpty() ) {
- s << (isArray ? "[]" : "{}");
- return;
- }
-
- s << ( isArray ? "[ " : "{ " );
- BSONObjIterator i(*this);
- bool first = true;
- while ( 1 ) {
- massert( 10327 , "Object does not end with EOO", i.moreWithEOO() );
- BSONElement e = i.next( true );
- massert( 10328 , "Invalid element size", e.size() > 0 );
- massert( 10329 , "Element too large", e.size() < ( 1 << 30 ) );
- int offset = (int) (e.rawdata() - this->objdata());
- massert( 10330 , "Element extends past end of object",
- e.size() + offset <= this->objsize() );
- bool end = ( e.size() + offset == this->objsize() );
- if ( e.eoo() ) {
- massert( 10331 , "EOO Before end of object", end );
- break;
- }
- if ( first )
- first = false;
- else
- s << ", ";
- e.toString( s, !isArray, full, depth );
- }
- s << ( isArray ? " ]" : " }" );
- }
-
- inline int BSONElement::size( int maxLen ) const {
- if ( totalSize >= 0 )
- return totalSize;
-
- int remain = maxLen - fieldNameSize() - 1;
-
- int x = 0;
- switch ( type() ) {
- case EOO:
- case Undefined:
- case jstNULL:
- case MaxKey:
- case MinKey:
- break;
- case mongo::Bool:
- x = 1;
- break;
- case NumberInt:
- x = 4;
- break;
- case Timestamp:
- case mongo::Date:
- case NumberDouble:
- case NumberLong:
- x = 8;
- break;
- case jstOID:
- x = 12;
- break;
- case Symbol:
- case Code:
- case mongo::String:
- massert( 10313 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
- x = valuestrsize() + 4;
- break;
- case CodeWScope:
- massert( 10314 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
- x = objsize();
- break;
-
- case DBRef:
- massert( 10315 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
- x = valuestrsize() + 4 + 12;
- break;
- case Object:
- case mongo::Array:
- massert( 10316 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
- x = objsize();
- break;
- case BinData:
- massert( 10317 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
- x = valuestrsize() + 4 + 1/*subtype*/;
- break;
- case RegEx: {
- const char *p = value();
- size_t len1 = ( maxLen == -1 ) ? strlen( p ) : (size_t)mongo::strnlen( p, remain );
- //massert( 10318 , "Invalid regex string", len1 != -1 ); // ERH - 4/28/10 - don't think this does anything
- p = p + len1 + 1;
- size_t len2;
- if( maxLen == -1 )
- len2 = strlen( p );
- else {
- size_t x = remain - len1 - 1;
- verify( x <= 0x7fffffff );
- len2 = mongo::strnlen( p, (int) x );
- }
- //massert( 10319 , "Invalid regex options string", len2 != -1 ); // ERH - 4/28/10 - don't think this does anything
- x = (int) (len1 + 1 + len2 + 1);
- }
- break;
- default: {
- StringBuilder ss;
- ss << "BSONElement: bad type " << (int) type();
- std::string msg = ss.str();
- massert( 13655 , msg.c_str(),false);
- }
- }
- totalSize = x + fieldNameSize() + 1; // BSONType
-
- return totalSize;
- }
-
- inline int BSONElement::size() const {
- if ( totalSize >= 0 )
- return totalSize;
-
- int x = 0;
- switch ( type() ) {
- case EOO:
- case Undefined:
- case jstNULL:
- case MaxKey:
- case MinKey:
- break;
- case mongo::Bool:
- x = 1;
- break;
- case NumberInt:
- x = 4;
- break;
- case Timestamp:
- case mongo::Date:
- case NumberDouble:
- case NumberLong:
- x = 8;
- break;
- case jstOID:
- x = 12;
- break;
- case Symbol:
- case Code:
- case mongo::String:
- x = valuestrsize() + 4;
- break;
- case DBRef:
- x = valuestrsize() + 4 + 12;
- break;
- case CodeWScope:
- case Object:
- case mongo::Array:
- x = objsize();
- break;
- case BinData:
- x = valuestrsize() + 4 + 1/*subtype*/;
- break;
- case RegEx:
- {
- const char *p = value();
- size_t len1 = strlen(p);
- p = p + len1 + 1;
- size_t len2;
- len2 = strlen( p );
- x = (int) (len1 + 1 + len2 + 1);
- }
- break;
- default:
- {
- StringBuilder ss;
- ss << "BSONElement: bad type " << (int) type();
- std::string msg = ss.str();
- massert(10320 , msg.c_str(),false);
- }
- }
- totalSize = x + fieldNameSize() + 1; // BSONType
-
- return totalSize;
- }
-
- inline std::string BSONElement::toString( bool includeFieldName, bool full ) const {
- StringBuilder s;
- toString(s, includeFieldName, full);
- return s.str();
- }
- inline void BSONElement::toString( StringBuilder& s, bool includeFieldName, bool full, int depth ) const {
-
- if ( depth > BSONObj::maxToStringRecursionDepth ) {
- // check if we want the full/complete string
- if ( full ) {
- StringBuilder s;
- s << "Reached maximum recursion depth of ";
- s << BSONObj::maxToStringRecursionDepth;
- uassert(16150, s.str(), full != true);
- }
- s << "...";
- return;
- }
-
- if ( includeFieldName && type() != EOO )
- s << fieldName() << ": ";
- switch ( type() ) {
- case EOO:
- s << "EOO";
- break;
- case mongo::Date:
- s << "new Date(" << (long long) date() << ')';
- break;
- case RegEx: {
- s << "/" << regex() << '/';
- const char *p = regexFlags();
- if ( p ) s << p;
- }
- break;
- case NumberDouble:
- s.appendDoubleNice( number() );
- break;
- case NumberLong:
- s << _numberLong();
- break;
- case NumberInt:
- s << _numberInt();
- break;
- case mongo::Bool:
- s << ( boolean() ? "true" : "false" );
- break;
- case Object:
- embeddedObject().toString(s, false, full, depth+1);
- break;
- case mongo::Array:
- embeddedObject().toString(s, true, full, depth+1);
- break;
- case Undefined:
- s << "undefined";
- break;
- case jstNULL:
- s << "null";
- break;
- case MaxKey:
- s << "MaxKey";
- break;
- case MinKey:
- s << "MinKey";
- break;
- case CodeWScope:
- s << "CodeWScope( "
- << codeWScopeCode() << ", " << codeWScopeObject().toString(false, full) << ")";
- break;
- case Code:
- if ( !full && valuestrsize() > 80 ) {
- s.write(valuestr(), 70);
- s << "...";
- }
- else {
- s.write(valuestr(), valuestrsize()-1);
- }
- break;
- case Symbol:
- case mongo::String:
- s << '"';
- if ( !full && valuestrsize() > 160 ) {
- s.write(valuestr(), 150);
- s << "...\"";
- }
- else {
- s.write(valuestr(), valuestrsize()-1);
- s << '"';
- }
- break;
- case DBRef:
- s << "DBRef('" << valuestr() << "',";
- {
- mongo::OID *x = (mongo::OID *) (valuestr() + valuestrsize());
- s << *x << ')';
- }
- break;
- case jstOID:
- s << "ObjectId('";
- s << __oid() << "')";
- break;
- case BinData:
- s << "BinData(" << binDataType() << ", ";
- {
- int len;
- const char *data = binDataClean(len);
- if ( !full && len > 80 ) {
- s << toHex(data, 70) << "...)";
- }
- else {
- s << toHex(data, len) << ")";
- }
- }
- break;
- case Timestamp:
- s << "Timestamp " << timestampTime() << "|" << timestampInc();
- break;
- default:
- s << "?type=" << type();
- break;
- }
- }
-
- /* return has eoo() true if no match
- supports "." notation to reach into embedded objects
- */
- inline BSONElement BSONObj::getFieldDotted(const StringData& name) const {
- BSONElement e = getField(name);
- if (e.eoo()) {
- size_t dot_offset = name.find('.');
- if (dot_offset != std::string::npos) {
- StringData left = name.substr(0, dot_offset);
- StringData right = name.substr(dot_offset + 1);
- BSONObj sub = getObjectField(left);
- return sub.isEmpty() ? BSONElement() : sub.getFieldDotted(right);
- }
- }
-
- return e;
- }
-
- inline BSONObj BSONObj::getObjectField(const StringData& name) const {
- BSONElement e = getField(name);
- BSONType t = e.type();
- return t == Object || t == Array ? e.embeddedObject() : BSONObj();
- }
-
- inline int BSONObj::nFields() const {
- int n = 0;
- BSONObjIterator i(*this);
- while ( i.moreWithEOO() ) {
- BSONElement e = i.next();
- if ( e.eoo() )
- break;
- n++;
- }
- return n;
- }
-
- inline BSONObj::BSONObj() {
- /* little endian ordering here, but perhaps that is ok regardless as BSON is spec'd
- to be little endian external to the system. (i.e. the rest of the implementation of bson,
- not this part, fails to support big endian)
- */
- static char p[] = { /*size*/5, 0, 0, 0, /*eoo*/0 };
- _objdata = p;
- }
-
- inline BSONObj BSONElement::Obj() const { return embeddedObjectUserCheck(); }
-
- inline BSONElement BSONElement::operator[] (const std::string& field) const {
- BSONObj o = Obj();
- return o[field];
- }
-
- inline void BSONObj::elems(std::vector<BSONElement> &v) const {
- BSONObjIterator i(*this);
- while( i.more() )
- v.push_back(i.next());
- }
-
- inline void BSONObj::elems(std::list<BSONElement> &v) const {
- BSONObjIterator i(*this);
- while( i.more() )
- v.push_back(i.next());
- }
-
- template <class T>
- void BSONObj::Vals(std::vector<T>& v) const {
- BSONObjIterator i(*this);
- while( i.more() ) {
- T t;
- i.next().Val(t);
- v.push_back(t);
- }
- }
- template <class T>
- void BSONObj::Vals(std::list<T>& v) const {
- BSONObjIterator i(*this);
- while( i.more() ) {
- T t;
- i.next().Val(t);
- v.push_back(t);
- }
- }
-
- template <class T>
- void BSONObj::vals(std::vector<T>& v) const {
- BSONObjIterator i(*this);
- while( i.more() ) {
- try {
- T t;
- i.next().Val(t);
- v.push_back(t);
- }
- catch(...) { }
- }
- }
- template <class T>
- void BSONObj::vals(std::list<T>& v) const {
- BSONObjIterator i(*this);
- while( i.more() ) {
- try {
- T t;
- i.next().Val(t);
- v.push_back(t);
- }
- catch(...) { }
- }
- }
-
- inline std::ostream& operator<<( std::ostream &s, const BSONObj &o ) {
- return s << o.toString();
- }
-
- inline std::ostream& operator<<( std::ostream &s, const BSONElement &e ) {
- return s << e.toString();
- }
-
- inline StringBuilder& operator<<( StringBuilder &s, const BSONObj &o ) {
- o.toString( s );
- return s;
- }
- inline StringBuilder& operator<<( StringBuilder &s, const BSONElement &e ) {
- e.toString( s );
- return s;
- }
-
-
- inline void BSONElement::Val(BSONObj& v) const { v = Obj(); }
-
- template<typename T>
- inline BSONFieldValue<BSONObj> BSONField<T>::query( const char * q , const T& t ) const {
- BSONObjBuilder b;
- b.append( q , t );
- return BSONFieldValue<BSONObj>( _name , b.obj() );
- }
-
- // used by jsonString()
- inline std::string escape( const std::string& s , bool escape_slash=false) {
- StringBuilder ret;
- for ( std::string::const_iterator i = s.begin(); i != s.end(); ++i ) {
- switch ( *i ) {
- case '"':
- ret << "\\\"";
- break;
- case '\\':
- ret << "\\\\";
- break;
- case '/':
- ret << (escape_slash ? "\\/" : "/");
- break;
- case '\b':
- ret << "\\b";
- break;
- case '\f':
- ret << "\\f";
- break;
- case '\n':
- ret << "\\n";
- break;
- case '\r':
- ret << "\\r";
- break;
- case '\t':
- ret << "\\t";
- break;
- default:
- if ( *i >= 0 && *i <= 0x1f ) {
- //TODO: these should be utf16 code-units not bytes
- char c = *i;
- ret << "\\u00" << toHexLower(&c, 1);
- }
- else {
- ret << *i;
- }
- }
- }
- return ret.str();
- }
-
- inline std::string BSONObj::hexDump() const {
- std::stringstream ss;
- const char *d = objdata();
- int size = objsize();
- for( int i = 0; i < size; ++i ) {
- ss.width( 2 );
- ss.fill( '0' );
- ss << std::hex << (unsigned)(unsigned char)( d[ i ] ) << std::dec;
- if ( ( d[ i ] >= '0' && d[ i ] <= '9' ) || ( d[ i ] >= 'A' && d[ i ] <= 'z' ) )
- ss << '\'' << d[ i ] << '\'';
- if ( i != size - 1 )
- ss << ' ';
- }
- return ss.str();
- }
-
- inline void BSONObjBuilder::appendKeys( const BSONObj& keyPattern , const BSONObj& values ) {
- BSONObjIterator i(keyPattern);
- BSONObjIterator j(values);
-
- while ( i.more() && j.more() ) {
- appendAs( j.next() , i.next().fieldName() );
- }
-
- verify( ! i.more() );
- verify( ! j.more() );
- }
-
- inline BSONObj BSONObj::removeField(const StringData& name) const {
- BSONObjBuilder b;
- BSONObjIterator i(*this);
- while ( i.more() ) {
- BSONElement e = i.next();
- const char *fname = e.fieldName();
- if ( name != fname )
- b.append(e);
- }
- return b.obj();
- }
-
- template<typename T> bool BSONObj::coerceVector( std::vector<T>* out ) const {
- BSONObjIterator i( *this );
- while ( i.more() ) {
- BSONElement e = i.next();
- T t;
- if ( ! e.coerce<T>( &t ) )
- return false;
- out->push_back( t );
- }
- return true;
- }
-
-
- template<> inline bool BSONElement::coerce<std::string>( std::string* out ) const {
- if ( type() != mongo::String )
- return false;
- *out = String();
- return true;
- }
-
- template<> inline bool BSONElement::coerce<int>( int* out ) const {
- if ( !isNumber() )
- return false;
- *out = numberInt();
- return true;
- }
-
- template<> inline bool BSONElement::coerce<double>( double* out ) const {
- if ( !isNumber() )
- return false;
- *out = numberDouble();
- return true;
- }
-
- template<> inline bool BSONElement::coerce<bool>( bool* out ) const {
- *out = trueValue();
- return true;
- }
-
- template<> inline bool BSONElement::coerce< std::vector<std::string> >( std::vector<std::string>* out ) const {
- if ( type() != mongo::Array )
- return false;
- return Obj().coerceVector<std::string>( out );
- }
-
-
-}
diff --git a/src/mongo/bson/bson_db.h b/src/mongo/bson/bson_db.h
index 3f2792f1599..bd1b7b53a33 100644
--- a/src/mongo/bson/bson_db.h
+++ b/src/mongo/bson/bson_db.h
@@ -110,4 +110,17 @@ namespace mongo {
return *_builder;
}
+ template<class T> inline
+ BSONObjBuilder& BSONObjBuilderValueStream::operator<<( T value ) {
+ _builder->append(_fieldName, value);
+ _fieldName = StringData();
+ return *_builder;
+ }
+
+ template<class T>
+ BSONObjBuilder& Labeler::operator<<( T value ) {
+ s_->subobj()->append( l_.l_, value );
+ return *s_->_builder;
+ }
+
}
diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp
index 4c7a8c9f662..47e9e0a1544 100644
--- a/src/mongo/bson/bsonelement.cpp
+++ b/src/mongo/bson/bsonelement.cpp
@@ -364,5 +364,555 @@ namespace mongo {
}
return v;
}
+
+ /* wo = "well ordered"
+ note: (mongodb related) : this can only change in behavior when index version # changes
+ */
+ int BSONElement::woCompare( const BSONElement &e,
+ bool considerFieldName ) const {
+ int lt = (int) canonicalType();
+ int rt = (int) e.canonicalType();
+ int x = lt - rt;
+ if( x != 0 && (!isNumber() || !e.isNumber()) )
+ return x;
+ if ( considerFieldName ) {
+ x = strcmp(fieldName(), e.fieldName());
+ if ( x != 0 )
+ return x;
+ }
+ x = compareElementValues(*this, e);
+ return x;
+ }
+
+
+ BSONObj BSONElement::embeddedObjectUserCheck() const {
+ if ( MONGO_likely(isABSONObj()) )
+ return BSONObj(value());
+ std::stringstream ss;
+ ss << "invalid parameter: expected an object (" << fieldName() << ")";
+ uasserted( 10065 , ss.str() );
+ return BSONObj(); // never reachable
+ }
+
+ BSONObj BSONElement::embeddedObject() const {
+ verify( isABSONObj() );
+ return BSONObj(value());
+ }
+
+ BSONObj BSONElement::codeWScopeObject() const {
+ verify( type() == CodeWScope );
+ int strSizeWNull = *(int *)( value() + 4 );
+ return BSONObj( value() + 4 + 4 + strSizeWNull );
+ }
+
+ // wrap this element up as a singleton object.
+ BSONObj BSONElement::wrap() const {
+ BSONObjBuilder b(size()+6);
+ b.append(*this);
+ return b.obj();
+ }
+
+ BSONObj BSONElement::wrap( const StringData& newName ) const {
+ BSONObjBuilder b(size() + 6 + newName.size());
+ b.appendAs(*this,newName);
+ return b.obj();
+ }
+
+ void BSONElement::Val(BSONObj& v) const {
+ v = Obj();
+ }
+
+ BSONObj BSONElement::Obj() const {
+ return embeddedObjectUserCheck();
+ }
+
+ BSONElement BSONElement::operator[] (const std::string& field) const {
+ BSONObj o = Obj();
+ return o[field];
+ }
+
+ int BSONElement::size( int maxLen ) const {
+ if ( totalSize >= 0 )
+ return totalSize;
+
+ int remain = maxLen - fieldNameSize() - 1;
+
+ int x = 0;
+ switch ( type() ) {
+ case EOO:
+ case Undefined:
+ case jstNULL:
+ case MaxKey:
+ case MinKey:
+ break;
+ case mongo::Bool:
+ x = 1;
+ break;
+ case NumberInt:
+ x = 4;
+ break;
+ case Timestamp:
+ case mongo::Date:
+ case NumberDouble:
+ case NumberLong:
+ x = 8;
+ break;
+ case jstOID:
+ x = 12;
+ break;
+ case Symbol:
+ case Code:
+ case mongo::String:
+ massert( 10313 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
+ x = valuestrsize() + 4;
+ break;
+ case CodeWScope:
+ massert( 10314 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
+ x = objsize();
+ break;
+
+ case DBRef:
+ massert( 10315 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
+ x = valuestrsize() + 4 + 12;
+ break;
+ case Object:
+ case mongo::Array:
+ massert( 10316 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
+ x = objsize();
+ break;
+ case BinData:
+ massert( 10317 , "Insufficient bytes to calculate element size", maxLen == -1 || remain > 3 );
+ x = valuestrsize() + 4 + 1/*subtype*/;
+ break;
+ case RegEx: {
+ const char *p = value();
+ size_t len1 = ( maxLen == -1 ) ? strlen( p ) : (size_t)mongo::strnlen( p, remain );
+ //massert( 10318 , "Invalid regex string", len1 != -1 ); // ERH - 4/28/10 - don't think this does anything
+ p = p + len1 + 1;
+ size_t len2;
+ if( maxLen == -1 )
+ len2 = strlen( p );
+ else {
+ size_t x = remain - len1 - 1;
+ verify( x <= 0x7fffffff );
+ len2 = mongo::strnlen( p, (int) x );
+ }
+ //massert( 10319 , "Invalid regex options string", len2 != -1 ); // ERH - 4/28/10 - don't think this does anything
+ x = (int) (len1 + 1 + len2 + 1);
+ }
+ break;
+ default: {
+ StringBuilder ss;
+ ss << "BSONElement: bad type " << (int) type();
+ std::string msg = ss.str();
+ massert( 13655 , msg.c_str(),false);
+ }
+ }
+ totalSize = x + fieldNameSize() + 1; // BSONType
+
+ return totalSize;
+ }
+
+ int BSONElement::size() const {
+ if ( totalSize >= 0 )
+ return totalSize;
+
+ int x = 0;
+ switch ( type() ) {
+ case EOO:
+ case Undefined:
+ case jstNULL:
+ case MaxKey:
+ case MinKey:
+ break;
+ case mongo::Bool:
+ x = 1;
+ break;
+ case NumberInt:
+ x = 4;
+ break;
+ case Timestamp:
+ case mongo::Date:
+ case NumberDouble:
+ case NumberLong:
+ x = 8;
+ break;
+ case jstOID:
+ x = 12;
+ break;
+ case Symbol:
+ case Code:
+ case mongo::String:
+ x = valuestrsize() + 4;
+ break;
+ case DBRef:
+ x = valuestrsize() + 4 + 12;
+ break;
+ case CodeWScope:
+ case Object:
+ case mongo::Array:
+ x = objsize();
+ break;
+ case BinData:
+ x = valuestrsize() + 4 + 1/*subtype*/;
+ break;
+ case RegEx:
+ {
+ const char *p = value();
+ size_t len1 = strlen(p);
+ p = p + len1 + 1;
+ size_t len2;
+ len2 = strlen( p );
+ x = (int) (len1 + 1 + len2 + 1);
+ }
+ break;
+ default:
+ {
+ StringBuilder ss;
+ ss << "BSONElement: bad type " << (int) type();
+ std::string msg = ss.str();
+ massert(10320 , msg.c_str(),false);
+ }
+ }
+ totalSize = x + fieldNameSize() + 1; // BSONType
+
+ return totalSize;
+ }
+
+ std::string BSONElement::toString( bool includeFieldName, bool full ) const {
+ StringBuilder s;
+ toString(s, includeFieldName, full);
+ return s.str();
+ }
+
+ void BSONElement::toString( StringBuilder& s, bool includeFieldName, bool full, int depth ) const {
+
+ if ( depth > BSONObj::maxToStringRecursionDepth ) {
+ // check if we want the full/complete string
+ if ( full ) {
+ StringBuilder s;
+ s << "Reached maximum recursion depth of ";
+ s << BSONObj::maxToStringRecursionDepth;
+ uassert(16150, s.str(), full != true);
+ }
+ s << "...";
+ return;
+ }
+
+ if ( includeFieldName && type() != EOO )
+ s << fieldName() << ": ";
+ switch ( type() ) {
+ case EOO:
+ s << "EOO";
+ break;
+ case mongo::Date:
+ s << "new Date(" << (long long) date() << ')';
+ break;
+ case RegEx: {
+ s << "/" << regex() << '/';
+ const char *p = regexFlags();
+ if ( p ) s << p;
+ }
+ break;
+ case NumberDouble:
+ s.appendDoubleNice( number() );
+ break;
+ case NumberLong:
+ s << _numberLong();
+ break;
+ case NumberInt:
+ s << _numberInt();
+ break;
+ case mongo::Bool:
+ s << ( boolean() ? "true" : "false" );
+ break;
+ case Object:
+ embeddedObject().toString(s, false, full, depth+1);
+ break;
+ case mongo::Array:
+ embeddedObject().toString(s, true, full, depth+1);
+ break;
+ case Undefined:
+ s << "undefined";
+ break;
+ case jstNULL:
+ s << "null";
+ break;
+ case MaxKey:
+ s << "MaxKey";
+ break;
+ case MinKey:
+ s << "MinKey";
+ break;
+ case CodeWScope:
+ s << "CodeWScope( "
+ << codeWScopeCode() << ", " << codeWScopeObject().toString(false, full) << ")";
+ break;
+ case Code:
+ if ( !full && valuestrsize() > 80 ) {
+ s.write(valuestr(), 70);
+ s << "...";
+ }
+ else {
+ s.write(valuestr(), valuestrsize()-1);
+ }
+ break;
+ case Symbol:
+ case mongo::String:
+ s << '"';
+ if ( !full && valuestrsize() > 160 ) {
+ s.write(valuestr(), 150);
+ s << "...\"";
+ }
+ else {
+ s.write(valuestr(), valuestrsize()-1);
+ s << '"';
+ }
+ break;
+ case DBRef:
+ s << "DBRef('" << valuestr() << "',";
+ {
+ mongo::OID *x = (mongo::OID *) (valuestr() + valuestrsize());
+ s << *x << ')';
+ }
+ break;
+ case jstOID:
+ s << "ObjectId('";
+ s << __oid() << "')";
+ break;
+ case BinData:
+ s << "BinData(" << binDataType() << ", ";
+ {
+ int len;
+ const char *data = binDataClean(len);
+ if ( !full && len > 80 ) {
+ s << toHex(data, 70) << "...)";
+ }
+ else {
+ s << toHex(data, len) << ")";
+ }
+ }
+ break;
+ case Timestamp:
+ s << "Timestamp " << timestampTime() << "|" << timestampInc();
+ break;
+ default:
+ s << "?type=" << type();
+ break;
+ }
+ }
+
+ std::ostream& operator<<( std::ostream &s, const BSONElement &e ) {
+ return s << e.toString();
+ }
+
+ StringBuilder& operator<<( StringBuilder &s, const BSONElement &e ) {
+ e.toString( s );
+ return s;
+ }
+
+ template<> bool BSONElement::coerce<std::string>( std::string* out ) const {
+ if ( type() != mongo::String )
+ return false;
+ *out = String();
+ return true;
+ }
+
+ template<> bool BSONElement::coerce<int>( int* out ) const {
+ if ( !isNumber() )
+ return false;
+ *out = numberInt();
+ return true;
+ }
+
+ template<> bool BSONElement::coerce<double>( double* out ) const {
+ if ( !isNumber() )
+ return false;
+ *out = numberDouble();
+ return true;
+ }
+
+ template<> bool BSONElement::coerce<bool>( bool* out ) const {
+ *out = trueValue();
+ return true;
+ }
+
+ template<> bool BSONElement::coerce< std::vector<std::string> >( std::vector<std::string>* out ) const {
+ if ( type() != mongo::Array )
+ return false;
+ return Obj().coerceVector<std::string>( out );
+ }
+
+ template<typename T> bool BSONObj::coerceVector( std::vector<T>* out ) const {
+ BSONObjIterator i( *this );
+ while ( i.more() ) {
+ BSONElement e = i.next();
+ T t;
+ if ( ! e.coerce<T>( &t ) )
+ return false;
+ out->push_back( t );
+ }
+ return true;
+ }
+
+ // used by jsonString()
+ std::string escape( const std::string& s , bool escape_slash) {
+ StringBuilder ret;
+ for ( std::string::const_iterator i = s.begin(); i != s.end(); ++i ) {
+ switch ( *i ) {
+ case '"':
+ ret << "\\\"";
+ break;
+ case '\\':
+ ret << "\\\\";
+ break;
+ case '/':
+ ret << (escape_slash ? "\\/" : "/");
+ break;
+ case '\b':
+ ret << "\\b";
+ break;
+ case '\f':
+ ret << "\\f";
+ break;
+ case '\n':
+ ret << "\\n";
+ break;
+ case '\r':
+ ret << "\\r";
+ break;
+ case '\t':
+ ret << "\\t";
+ break;
+ default:
+ if ( *i >= 0 && *i <= 0x1f ) {
+ //TODO: these should be utf16 code-units not bytes
+ char c = *i;
+ ret << "\\u00" << toHexLower(&c, 1);
+ }
+ else {
+ ret << *i;
+ }
+ }
+ }
+ return ret.str();
+ }
+
+ /* must be same type when called, unless both sides are #s
+ this large function is in header to facilitate inline-only use of bson
+ */
+ int compareElementValues(const BSONElement& l, const BSONElement& r) {
+ int f;
+
+ switch ( l.type() ) {
+ case EOO:
+ case Undefined: // EOO and Undefined are same canonicalType
+ case jstNULL:
+ case MaxKey:
+ case MinKey:
+ f = l.canonicalType() - r.canonicalType();
+ if ( f<0 ) return -1;
+ return f==0 ? 0 : 1;
+ case Bool:
+ return *l.value() - *r.value();
+ case Timestamp:
+ // unsigned compare for timestamps - note they are not really dates but (ordinal + time_t)
+ if ( l.date() < r.date() )
+ return -1;
+ return l.date() == r.date() ? 0 : 1;
+ case Date:
+ {
+ long long a = (long long) l.Date().millis;
+ long long b = (long long) r.Date().millis;
+ if( a < b )
+ return -1;
+ return a == b ? 0 : 1;
+ }
+ case NumberLong:
+ if( r.type() == NumberLong ) {
+ long long L = l._numberLong();
+ long long R = r._numberLong();
+ if( L < R ) return -1;
+ if( L == R ) return 0;
+ return 1;
+ }
+ goto dodouble;
+ case NumberInt:
+ if( r.type() == NumberInt ) {
+ int L = l._numberInt();
+ int R = r._numberInt();
+ if( L < R ) return -1;
+ return L == R ? 0 : 1;
+ }
+ // else fall through
+ case NumberDouble:
+dodouble:
+ {
+ double left = l.number();
+ double right = r.number();
+ if( left < right )
+ return -1;
+ if( left == right )
+ return 0;
+ if( isNaN(left) )
+ return isNaN(right) ? 0 : -1;
+ return 1;
+ }
+ case jstOID:
+ return memcmp(l.value(), r.value(), 12);
+ case Code:
+ case Symbol:
+ case String:
+ /* todo: a utf sort order version one day... */
+ {
+ // we use memcmp as we allow zeros in UTF8 strings
+ int lsz = l.valuestrsize();
+ int rsz = r.valuestrsize();
+ int common = std::min(lsz, rsz);
+ int res = memcmp(l.valuestr(), r.valuestr(), common);
+ if( res )
+ return res;
+ // longer std::string is the greater one
+ return lsz-rsz;
+ }
+ case Object:
+ case Array:
+ return l.embeddedObject().woCompare( r.embeddedObject() );
+ case DBRef: {
+ int lsz = l.valuesize();
+ int rsz = r.valuesize();
+ if ( lsz - rsz != 0 ) return lsz - rsz;
+ return memcmp(l.value(), r.value(), lsz);
+ }
+ case BinData: {
+ int lsz = l.objsize(); // our bin data size in bytes, not including the subtype byte
+ int rsz = r.objsize();
+ if ( lsz - rsz != 0 ) return lsz - rsz;
+ return memcmp(l.value()+4, r.value()+4, lsz+1 /*+1 for subtype byte*/);
+ }
+ case RegEx: {
+ int c = strcmp(l.regex(), r.regex());
+ if ( c )
+ return c;
+ return strcmp(l.regexFlags(), r.regexFlags());
+ }
+ case CodeWScope : {
+ f = l.canonicalType() - r.canonicalType();
+ if ( f )
+ return f;
+ f = strcmp( l.codeWScopeCode() , r.codeWScopeCode() );
+ if ( f )
+ return f;
+ f = strcmp( l.codeWScopeScopeDataUnsafe() , r.codeWScopeScopeDataUnsafe() );
+ if ( f )
+ return f;
+ return 0;
+ }
+ default:
+ verify( false);
+ }
+ return -1;
+ }
+
} // namespace mongo
diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h
index dd751c8b286..2c827398892 100644
--- a/src/mongo/bson/bsonelement.h
+++ b/src/mongo/bson/bsonelement.h
@@ -44,15 +44,10 @@ namespace mongo {
class BSONObj;
class BSONElement;
class BSONObjBuilder;
-}
-namespace bson {
- typedef mongo::BSONElement be;
- typedef mongo::BSONObj bo;
- typedef mongo::BSONObjBuilder bob;
-}
-
-namespace mongo {
+ typedef BSONElement be;
+ typedef BSONObj bo;
+ typedef BSONObjBuilder bob;
/* l and r MUST have same type when called: check that first. */
int compareElementValues(const BSONElement& l, const BSONElement& r);
@@ -644,4 +639,7 @@ namespace mongo {
totalSize = 1;
}
+ // TODO(SERVER-14596): move to a better place; take a StringData.
+ std::string escape( const std::string& s , bool escape_slash=false);
+
}
diff --git a/src/mongo/bson/bsonmisc.cpp b/src/mongo/bson/bsonmisc.cpp
index c6088dbfdf1..b1b213791b9 100644
--- a/src/mongo/bson/bsonmisc.cpp
+++ b/src/mongo/bson/bsonmisc.cpp
@@ -68,4 +68,50 @@ namespace mongo {
MinKeyLabeler MINKEY;
MaxKeyLabeler MAXKEY;
+ BSONObjBuilderValueStream::BSONObjBuilderValueStream( BSONObjBuilder * builder ) {
+ _builder = builder;
+ }
+
+ BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const BSONElement& e ) {
+ _builder->appendAs( e , _fieldName );
+ _fieldName = StringData();
+ return *_builder;
+ }
+
+ BufBuilder& BSONObjBuilderValueStream::subobjStart() {
+ StringData tmp = _fieldName;
+ _fieldName = StringData();
+ return _builder->subobjStart(tmp);
+ }
+
+ BufBuilder& BSONObjBuilderValueStream::subarrayStart() {
+ StringData tmp = _fieldName;
+ _fieldName = StringData();
+ return _builder->subarrayStart(tmp);
+ }
+
+ Labeler BSONObjBuilderValueStream::operator<<( const Labeler::Label &l ) {
+ return Labeler( l, this );
+ }
+
+ void BSONObjBuilderValueStream::endField( const StringData& nextFieldName ) {
+ if ( haveSubobj() ) {
+ verify( _fieldName.rawData() );
+ _builder->append( _fieldName, subobj()->done() );
+ _subobj.reset();
+ }
+ _fieldName = nextFieldName;
+ }
+
+ BSONObjBuilder *BSONObjBuilderValueStream::subobj() {
+ if ( !haveSubobj() )
+ _subobj.reset( new BSONObjBuilder() );
+ return _subobj.get();
+ }
+
+ BSONObjBuilder& Labeler::operator<<( const BSONElement& e ) {
+ s_->subobj()->appendAs( e, l_.l_ );
+ return *s_->_builder;
+ }
+
} // namespace mongo
diff --git a/src/mongo/bson/bsonmisc.h b/src/mongo/bson/bsonmisc.h
index 0a2cd60b14c..af96981128e 100644
--- a/src/mongo/bson/bsonmisc.h
+++ b/src/mongo/bson/bsonmisc.h
@@ -32,7 +32,6 @@
#include <memory>
#include "mongo/bson/bsonelement.h"
-#include "mongo/client/export_macros.h"
namespace mongo {
@@ -91,38 +90,38 @@ namespace mongo {
Example:
std::cout << BSON( GENOID << "z" << 3 ); // { _id : ..., z : 3 }
*/
- struct MONGO_CLIENT_API GENOIDLabeler { };
- extern MONGO_CLIENT_API GENOIDLabeler GENOID;
+ struct GENOIDLabeler { };
+ extern GENOIDLabeler GENOID;
/* Utility class to add a Date element with the current time
Example:
std::cout << BSON( "created" << DATENOW ); // { created : "2009-10-09 11:41:42" }
*/
- struct MONGO_CLIENT_API DateNowLabeler { };
- extern MONGO_CLIENT_API DateNowLabeler DATENOW;
+ struct DateNowLabeler { };
+ extern DateNowLabeler DATENOW;
/* Utility class to assign a NULL value to a given attribute
Example:
std::cout << BSON( "a" << BSONNULL ); // { a : null }
*/
- struct MONGO_CLIENT_API NullLabeler { };
- extern MONGO_CLIENT_API NullLabeler BSONNULL;
+ struct NullLabeler { };
+ extern NullLabeler BSONNULL;
/* Utility class to assign an Undefined value to a given attribute
Example:
std::cout << BSON( "a" << BSONUndefined ); // { a : undefined }
*/
- struct MONGO_CLIENT_API UndefinedLabeler { };
- extern MONGO_CLIENT_API UndefinedLabeler BSONUndefined;
+ struct UndefinedLabeler { };
+ extern UndefinedLabeler BSONUndefined;
/* Utility class to add the minKey (minus infinity) to a given attribute
Example:
std::cout << BSON( "a" << MINKEY ); // { "a" : { "$minKey" : 1 } }
*/
- struct MONGO_CLIENT_API MinKeyLabeler { };
- extern MONGO_CLIENT_API MinKeyLabeler MINKEY;
- struct MONGO_CLIENT_API MaxKeyLabeler { };
- extern MONGO_CLIENT_API MaxKeyLabeler MAXKEY;
+ struct MinKeyLabeler { };
+ extern MinKeyLabeler MINKEY;
+ struct MaxKeyLabeler { };
+ extern MaxKeyLabeler MAXKEY;
// Utility class to implement GT, GTE, etc as described above.
class Labeler {
@@ -187,13 +186,13 @@ namespace mongo {
OID oid;
};
- extern MONGO_CLIENT_API Labeler::Label GT;
- extern MONGO_CLIENT_API Labeler::Label GTE;
- extern MONGO_CLIENT_API Labeler::Label LT;
- extern MONGO_CLIENT_API Labeler::Label LTE;
- extern MONGO_CLIENT_API Labeler::Label NE;
- extern MONGO_CLIENT_API Labeler::Label NIN;
- extern MONGO_CLIENT_API Labeler::Label BSIZE;
+ extern Labeler::Label GT;
+ extern Labeler::Label GTE;
+ extern Labeler::Label LT;
+ extern Labeler::Label LTE;
+ extern Labeler::Label NE;
+ extern Labeler::Label NIN;
+ extern Labeler::Label BSIZE;
// $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT << 6));
@@ -206,7 +205,7 @@ namespace mongo {
// definitions in bsonobjbuilder.h b/c of incomplete types
// Utility class to implement BSON( key << val ) as described above.
- class MONGO_CLIENT_API BSONObjBuilderValueStream : public boost::noncopyable {
+ class BSONObjBuilderValueStream : public boost::noncopyable {
public:
friend class Labeler;
BSONObjBuilderValueStream( BSONObjBuilder * builder );
diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp
index 0614ab98a83..0fc1a2461dd 100644
--- a/src/mongo/bson/bsonobj.cpp
+++ b/src/mongo/bson/bsonobj.cpp
@@ -38,6 +38,52 @@ namespace mongo {
using namespace std;
/* BSONObj ------------------------------------------------------------*/
+ // deep (full) equality
+ bool BSONObj::equal(const BSONObj &rhs) const {
+ BSONObjIterator i(*this);
+ BSONObjIterator j(rhs);
+ BSONElement l,r;
+ do {
+ // so far, equal...
+ l = i.next();
+ r = j.next();
+ if ( l.eoo() )
+ return r.eoo();
+ } while( l == r );
+ return false;
+ }
+
+ void BSONObj::_assertInvalid() const {
+ StringBuilder ss;
+ int os = objsize();
+ ss << "BSONObj size: " << os << " (0x" << integerToHex( os ) << ") is invalid. "
+ << "Size must be between 0 and " << BSONObjMaxInternalSize
+ << "(" << ( BSONObjMaxInternalSize/(1024*1024) ) << "MB)";
+ try {
+ BSONElement e = firstElement();
+ ss << " First element: " << e.toString();
+ }
+ catch ( ... ) { }
+ massert( 10334 , ss.str() , 0 );
+ }
+
+ BSONObj BSONObj::copy() const {
+ Holder *h = (Holder*) malloc(objsize() + sizeof(unsigned));
+ h->zero();
+ memcpy(h->data, objdata(), objsize());
+ return BSONObj(h);
+ }
+
+ BSONObj BSONObj::getOwned() const {
+ if ( isOwned() )
+ return *this;
+ return copy();
+ }
+
+ BSONObjIterator BSONObj::begin() const {
+ return BSONObjIterator(*this);
+ }
+
string BSONObj::md5() const {
md5digest d;
md5_state_t st;
@@ -589,4 +635,234 @@ namespace mongo {
}
}
+ void BSONObj::getFields(unsigned n, const char **fieldNames, BSONElement *fields) const {
+ BSONObjIterator i(*this);
+ while ( i.more() ) {
+ BSONElement e = i.next();
+ const char *p = e.fieldName();
+ for( unsigned i = 0; i < n; i++ ) {
+ if( strcmp(p, fieldNames[i]) == 0 ) {
+ fields[i] = e;
+ break;
+ }
+ }
+ }
+ }
+
+ BSONElement BSONObj::getField(const StringData& name) const {
+ BSONObjIterator i(*this);
+ while ( i.more() ) {
+ BSONElement e = i.next();
+ if ( name == e.fieldName() )
+ return e;
+ }
+ return BSONElement();
+ }
+
+ int BSONObj::getIntField(const StringData& name) const {
+ BSONElement e = getField(name);
+ return e.isNumber() ? (int) e.number() : std::numeric_limits< int >::min();
+ }
+
+ bool BSONObj::getBoolField(const StringData& name) const {
+ BSONElement e = getField(name);
+ return e.type() == Bool ? e.boolean() : false;
+ }
+
+ const char * BSONObj::getStringField(const StringData& name) const {
+ BSONElement e = getField(name);
+ return e.type() == String ? e.valuestr() : "";
+ }
+
+ bool BSONObj::isValid() const {
+ int x = objsize();
+ return x > 0 && x <= BSONObjMaxInternalSize;
+ }
+
+ bool BSONObj::getObjectID(BSONElement& e) const {
+ BSONElement f = getField("_id");
+ if( !f.eoo() ) {
+ e = f;
+ return true;
+ }
+ return false;
+ }
+
+ BSONObj BSONObj::removeField(const StringData& name) const {
+ BSONObjBuilder b;
+ BSONObjIterator i(*this);
+ while ( i.more() ) {
+ BSONElement e = i.next();
+ const char *fname = e.fieldName();
+ if ( name != fname )
+ b.append(e);
+ }
+ return b.obj();
+ }
+
+ std::string BSONObj::hexDump() const {
+ std::stringstream ss;
+ const char *d = objdata();
+ int size = objsize();
+ for( int i = 0; i < size; ++i ) {
+ ss.width( 2 );
+ ss.fill( '0' );
+ ss << std::hex << (unsigned)(unsigned char)( d[ i ] ) << std::dec;
+ if ( ( d[ i ] >= '0' && d[ i ] <= '9' ) || ( d[ i ] >= 'A' && d[ i ] <= 'z' ) )
+ ss << '\'' << d[ i ] << '\'';
+ if ( i != size - 1 )
+ ss << ' ';
+ }
+ return ss.str();
+ }
+
+
+ void BSONObj::elems(std::vector<BSONElement> &v) const {
+ BSONObjIterator i(*this);
+ while( i.more() )
+ v.push_back(i.next());
+ }
+
+ void BSONObj::elems(std::list<BSONElement> &v) const {
+ BSONObjIterator i(*this);
+ while( i.more() )
+ v.push_back(i.next());
+ }
+
+ /* return has eoo() true if no match
+ supports "." notation to reach into embedded objects
+ */
+ BSONElement BSONObj::getFieldDotted(const StringData& name) const {
+ BSONElement e = getField(name);
+ if (e.eoo()) {
+ size_t dot_offset = name.find('.');
+ if (dot_offset != std::string::npos) {
+ StringData left = name.substr(0, dot_offset);
+ StringData right = name.substr(dot_offset + 1);
+ BSONObj sub = getObjectField(left);
+ return sub.isEmpty() ? BSONElement() : sub.getFieldDotted(right);
+ }
+ }
+
+ return e;
+ }
+
+ BSONObj BSONObj::getObjectField(const StringData& name) const {
+ BSONElement e = getField(name);
+ BSONType t = e.type();
+ return t == Object || t == Array ? e.embeddedObject() : BSONObj();
+ }
+
+ int BSONObj::nFields() const {
+ int n = 0;
+ BSONObjIterator i(*this);
+ while ( i.moreWithEOO() ) {
+ BSONElement e = i.next();
+ if ( e.eoo() )
+ break;
+ n++;
+ }
+ return n;
+ }
+
+ BSONObj::BSONObj() {
+ /* little endian ordering here, but perhaps that is ok regardless as BSON is spec'd
+ to be little endian external to the system. (i.e. the rest of the implementation of bson,
+ not this part, fails to support big endian)
+ */
+ static char p[] = { /*size*/5, 0, 0, 0, /*eoo*/0 };
+ _objdata = p;
+ }
+
+ std::string BSONObj::toString( bool isArray, bool full ) const {
+ if ( isEmpty() ) return (isArray ? "[]" : "{}");
+ StringBuilder s;
+ toString(s, isArray, full);
+ return s.str();
+ }
+ void BSONObj::toString( StringBuilder& s, bool isArray, bool full, int depth ) const {
+ if ( isEmpty() ) {
+ s << (isArray ? "[]" : "{}");
+ return;
+ }
+
+ s << ( isArray ? "[ " : "{ " );
+ BSONObjIterator i(*this);
+ bool first = true;
+ while ( 1 ) {
+ massert( 10327 , "Object does not end with EOO", i.moreWithEOO() );
+ BSONElement e = i.next( true );
+ massert( 10328 , "Invalid element size", e.size() > 0 );
+ massert( 10329 , "Element too large", e.size() < ( 1 << 30 ) );
+ int offset = (int) (e.rawdata() - this->objdata());
+ massert( 10330 , "Element extends past end of object",
+ e.size() + offset <= this->objsize() );
+ bool end = ( e.size() + offset == this->objsize() );
+ if ( e.eoo() ) {
+ massert( 10331 , "EOO Before end of object", end );
+ break;
+ }
+ if ( first )
+ first = false;
+ else
+ s << ", ";
+ e.toString( s, !isArray, full, depth );
+ }
+ s << ( isArray ? " ]" : " }" );
+ }
+
+ std::ostream& operator<<( std::ostream &s, const BSONObj &o ) {
+ return s << o.toString();
+ }
+
+ StringBuilder& operator<<( StringBuilder &s, const BSONObj &o ) {
+ o.toString( s );
+ return s;
+ }
+
+ template <class T>
+ void BSONObj::Vals(std::vector<T>& v) const {
+ BSONObjIterator i(*this);
+ while( i.more() ) {
+ T t;
+ i.next().Val(t);
+ v.push_back(t);
+ }
+ }
+ template <class T>
+ void BSONObj::Vals(std::list<T>& v) const {
+ BSONObjIterator i(*this);
+ while( i.more() ) {
+ T t;
+ i.next().Val(t);
+ v.push_back(t);
+ }
+ }
+
+ template <class T>
+ void BSONObj::vals(std::vector<T>& v) const {
+ BSONObjIterator i(*this);
+ while( i.more() ) {
+ try {
+ T t;
+ i.next().Val(t);
+ v.push_back(t);
+ }
+ catch(...) { }
+ }
+ }
+ template <class T>
+ void BSONObj::vals(std::list<T>& v) const {
+ BSONObjIterator i(*this);
+ while( i.more() ) {
+ try {
+ T t;
+ i.next().Val(t);
+ v.push_back(t);
+ }
+ catch(...) { }
+ }
+ }
+
+
} // namespace mongo
diff --git a/src/mongo/bson/bsonobjbuilder.cpp b/src/mongo/bson/bsonobjbuilder.cpp
index 7f40c2adc3b..c75644c198c 100644
--- a/src/mongo/bson/bsonobjbuilder.cpp
+++ b/src/mongo/bson/bsonobjbuilder.cpp
@@ -192,4 +192,60 @@ namespace mongo {
return false;
}
}
+
+ /* add all the fields from the object specified to this object */
+ BSONObjBuilder& BSONObjBuilder::appendElements(BSONObj x) {
+ if (!x.isEmpty())
+ _b.appendBuf(
+ x.objdata() + 4, // skip over leading length
+ x.objsize() - 5); // ignore leading length and trailing \0
+ return *this;
+ }
+
+ /* add all the fields from the object specified to this object if they don't exist */
+ BSONObjBuilder& BSONObjBuilder::appendElementsUnique(BSONObj x) {
+ std::set<std::string> have;
+ {
+ BSONObjIterator i = iterator();
+ while ( i.more() )
+ have.insert( i.next().fieldName() );
+ }
+
+ BSONObjIterator it(x);
+ while ( it.more() ) {
+ BSONElement e = it.next();
+ if ( have.count( e.fieldName() ) )
+ continue;
+ append(e);
+ }
+ return *this;
+ }
+
+ void BSONObjBuilder::appendKeys( const BSONObj& keyPattern , const BSONObj& values ) {
+ BSONObjIterator i(keyPattern);
+ BSONObjIterator j(values);
+
+ while ( i.more() && j.more() ) {
+ appendAs( j.next() , i.next().fieldName() );
+ }
+
+ verify( ! i.more() );
+ verify( ! j.more() );
+ }
+
+ BSONObjIterator BSONObjBuilder::iterator() const {
+ const char * s = _b.buf() + _offset;
+ const char * e = _b.buf() + _b.len();
+ return BSONObjIterator( s , e );
+ }
+
+ bool BSONObjBuilder::hasField( const StringData& name ) const {
+ BSONObjIterator i = iterator();
+ while ( i.more() )
+ if ( name == i.next().fieldName() )
+ return true;
+ return false;
+ }
+
+
} // namespace mongo
diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h
index 80dce815faf..3495ca9313d 100644
--- a/src/mongo/bson/bsonobjbuilder.h
+++ b/src/mongo/bson/bsonobjbuilder.h
@@ -40,10 +40,10 @@
#include <limits>
#include "mongo/base/parse_number.h"
+#include "mongo/bson/bson_field.h"
#include "mongo/bson/bsonelement.h"
-#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonmisc.h"
-#include "mongo/bson/bson_field.h"
+#include "mongo/bson/bsonobj.h"
#include "mongo/client/export_macros.h"
#if defined(_DEBUG) && defined(MONGO_EXPOSE_MACROS)
@@ -886,6 +886,13 @@ namespace mongo {
inline BSONArrayBuilder& BSONArrayBuilder::append( const std::set< T >& vals ) {
return _appendArrayIt< std::set< T > >( *this, vals );
}
+
+ template <typename T>
+ inline BSONFieldValue<BSONObj> BSONField<T>::query(const char * q, const T& t) const {
+ BSONObjBuilder b;
+ b.append( q , t );
+ return BSONFieldValue<BSONObj>( _name , b.obj() );
+ }
// $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
diff --git a/src/mongo/bson/bsontypes.h b/src/mongo/bson/bsontypes.h
index 3bb6ab22f02..d23ba94c773 100644
--- a/src/mongo/bson/bsontypes.h
+++ b/src/mongo/bson/bsontypes.h
@@ -31,8 +31,6 @@
#include "mongo/util/assert_util.h"
-namespace bson { }
-
namespace mongo {
class BSONArrayBuilder;
diff --git a/src/mongo/client/dbclientinterface.h b/src/mongo/client/dbclientinterface.h
index ecb7390299e..907b5abd416 100644
--- a/src/mongo/client/dbclientinterface.h
+++ b/src/mongo/client/dbclientinterface.h
@@ -35,6 +35,7 @@
#include "mongo/pch.h"
#include "mongo/base/string_data.h"
+#include "mongo/bson/bson_field.h"
#include "mongo/client/export_macros.h"
#include "mongo/db/jsobj.h"
#include "mongo/logger/log_severity.h"
diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp
index be1d76b081b..9b96879b5cb 100644
--- a/src/mongo/client/examples/mongoperf.cpp
+++ b/src/mongo/client/examples/mongoperf.cpp
@@ -56,7 +56,6 @@
using namespace std;
using namespace mongo;
-using namespace bson;
int dummy;
unsigned recSizeKB;
diff --git a/src/mongo/db/auth/privilege_parser.h b/src/mongo/db/auth/privilege_parser.h
index 7c892602032..ac35ff0f114 100644
--- a/src/mongo/db/auth/privilege_parser.h
+++ b/src/mongo/db/auth/privilege_parser.h
@@ -32,6 +32,7 @@
#include <vector>
#include "mongo/base/string_data.h"
+#include "mongo/bson/bson_field.h"
#include "mongo/db/jsobj.h"
#include "mongo/s/bson_serializable.h"
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index 33d5e7da9a5..ccf9c5ffaee 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -63,7 +63,6 @@
namespace mongo {
using namespace html;
- using namespace bson;
struct Timing {
Timing() {
diff --git a/src/mongo/db/jsobj.h b/src/mongo/db/jsobj.h
index 0122b0c53bd..def5c4da503 100644
--- a/src/mongo/db/jsobj.h
+++ b/src/mongo/db/jsobj.h
@@ -51,7 +51,6 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsonobjiterator.h"
-#include "mongo/bson/bson-inl.h"
#include "mongo/bson/ordering.h"
#include "mongo/base/string_data.h"
#include "mongo/bson/bson_db.h"
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index e2bdd1dc066..ff82ffbdb79 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -34,7 +34,6 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsonobjiterator.h"
-#include "mongo/bson/bson-inl.h"
#include "mongo/db/matcher/expression_array.h"
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_tree.h"
diff --git a/src/mongo/db/matcher/expression_parser_tree.cpp b/src/mongo/db/matcher/expression_parser_tree.cpp
index 04a25dac779..01b4ee7a981 100644
--- a/src/mongo/db/matcher/expression_parser_tree.cpp
+++ b/src/mongo/db/matcher/expression_parser_tree.cpp
@@ -33,7 +33,6 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsonobjiterator.h"
-#include "mongo/bson/bson-inl.h"
#include "mongo/db/matcher/expression_array.h"
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/expression_tree.h"
diff --git a/src/mongo/db/matcher/expression_tree.cpp b/src/mongo/db/matcher/expression_tree.cpp
index 95e272c1cb3..d45c84ebeda 100644
--- a/src/mongo/db/matcher/expression_tree.cpp
+++ b/src/mongo/db/matcher/expression_tree.cpp
@@ -34,7 +34,6 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsonobjiterator.h"
-#include "mongo/bson/bson-inl.h"
#include "mongo/util/log.h"
namespace mongo {
diff --git a/src/mongo/db/query/type_explain.h b/src/mongo/db/query/type_explain.h
index a151c78715d..f19b8ca107a 100644
--- a/src/mongo/db/query/type_explain.h
+++ b/src/mongo/db/query/type_explain.h
@@ -31,6 +31,7 @@
#include <string>
#include "mongo/base/string_data.h"
+#include "mongo/bson/bson_field.h"
#include "mongo/s/bson_serializable.h"
namespace mongo {
diff --git a/src/mongo/db/repl/health.cpp b/src/mongo/db/repl/health.cpp
index 960c56267b0..1bc54dbd5ac 100644
--- a/src/mongo/db/repl/health.cpp
+++ b/src/mongo/db/repl/health.cpp
@@ -53,7 +53,6 @@ namespace repl {
mutex ScopedConn::mapMutex("ScopedConn::mapMutex");
using namespace html;
- using namespace bson;
static RamLog * _rsLog = RamLog::get("rs");
Tee* rsLog = _rsLog;
diff --git a/src/mongo/db/repl/heartbeat.cpp b/src/mongo/db/repl/heartbeat.cpp
index 90012ec837c..6fd72d74477 100644
--- a/src/mongo/db/repl/heartbeat.cpp
+++ b/src/mongo/db/repl/heartbeat.cpp
@@ -53,8 +53,6 @@ namespace repl {
MONGO_FP_DECLARE(rsDelayHeartbeatResponse);
- using namespace bson;
-
namespace {
/**
* Returns true if there is no data on this server. Useful when starting replication.
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index 36cfd2a0e31..c77c1761f41 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -40,8 +40,6 @@
#include "mongo/db/repl/rs_config.h"
#include "mongo/db/repl/write_concern.h"
-using namespace bson;
-
namespace mongo {
namespace repl {
diff --git a/src/mongo/db/repl/replset_web_handler.cpp b/src/mongo/db/repl/replset_web_handler.cpp
index 175883e967e..1ab296a59c3 100644
--- a/src/mongo/db/repl/replset_web_handler.cpp
+++ b/src/mongo/db/repl/replset_web_handler.cpp
@@ -38,7 +38,6 @@
namespace mongo {
namespace repl {
- using namespace bson;
using namespace html;
class ReplSetHandler : public DbWebHandler {
diff --git a/src/mongo/db/repl/rs.cpp b/src/mongo/db/repl/rs.cpp
index de4b06fb91a..a007b80f66d 100644
--- a/src/mongo/db/repl/rs.cpp
+++ b/src/mongo/db/repl/rs.cpp
@@ -39,13 +39,9 @@
#include "mongo/db/repl/repl_set_impl.h"
#include "mongo/db/server_parameters.h"
-using namespace std;
-
namespace mongo {
namespace repl {
- using namespace bson;
-
ReplSet *theReplSet = 0;
// This is a bitmask with the first bit set. It's used to mark connections that should be kept
diff --git a/src/mongo/db/repl/rs_config.cpp b/src/mongo/db/repl/rs_config.cpp
index 45db18f0066..0867776d71e 100644
--- a/src/mongo/db/repl/rs_config.cpp
+++ b/src/mongo/db/repl/rs_config.cpp
@@ -45,8 +45,6 @@
#include "mongo/util/net/hostandport.h"
#include "mongo/util/text.h"
-using namespace bson;
-
namespace mongo {
MONGO_LOG_DEFAULT_COMPONENT_FILE(::mongo::logger::LogComponent::kReplication);
diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp
index 72094a53308..0ca30eabd27 100644
--- a/src/mongo/db/repl/rs_initialsync.cpp
+++ b/src/mongo/db/repl/rs_initialsync.cpp
@@ -55,7 +55,6 @@ namespace mongo {
namespace repl {
using namespace mongoutils;
- using namespace bson;
// add try/catch with sleep
diff --git a/src/mongo/db/repl/rs_initiate.cpp b/src/mongo/db/repl/rs_initiate.cpp
index b6a71b438dd..9232e6275fb 100644
--- a/src/mongo/db/repl/rs_initiate.cpp
+++ b/src/mongo/db/repl/rs_initiate.cpp
@@ -53,7 +53,6 @@
#include "mongo/util/mmap.h"
#include "mongo/util/mongoutils/str.h"
-using namespace bson;
using namespace mongoutils;
namespace mongo {
diff --git a/src/mongo/db/repl/rs_initiate.h b/src/mongo/db/repl/rs_initiate.h
index edc4c59d841..c9ff7566d7e 100644
--- a/src/mongo/db/repl/rs_initiate.h
+++ b/src/mongo/db/repl/rs_initiate.h
@@ -29,9 +29,8 @@
#pragma once
namespace mongo {
-namespace bson {
class BSONObjBuilder;
-} // namespace bson
+
namespace repl {
class ReplSetConfig;
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index 32093b02374..4f7f31c81bf 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -89,8 +89,6 @@ namespace mongo {
namespace repl {
- using namespace bson;
-
class RSFatalException : public std::exception {
public:
RSFatalException(std::string m = "replica set fatal exception")
diff --git a/src/mongo/db/repl/rs_sync.cpp b/src/mongo/db/repl/rs_sync.cpp
index b0a16002336..e6ef65ba88f 100644
--- a/src/mongo/db/repl/rs_sync.cpp
+++ b/src/mongo/db/repl/rs_sync.cpp
@@ -58,8 +58,6 @@
namespace mongo {
namespace repl {
- using namespace bson;
-
MONGO_EXPORT_STARTUP_SERVER_PARAMETER(maxSyncSourceLagSecs, int, 30);
MONGO_INITIALIZER(maxSyncSourceLagSecsCheck) (InitializerContext*) {
if (maxSyncSourceLagSecs < 1) {
diff --git a/src/mongo/db/restapi.cpp b/src/mongo/db/restapi.cpp
index cd6619d2d06..031612b59cd 100644
--- a/src/mongo/db/restapi.cpp
+++ b/src/mongo/db/restapi.cpp
@@ -51,7 +51,6 @@ namespace mongo {
bool getInitialSyncCompleted();
- using namespace bson;
using namespace html;
class RESTHandler : public DbWebHandler {
diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp
index 4881461d5e1..43aa6587531 100644
--- a/src/mongo/dbtests/jsobjtests.cpp
+++ b/src/mongo/dbtests/jsobjtests.cpp
@@ -41,6 +41,17 @@
#include "mongo/util/stringutils.h"
namespace mongo {
+ typedef std::map<std::string, BSONElement> BSONMap;
+ BSONMap bson2map(const BSONObj& obj) {
+ BSONMap m;
+ BSONObjIterator it(obj);
+ while (it.more()) {
+ BSONElement e = it.next();
+ m[e.fieldName()] = e;
+ }
+ return m;
+ }
+
void dotted2nested(BSONObjBuilder& b, const BSONObj& obj) {
//use map to sort fields
BSONMap sorted = bson2map(obj);
diff --git a/src/mongo/dbtests/perftests.cpp b/src/mongo/dbtests/perftests.cpp
index d8158d5eb6f..6125b91eeb5 100644
--- a/src/mongo/dbtests/perftests.cpp
+++ b/src/mongo/dbtests/perftests.cpp
@@ -63,8 +63,6 @@
#include <mutex>
#endif
-using namespace bson;
-
namespace PerfTests {
const bool profiling = false;
diff --git a/src/mongo/s/type_chunk.h b/src/mongo/s/type_chunk.h
index 8bbd5ad3a9a..7819025bb71 100644
--- a/src/mongo/s/type_chunk.h
+++ b/src/mongo/s/type_chunk.h
@@ -32,6 +32,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h"
+#include "mongo/bson/bson_field.h"
#include "mongo/db/jsobj.h"
#include "mongo/s/chunk_version.h"
diff --git a/src/mongo/server.h b/src/mongo/server.h
index 157c23d7f7c..0565511b09f 100644
--- a/src/mongo/server.h
+++ b/src/mongo/server.h
@@ -47,8 +47,6 @@
#include "mongo/bson/inline_decls.h"
-//using namespace bson;
-
/* Note: do not clutter code with these -- ONLY use in hot spots / significant loops. */
// branch prediction. indicate we expect to be true