///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__MTHRTRIMPARSER_PARSE, "_mthRTrimParser::parse" ) INT32 _mthRTrimParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY(SDB__MTHRTRIMPARSER_PARSE ) ; #if defined (_DEBUG) if ( 0 != _name.compare( e.fieldName() ) ) { PD_LOG( PDERROR, "field name[%s] is not valid", e.fieldName() ) ; rc = SDB_INVALIDARG ; goto error ; } #endif if ( e.eoo() ) { PD_LOG( PDERROR, "invalid element" ) ; rc = SDB_INVALIDARG ; goto error ; } action.setAttribute( MTH_S_ATTR_PROJECTION ) ; action.setFunc( &mthRTrimBuild, &mthRTrimGet ) ; action.setName( _name.c_str() ) ; done: PD_TRACE_EXITRC( SDB__MTHRTRIMPARSER_PARSE, rc ) ; return rc ; error: goto done ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHELEMMATCHONEPARSER_PARSE, "_mthElemMatchOneParser::parse" ) INT32 _mthElemMatchOneParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHELEMMATCHONEPARSER_PARSE ) ; if ( Object != e.type() ) { PD_LOG( PDERROR, "$elemMatch(One) requires object value" ) ; rc = SDB_INVALIDARG ; goto error ; } rc = action.getMatcher().loadPattern( e.embeddedObject() ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to load match pattern:%d", rc ) ; goto error ; } action.setName( _name.c_str() ) ; action.setAttribute( MTH_S_ATTR_PROJECTION ) ; action.setFunc( &mthElemMatchOneBuild, &mthElemMatchOneGet ) ; done: PD_TRACE_EXITRC( SDB__MTHELEMMATCHONEPARSER_PARSE, rc ) ; return rc ; error: goto done ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHELEMMATCHGETN, "mthElemMatchGetN" ) static INT32 mthElemMatchGetN( const CHAR *fieldName, const bson::BSONElement &in, _mthSAction *action, bson::BSONElement &out, INT32 n ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHELEMMATCHGETN ) ; if ( Array == in.type() ) { BSONObjBuilder objBuilder ; BSONArrayBuilder arrayBuilder( objBuilder.subarrayStart( fieldName ) ) ; _mthElemMatchIterator i( in.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 ) ; action->setObj( objBuilder.obj() ) ; out = action->getObj().getField( fieldName ) ; } else { out = BSONElement() ; } done: PD_TRACE_EXITRC( SDB__MTHELEMMATCHGETN, rc ) ; return rc ; error: goto done ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHDEFAULTGET, "mthDefaultGet" ) INT32 mthDefaultGet( const CHAR *fieldName, const bson::BSONElement &in, _mthSAction *action, bson::BSONElement &out ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHDEFAULTGET ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; if ( !in.eoo() ) { out = in ; goto done ; } if ( action->getObj().isEmpty() ) { bson::BSONObjBuilder builder ; builder.appendAs( action->getValue(), fieldName ) ; bson::BSONObj obj = builder.obj() ; action->setObj( builder.obj() ) ; action->setValue( obj.getField( fieldName ) ) ; } out = action->getValue() ; done: PD_TRACE_EXITRC( SDB__MTHDEFAULTGET, rc ) ; return rc ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSACTIONPARSER_GETACTION, "_mthSActionParser::getAction" ) INT32 _mthSActionParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSACTIONPARSER_GETACTION ) ; SDB_ASSERT( !e.eoo(), "can not be invalid" ) ; const CHAR *fieldName = e.fieldName() ; action.clear() ; if ( '$' != *fieldName ) { goto done ; } { PARSERS::const_iterator itr = _parsers.find( fieldName ) ; if ( _parsers.end() == itr ) { PD_LOG( PDERROR, "can not find the parser of action[%s]", fieldName ) ; rc = SDB_INVALIDARG ; goto error ; } rc = itr->second->parse( e, action ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to parse action:%d", rc ) ; goto error ; } } done: PD_TRACE_EXITRC( SDB__MTHSACTIONPARSER_GETACTION, rc ) ; return rc ; error: goto done ; }
///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__MTHSLICEGET, "mthSliceGet" ) INT32 mthSliceGet( const CHAR *fieldName, const bson::BSONElement &in, _mthSAction *action, bson::BSONElement &out ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSLICEGET ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; INT32 begin = 0 ; INT32 limit = -1 ; if ( Array != in.type() ) { out = in ; goto done ; } else if ( Array == in.type() ) { BSONObjBuilder subBuilder ; action->getSlicePair( begin, limit ) ; _mthSliceIterator i( in.embeddedObject(), begin, limit ) ; BSONArrayBuilder sliceBuilder( subBuilder.subarrayStart( fieldName ) ) ; while ( i.more() ) { sliceBuilder.append( i.next() ) ; } sliceBuilder.doneFast() ; action->setObj( subBuilder.obj() ) ; out = action->getObj().getField( fieldName ) ; } done: PD_TRACE_EXITRC( SDB__MTHSLICEGET, 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__MTHINCLUDEPARSER_PARSE, "_mthIncludeParser::parse" ) INT32 _mthIncludeParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHINCLUDEPARSER_PARSE ) ; SDB_ASSERT( !e.eoo(), "can not be eoo" ) ; if ( !e.isNumber() ) { PD_LOG( PDERROR, "invalid element type[%d]", e.type() ) ; rc = SDB_INVALIDARG ; goto error ; } #if defined (_DEBUG) if ( 0 != _name.compare( e.fieldName() ) ) { PD_LOG( PDERROR, "field name[%s] is not valid", e.fieldName() ) ; rc = SDB_INVALIDARG ; goto error ; } #endif action.setName( _name.c_str() ) ; if ( 0 == e.numberLong() ) { action.setAttribute( MTH_S_ATTR_EXCLUDE ) ; } else { action.setAttribute( MTH_S_ATTR_INCLUDE ) ; action.setFunc( &mthIncludeBuild, &mthIncludeGet ) ; } done: PD_TRACE_EXITRC( SDB__MTHINCLUDEPARSER_PARSE, rc ) ; return rc ; error: goto done ; }
UINT32 _utilBSONHasherObsolete::hash( const bson::BSONElement &e ) { UINT32 hashCode = 0 ; HASH_COMBINE( hashCode, e.canonicalType() ) ; switch( e.type() ) { case EOO: case Undefined: case jstNULL: case MaxKey: case MinKey: break ; case Bool: HASH_COMBINE( hashCode, e.boolean() ) ; break ; case Timestamp: { UINT64 v = e._opTime().asDate() ; UINT32 h = hash( &v, sizeof( v ) ) ; HASH_COMBINE( hashCode, h ) ; } break ; case Date: { UINT64 v = e.date().millis ; UINT32 h = hash( &v, sizeof( v ) ) ; HASH_COMBINE( hashCode, h ) ; } break ; case NumberDouble: case NumberLong: case NumberInt: { FLOAT64 dv = e.Number() ; UINT64 uv = dv ; UINT32 afp = ( dv - uv ) * 1000000 ; UINT32 h1 = 0 ; UINT32 h2 = 0 ; h1 = hash( &uv, sizeof( uv ) ) ; h2 = hash( &afp, sizeof( afp ) ) ; HASH_COMBINE( hashCode, h1 ) ; HASH_COMBINE( hashCode, h2 ) ; break ; } case jstOID: HASH_COMBINE( hashCode, hash( e.OID() ) ) ; break ; case Code: case Symbol: case String: HASH_COMBINE( hashCode, hash( e.valuestrsafe(), e.valuestrsize() - 1 ) ) ; break ; case Object: case Array: HASH_COMBINE( hashCode, hash( e.embeddedObject() ) ) ; break ; case DBRef: case BinData: HASH_COMBINE( hashCode, hash( e.value(), e.valuesize() ) ) ; break ; case RegEx: HASH_COMBINE( hashCode, hash( e.regex() ) ) ; HASH_COMBINE( hashCode, hash( e.regexFlags() ) ) ; break ; case CodeWScope: HASH_COMBINE( hashCode, hash( e.codeWScopeCode() ) ) ; HASH_COMBINE( hashCode, hash( e.codeWScopeObject() ) ) ; break ; } return hashCode ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSUBSTRPARSER_PARSE, "_mthSubStrParser::parse" ) INT32 _mthSubStrParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSUBSTRPARSER_PARSE ) ; INT32 begin = 0 ; INT32 limit = -1 ; #if defined (_DEBUG) if ( 0 != _name.compare( e.fieldName() ) ) { PD_LOG( PDERROR, "field name[%s] is not valid", e.fieldName() ) ; rc = SDB_INVALIDARG ; goto error ; } #endif if ( e.isNumber() && 0 <= e.numberInt()) { limit = e.numberInt() ; } else if ( e.isNumber() ) { begin = e.numberInt() ; } else if ( Array == e.type() ) { BSONObjIterator i( e.embeddedObject() ) ; BSONElement ele ; if ( !i.more() ) { goto invalid_arg ; } ele = i.next() ; if ( !ele.isNumber() ) { goto invalid_arg ; } begin = ele.numberInt() ; if ( !i.more() ) { goto invalid_arg ; } ele = i.next() ; if ( !ele.isNumber() ) { goto invalid_arg ; } limit = ele.numberInt() ; } else { PD_LOG( PDERROR, "invalid element" ) ; rc = SDB_INVALIDARG ; goto error ; } action.setAttribute( MTH_S_ATTR_PROJECTION ) ; action.setFunc( &mthSubStrBuild, &mthSubStrGet ) ; action.setName( _name.c_str() ) ; action.setArg( BSON( "arg1" << begin << "arg2" << limit ) ) ; done: PD_TRACE_EXITRC( SDB__MTHSUBSTRPARSER_PARSE, rc ) ; return rc ; error: goto done ; invalid_arg: PD_LOG( PDERROR, "invalid substr argument:%s", e.toString( TRUE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; }