///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSLICEBUILD, "mthSliceBuild" ) INT32 mthSliceBuild( const CHAR *fieldName, const bson::BSONElement &e, _mthSAction *action, bson::BSONObjBuilder &builder ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSLICEBUILD ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; INT32 begin = 0 ; INT32 limit = -1 ; if ( e.eoo() ) { goto done ; } else if ( Array == e.type() ) { action->getSlicePair( begin, limit ) ; _mthSliceIterator i( e.embeddedObject(), begin, limit ) ; BSONArrayBuilder sliceBuilder( builder.subarrayStart( fieldName ) ) ; while ( i.more() ) { sliceBuilder.append( i.next() ) ; } sliceBuilder.doneFast() ; } else { builder.append( e ) ; } done: PD_TRACE_EXITRC( SDB__MTHSLICEBUILD, rc ) ; return rc ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHDEFAULTBUILD, "mthDefaultBuild" ) INT32 mthDefaultBuild( const CHAR *fieldName, const bson::BSONElement &e, _mthSAction *action, bson::BSONObjBuilder &builder ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHDEFAULTBUILD ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; if ( e.eoo() ) { builder.appendAs( action->getValue(), fieldName ) ; } else { builder.append( e ) ; } PD_TRACE_EXITRC( SDB__MTHDEFAULTBUILD, rc ) ; return rc ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHINCLUDEBUILD, "mthIncludeBuild" ) INT32 mthIncludeBuild( const CHAR *fieldName, const bson::BSONElement &e, _mthSAction *action, bson::BSONObjBuilder &builder ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHINCLUDEBUILD ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; if ( !e.eoo() ) { builder.append( e ) ; } PD_TRACE_EXITRC( SDB__MTHINCLUDEBUILD, rc ) ; return rc ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHELEMMATCHBUILDN, "mthElemMatchBuildN" ) static INT32 mthElemMatchBuildN( const CHAR *fieldName, const bson::BSONElement &e, _mthSAction *action, bson::BSONObjBuilder &builder, INT32 n ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHELEMMATCHBUILDN ) ; if ( Array == e.type() ) { BSONArrayBuilder arrayBuilder( builder.subarrayStart( fieldName ) ) ; _mthElemMatchIterator i( e.embeddedObject(), &( action->getMatcher() ), n ) ; do { BSONElement next ; rc = i.next( next ) ; if ( SDB_OK == rc ) { arrayBuilder.append( next ) ; } else if ( SDB_DMS_EOC == rc ) { arrayBuilder.doneFast() ; rc = SDB_OK ; break ; } else { PD_LOG( PDERROR, "failed to get next element:%d", rc ) ; goto error ; } } while ( TRUE ) ; } done: PD_TRACE_EXITRC( SDB__MTHELEMMATCHBUILDN, rc ) ; return rc ; error: goto done ; }
INT32 sptConvertor2::_appendToBson( const std::string &name, const jsval &val, bson::BSONObjBuilder &builder ) { INT32 rc = SDB_OK ; switch (JS_TypeOfValue( _cx, val )) { case JSTYPE_VOID : { /// do nothing. break ; } case JSTYPE_NULL : { builder.appendNull( name ) ; break ; } case JSTYPE_NUMBER : { if ( JSVAL_IS_INT( val ) ) { INT32 iN = 0 ; rc = _toInt( val, iN ) ; if ( SDB_OK != rc ) { goto error ; } builder.appendNumber( name, iN ) ; } else { FLOAT64 fV = 0 ; rc = _toDouble( val, fV ) ; if ( SDB_OK != rc ) { goto error ; } builder.appendNumber( name, fV ) ; } break ; } case JSTYPE_STRING : { std::string str ; rc = _toString( val, str ) ; if ( SDB_OK != rc ) { goto error ; } builder.append( name, str ) ; break ; } case JSTYPE_BOOLEAN : { BOOLEAN bL = TRUE ; rc = _toBoolean( val, bL ) ; if ( SDB_OK != rc ) { goto error ; } builder.appendBool( name, bL ) ; break ; } case JSTYPE_OBJECT : { if ( JSVAL_IS_NULL( val ) ) { builder.appendNull( name ) ; } else { JSObject *obj = JSVAL_TO_OBJECT( val ) ; if ( NULL == obj ) { builder.appendNull( name ) ; } else if ( !_addSpecialObj( obj, name.c_str(), builder ) ) { BSONObj bsonobj ; rc = toBson( obj, bsonobj ) ; if ( SDB_OK != rc ) { goto error ; } if ( JS_IsArrayObject( _cx, obj ) ) { builder.appendArray( name, bsonobj ) ; } else { builder.append( name, bsonobj ) ; } } else { /// do noting } } break ; } case JSTYPE_FUNCTION : { std::string str ; rc = _toString( val, str ) ; if ( SDB_OK != rc ) { goto error ; } builder.appendCode( name, str ) ; break ; } default : { SDB_ASSERT( FALSE, "unexpected type" ) ; rc = SDB_INVALIDARG ; goto error ; } } done: return rc ; error: goto done ; }
BOOLEAN sptConvertor2::_addSpecialObj( JSObject *obj, const CHAR *key, bson::BSONObjBuilder &builder ) { BOOLEAN ret = TRUE ; INT32 rc = SDB_OK ; JSIdArray *properties = JS_Enumerate( _cx, obj ) ; if ( NULL == properties || 0 == properties->length ) { goto error ; } { /// get the first ele jsid id = properties->vector[0] ; jsval fieldName ; std::string name ; if ( !JS_IdToValue( _cx, id, &fieldName )) { goto error ; } rc = _toString( fieldName, name ) ; if ( SDB_OK != rc ) { goto error ; } if ( name.length() <= 1 ) { goto error ; } /// start with '$' if ( SPT_CONVERTOR_SPE_OBJSTART != name.at(0) ) { goto error ; } if ( 0 == name.compare( SPT_SPEOBJ_MINKEY ) && 1 == properties->length ) { jsval value ; if ( !_getProperty( obj, name.c_str(), JSTYPE_NUMBER, value ) ) { goto error ; } builder.appendMinKey( key ) ; } else if ( 0 == name.compare(SPT_SPEOBJ_MAXKEY) && 1 == properties->length ) { jsval value ; if ( !_getProperty( obj, name.c_str(), JSTYPE_NUMBER, value ) ) { goto error ; } builder.appendMaxKey( key ) ; } else if ( 0 == name.compare( SPT_SPEOBJ_OID ) && 1 == properties->length ) { std::string strValue ; jsval value ; if ( !_getProperty( obj, name.c_str(), JSTYPE_STRING, value )) { goto error ; } rc = _toString( value, strValue ) ; if ( SDB_OK != rc ) { goto error ; } if ( 24 != strValue.length() ) { goto error ; } { OID id( strValue ) ; builder.appendOID( key, &id ) ; } } else if ( 0 == name.compare( SPT_SPEOBJ_TIMESTAMP ) && 1 == properties->length ) { std::string strValue ; jsval value ; time_t tm ; UINT64 usec = 0 ; if ( !_getProperty( obj, name.c_str(), JSTYPE_STRING, value )) { goto error ; } rc = _toString( value, strValue ) ; if ( SDB_OK != rc ) { goto error ; } if ( SDB_OK != engine::utilStr2TimeT( strValue.c_str(), tm, &usec )) { goto error ; } { builder.appendTimestamp( key, tm * 1000, usec ) ; } } else if ( 0 == name.compare( SPT_SPEOBJ_DATE ) && 1 == properties->length ) { std::string strValue ; jsval value ; Date_t dt ; UINT64 millis = 0 ; if ( !_getProperty( obj, name.c_str(), JSTYPE_STRING, value )) { goto error ; } rc = _toString( value, strValue ) ; if ( SDB_OK != rc ) { goto error ; } if ( SDB_OK != engine::utilStr2Date( strValue.c_str(), millis ) ) { goto error ; } dt.millis = millis ; builder.appendDate( key, dt ) ; } else if ( 0 == name.compare( SPT_SPEOBJ_REGEX ) && 2 == properties->length ) { std::string optionName ; std::string strRegex, strOption ; jsval jsRegex, jsOption ; jsid optionid = properties->vector[1] ; jsval optionValName ; if ( !JS_IdToValue( _cx, optionid, &optionValName )) { goto error ; } rc = _toString( optionValName, optionName ) ; if ( SDB_OK != rc ) { goto error ; } if ( 0 != optionName.compare( SPT_SPEOBJ_OPTION ) ) { goto error ; } if ( !_getProperty( obj, name.c_str(), JSTYPE_STRING, jsRegex )) { goto error ; } if ( !_getProperty( obj, optionName.c_str(), JSTYPE_STRING, jsOption )) { goto error ; } rc = _toString( jsRegex, strRegex ) ; if ( SDB_OK != rc ) { goto error ; } rc = _toString( jsOption, strOption ) ; if ( SDB_OK != rc ) { goto error ; } builder.appendRegex( key, strRegex, strOption ) ; } else if ( 0 == name.compare( SPT_SPEOBJ_BINARY ) && 2 == properties->length ) { std::string typeName ; std::string strBin, strType ; jsval jsBin, jsType ; jsid typeId = properties->vector[1] ; jsval typeValName ; BinDataType binType ; CHAR *decode = NULL ; INT32 decodeSize = 0 ; if ( !JS_IdToValue( _cx, typeId, &typeValName )) { goto error ; } rc = _toString( typeValName, typeName ) ; if ( SDB_OK != rc ) { goto error ; } if ( 0 != typeName.compare( SPT_SPEOBJ_TYPE ) ) { goto error ; } if ( !_getProperty( obj, name.c_str(), JSTYPE_STRING, jsBin )) { goto error ; } if ( !_getProperty( obj, typeName.c_str(), JSTYPE_STRING, jsType )) { goto error ; } rc = _toString( jsBin, strBin ) ; if ( SDB_OK != rc ) { goto error ; } rc = _toString( jsType, strType ) ; if ( SDB_OK != rc || strType.empty()) { goto error ; } try { binType = (BinDataType)(boost::lexical_cast<INT32>(strType)) ; } catch ( std::bad_cast &e ) { PD_LOG( PDERROR, "invalid bindata type:%s", strType.c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } decodeSize = getDeBase64Size( strBin.c_str() ) ; if( decodeSize < 0 ) { PD_LOG( PDERROR, "invalid bindata %s", strBin.c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } if( decodeSize > 0 ) { decode = ( CHAR * )SDB_OSS_MALLOC( decodeSize ) ; if ( NULL == decode ) { PD_LOG( PDERROR, "failed to allocate mem." ) ; rc = SDB_OOM ; goto error ; } memset ( decode, 0, decodeSize ) ; if ( base64Decode( strBin.c_str(), decode, decodeSize ) < 0 ) { PD_LOG( PDERROR, "failed to decode base64 code" ) ; rc = SDB_INVALIDARG ; SDB_OSS_FREE( decode ) ; goto error ; } builder.appendBinData( key, decodeSize, binType, decode ) ; SDB_OSS_FREE( decode ) ; } else { builder.appendBinData( key, 0, binType, "" ) ; } } else { goto error ; } } done: return ret ; error: ret = FALSE ; goto done ; }