Beispiel #1
0
    void append( BSONObjBuilder& b , string name , jsval val , BSONType oldType = EOO , int depth=0 ) {
        //cout << "name: " << name << "\t" << typeString( val ) << " oldType: " << oldType << endl;
        switch ( JS_TypeOfValue( _context , val ) ) {

        case JSTYPE_VOID:
            b.appendUndefined( name.c_str() );
            break;
        case JSTYPE_NULL:
            b.appendNull( name.c_str() );
            break;

        case JSTYPE_NUMBER: {
            double d = toNumber( val );
            if ( oldType == NumberInt && ((int)d) == d )
                b.append( name.c_str() , (int)d );
            else
                b.append( name.c_str() , d );
            break;
        }
        case JSTYPE_STRING:
            b.append( name.c_str() , toString( val ) );
            break;
        case JSTYPE_BOOLEAN:
            b.appendBool( name.c_str() , toBoolean( val ) );
            break;

        case JSTYPE_OBJECT: {
            JSObject * o = JSVAL_TO_OBJECT( val );
            if ( ! o || o == JSVAL_NULL ) {
                b.appendNull( name.c_str() );
            }
            else if ( ! appendSpecialDBObject( this , b , name , val , o ) ) {
                BSONObj sub = toObject( o , depth );
                if ( JS_IsArrayObject( _context , o ) ) {
                    b.appendArray( name.c_str() , sub );
                }
                else {
                    b.append( name.c_str() , sub );
                }
            }
            break;
        }

        case JSTYPE_FUNCTION: {
            string s = toString(val);
            if ( s[0] == '/' ) {
                appendRegex( b , name , s );
            }
            else {
                b.appendCode( name.c_str() , getFunctionCode( val ).c_str() );
            }
            break;
        }

        default:
            uassert( 10217 ,  (string)"can't append field.  name:" + name + " type: " + typeString( val ) , 0 );
        }
    }
Beispiel #2
0
    BtreeKeyGeneratorV1::BtreeKeyGeneratorV1(vector<const char*> fieldNames,
                                             vector<BSONElement> fixed, bool isSparse)
        : BtreeKeyGenerator(fieldNames, fixed, isSparse) {

        BSONObjBuilder b;
        b.appendUndefined( "" );
        _undefinedObj = b.obj();
        _undefinedElt = _undefinedObj.firstElement();
    }
Beispiel #3
0
    void IndexSpec::_init() {
        verify( keyPattern.objsize() );

        // some basics
        _nFields = keyPattern.nFields();
        _sparse = info["sparse"].trueValue();
        uassert( 13529 , "sparse only works for single field keys" , ! _sparse || _nFields );


        {
            // build _nullKey

            BSONObjBuilder b;
            BSONObjIterator i( keyPattern );

            while( i.more() ) {
                BSONElement e = i.next();
                _fieldNames.push_back( e.fieldName() );
                _fixed.push_back( BSONElement() );
                b.appendNull( "" );
            }
            _nullKey = b.obj();
        }

        {
            // _nullElt
            BSONObjBuilder b;
            b.appendNull( "" );
            _nullObj = b.obj();
            _nullElt = _nullObj.firstElement();
        }

        {
            // _undefinedElt
            BSONObjBuilder b;
            b.appendUndefined( "" );
            _undefinedObj = b.obj();
            _undefinedElt = _undefinedObj.firstElement();
        }
        
        {
            // handle plugins
            string pluginName = IndexPlugin::findPluginName( keyPattern );
            if ( pluginName.size() ) {
                IndexPlugin * plugin = IndexPlugin::get( pluginName );
                if ( ! plugin ) {
                    log() << "warning: can't find plugin [" << pluginName << "]" << endl;
                }
                else {
                    _indexType.reset( plugin->generate( this ) );
                }
            }
        }

        _finishedInit = true;
    }
Beispiel #4
0
    static BSONObj native_sleep( const mongo::BSONObj& args, void* data ) {
        uassert( 16259,
                 "sleep takes a single numeric argument -- sleep(milliseconds)",
                 args.nFields() == 1 && args.firstElement().isNumber() );
        sleepmillis( static_cast<long long>( args.firstElement().number() ) );

        BSONObjBuilder b;
        b.appendUndefined( "" );
        return b.obj();
    }
Beispiel #5
0
   /*
      IXM Tool functions
   */
   BSONObj ixmGetUndefineKeyObj( INT32 fieldNum )
   {
      static BSONObj s_undefineKeys[ IXM_MAX_PREALLOCATED_UNDEFKEY ] ;
      static BOOLEAN s_init = FALSE ;
      static ossSpinXLatch s_latch ;

      if ( FALSE == s_init )
      {
         s_latch.get() ;
         if ( FALSE == s_init )
         {
            for ( SINT32 i = 0; i < IXM_MAX_PREALLOCATED_UNDEFKEY ; ++i )
            {
               BSONObjBuilder b ;
               for ( SINT32 j = 0; j <= i; ++j )
               {
                  b.appendUndefined("") ;
               }
               s_undefineKeys[i] = b.obj() ;
            }
            s_init = TRUE ;
         }
         s_latch.release() ;
      }

      if ( fieldNum > 0 && fieldNum <= IXM_MAX_PREALLOCATED_UNDEFKEY )
      {
         return s_undefineKeys[ fieldNum - 1 ] ;
      }
      else
      {
         BSONObjBuilder b ;
         for ( INT32 i = 0; i < fieldNum; ++i )
         {
            b.appendUndefined("") ;
         }
         return b.obj() ;
      }
   }
Beispiel #6
0
 void S2AccessMethod::getLiteralKeysArray(const BSONObj& obj, BSONObjSet* out) const {
     BSONObjIterator objIt(obj);
     if (!objIt.more()) {
         // Empty arrays are indexed as undefined.
         BSONObjBuilder b;
         b.appendUndefined("");
         out->insert(b.obj());
     } else {
         // Non-empty arrays are exploded.
         while (objIt.more()) {
             BSONObjBuilder b;
             b.appendAs(objIt.next(), "");
             out->insert(b.obj());
         }
     }
 }
Beispiel #7
0
BSONObj makeUndefined() {
    BSONObjBuilder b;
    b.appendUndefined( "" );
    return b.obj();
}
Beispiel #8
0
    void v8ToMongoElement( BSONObjBuilder & b , v8::Handle<v8::String> name , const string sname , v8::Handle<v8::Value> value ){
        
        if ( value->IsString() ){
            b.append( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
        
        if ( value->IsFunction() ){
            b.appendCode( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
    
        if ( value->IsNumber() ){
            if ( value->IsInt32() )
                b.append( sname.c_str(), int( value->ToInt32()->Value() ) );
            else
                b.append( sname.c_str() , value->ToNumber()->Value() );
            return;
        }
    
        if ( value->IsArray() ){
            BSONObj sub = v8ToMongo( value->ToObject() );
            b.appendArray( sname.c_str() , sub );
            return;
        }
    
        if ( value->IsDate() ){
            b.appendDate( sname.c_str() , Date_t(v8::Date::Cast( *value )->NumberValue()) );
            return;
        }

        if ( value->IsExternal() )
            return;
        
        if ( value->IsObject() ){
            // The user could potentially modify the fields of these special objects,
            // wreaking havoc when we attempt to reinterpret them.  Not doing any validation
            // for now...
            Local< v8::Object > obj = value->ToObject();
            if ( obj->InternalFieldCount() && obj->GetInternalField( 0 )->IsNumber() ) {
                switch( obj->GetInternalField( 0 )->ToInt32()->Value() ) { // NOTE Uint32's Value() gave me a linking error, so going with this instead
                    case Timestamp:
                        b.appendTimestamp( sname.c_str(),
                                          Date_t( v8::Date::Cast( *obj->Get( v8::String::New( "time" ) ) )->NumberValue() ),
                                          obj->Get( v8::String::New( "i" ) )->ToInt32()->Value() );
                        return;
                    case MinKey:
                        b.appendMinKey( sname.c_str() );
                        return;
                    case MaxKey:
                        b.appendMaxKey( sname.c_str() );
                        return;
                    default:
                        assert( "invalid internal field" == 0 );
                }
            }
            string s = toSTLString( value );
            if ( s.size() && s[0] == '/' ){
                s = s.substr( 1 );
                string r = s.substr( 0 , s.rfind( "/" ) );
                string o = s.substr( s.rfind( "/" ) + 1 );
                b.appendRegex( sname.c_str() , r.c_str() , o.c_str() );
            }
            else if ( value->ToObject()->GetPrototype()->IsObject() &&
                      value->ToObject()->GetPrototype()->ToObject()->HasRealNamedProperty( v8::String::New( "isObjectId" ) ) ){
                OID oid;
                oid.init( toSTLString( value ) );
                b.appendOID( sname.c_str() , &oid );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__NumberLong" ) ).IsEmpty() ) {
                // TODO might be nice to potentially speed this up with an indexed internal
                // field, but I don't yet know how to use an ObjectTemplate with a
                // constructor.
                unsigned long long val =
                ( (unsigned long long)( value->ToObject()->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
                (unsigned)( value->ToObject()->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
                b.append( sname.c_str(), (long long)val );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) {
                OID oid;
                oid.init( toSTLString( value->ToObject()->Get( v8::String::New( "id" ) ) ) );
                string ns = toSTLString( value->ToObject()->Get( v8::String::New( "ns" ) ) );
                b.appendDBRef( sname.c_str(), ns.c_str(), oid );                
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__BinData" ) ).IsEmpty() ) {
                int len = obj->Get( v8::String::New( "len" ) )->ToInt32()->Value();
                v8::String::Utf8Value data( obj->Get( v8::String::New( "data" ) ) );
                const char *dataArray = *data;
                assert( data.length() == len );
                b.appendBinData( sname.c_str(),
                                len,
                                mongo::BinDataType( obj->Get( v8::String::New( "type" ) )->ToInt32()->Value() ),
                                dataArray );
            } else {
                BSONObj sub = v8ToMongo( value->ToObject() );
                b.append( sname.c_str() , sub );
            }
            return;
        }
    
        if ( value->IsBoolean() ){
            b.appendBool( sname.c_str() , value->ToBoolean()->Value() );
            return;
        }
    
        else if ( value->IsUndefined() ){
            b.appendUndefined( sname.c_str() );
            return;
        }
    
        else if ( value->IsNull() ){
            b.appendNull( sname.c_str() );
            return;
        }

        cout << "don't know how to convert to mongo field [" << name << "]\t" << value << endl;
    }