INT32 getIndexesCommand::convertRequest( mongoParser &parser, std::vector<msgBuffer*> &sdbMsgs ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *getIndex = NULL ; bson::BSONObj cond ; bson::BSONObjBuilder obj ; bson::BSONObjBuilder indexObj ; const std::string cmdStr = "$get indexes" ; std::string fullname ; msgBuffer *sdbMsg = SDB_OSS_NEW msgBuffer() ; if ( NULL == sdbMsg ) { rc = SDB_OOM ; goto error ; } parser.opType = OP_CMD_GET_INDEX ; sdbMsg->reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg->advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg->data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; getIndex = ( MsgOpQuery * )sdbMsg->data() ; getIndex->version = 0 ; getIndex->w = 0 ; getIndex->padding = 0 ; getIndex->flags = 0 ; getIndex->nameLength = cmdStr.length() ; parser.skip( parser.nsLen + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; getIndex->numToSkip = 0 ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; getIndex->numToReturn = -1 ; if ( parser.more() ) { parser.nextObj( cond ) ; } indexObj.append( "indexDef.name", cond.getStringField( "index" ) ) ; obj.append( "Collection", cond.getStringField( "ns" ) ) ; sdbMsg->write( cmdStr.c_str(), getIndex->nameLength + 1, TRUE ) ; sdbMsg->write( indexObj.done(), TRUE ) ; sdbMsg->write( fap::emptyObj, TRUE ) ; sdbMsg->write( fap::emptyObj, TRUE ) ; sdbMsg->write( obj.done(), TRUE ) ; header->messageLength = sdbMsg->size() ; sdbMsgs.push_back( sdbMsg ) ; done: return rc ; error: goto done ; }
INT32 updateCommand::convertRequest( mongoParser &parser, std::vector<msgBuffer*> &sdbMsgs ) { INT32 rc = SDB_OK ; INT32 updateFlags = 0 ; MsgHeader *header = NULL ; MsgOpUpdate *update = NULL ; bson::BSONObj cond ; bson::BSONObj updater ; bson::BSONObj hint ; msgBuffer *sdbMsg = SDB_OSS_NEW msgBuffer() ; if ( NULL == sdbMsg ) { rc = SDB_OOM ; goto error ; } parser.opType = OP_UPDATE ; sdbMsg->reverse( sizeof ( MsgOpUpdate ) ) ; sdbMsg->advance( sizeof ( MsgOpUpdate ) - 4 ) ; header = ( MsgHeader * )sdbMsg->data() ; header->opCode = MSG_BS_UPDATE_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; update = ( MsgOpUpdate * )sdbMsg->data() ; update->version = 0 ; update->w = 0 ; update->padding = 0 ; update->flags = 0 ; update->nameLength = parser.nsLen ; parser.skip( update->nameLength + 1 ) ; parser.readNumber( sizeof( INT32 ), (CHAR *)&updateFlags ) ; if ( updateFlags & UPDATE_UPSERT ) { update->flags |= FLG_UPDATE_UPSERT ; } if ( updateFlags & UPDATE_MULTI ) { update->flags |= FLG_UPDATE_MULTIUPDATE ; } if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( cond ) ; if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( updater ) ; hint = cond.getObjectField( "$hint" ) ; hint = removeField( hint, "$hint" ) ; sdbMsg->write( parser.fullName, update->nameLength + 1, TRUE ) ; sdbMsg->write( cond, TRUE ) ; sdbMsg->write( updater, TRUE ) ; sdbMsg->write( hint, TRUE ) ; header->messageLength = sdbMsg->size() ; sdbMsgs.push_back( sdbMsg ) ; done: return rc ; error: goto done ; }
INT32 dropCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *query = NULL ; bson::BSONObj cond ; bson::BSONObj obj ; bson::BSONElement e ; const std::string cmdStr = "$drop collection" ; std::string fullname ; parser.opType = OP_CMD_DROP ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; query = ( MsgOpQuery * )sdbMsg.data() ; query->version = 0 ; query->w = 0 ; query->padding = 0 ; query->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, query->flags ) ; fullname = parser.csName ; query->nameLength = cmdStr.length() ; parser.skip( parser.nsLen + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; query->numToSkip = 0 ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; query->numToReturn = (0 == nToReturn ? -1 : nToReturn) ; if ( 0 > nToReturn ) { query->numToReturn = -nToReturn ; } if ( parser.more() ) { parser.nextObj( cond ) ; } fullname += "." ; fullname += cond.getStringField( "drop" ) ; sdbMsg.write( cmdStr.c_str(), query->nameLength + 1, TRUE ) ; obj = BSON( "Name" << fullname.c_str() ) ; sdbMsg.write( obj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.doneLen() ; return rc ; }
INT32 countCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *query = NULL ; bson::BSONObj all ; bson::BSONObj queryObj ; bson::BSONObj orderby ; bson::BSONObj fields ; bson::BSONObj obj ; bson::BSONElement e ; const std::string cmdStr = "$get count" ; std::string fullname ; parser.opType = OP_CMD_COUNT ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; query = ( MsgOpQuery * )sdbMsg.data() ; query->version = 0 ; query->w = 0 ; query->padding = 0 ; query->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, query->flags ) ; fullname = parser.csName ; query->nameLength = cmdStr.length() ; parser.skip( parser.nsLen + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; query->numToSkip = nToSkip ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; query->numToReturn = nToReturn ; if ( parser.more() ) { parser.nextObj( all ) ; } fullname += "." ; fullname += all.getStringField( "count" ) ; query->nameLength = cmdStr.length() ; sdbMsg.write( cmdStr.c_str(), query->nameLength + 1, TRUE ) ; obj = BSON( "Collection" << fullname.c_str() ) ; queryObj = fap::getCondObj( all ) ; orderby = all.getObjectField( "sort" ) ; if ( all.hasField( "limit" ) ) { query->numToReturn = all.getIntField( "limit" ) ; } if ( all.hasField( "skip" ) ) { query->numToSkip = all.getIntField( "skip" ) ; } sdbMsg.write( queryObj, TRUE ) ; sdbMsg.write( fields, TRUE ) ; sdbMsg.write( orderby, TRUE ) ; sdbMsg.write( obj, TRUE ) ; sdbMsg.doneLen() ; return rc ; }
INT32 queryCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = -1 ; MsgHeader *header = NULL ; MsgOpQuery *query = NULL ; const CHAR *cmdStr = NULL ; command* cmd = NULL ; bson::BSONObj all ; bson::BSONObj cond ; bson::BSONObj selector ; bson::BSONObj orderby ; bson::BSONObj hint ; bson::BSONObj fieldToReturn ; parser.opType = OP_QUERY ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; query = ( MsgOpQuery * )sdbMsg.data() ; query->version = 0 ; query->w = 0 ; query->padding = 0 ; query->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, query->flags ) ; query->nameLength = parser.nsLen ; parser.skip( query->nameLength + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; query->numToSkip = nToSkip ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; query->numToReturn = (0 == nToReturn ? -1 : nToReturn) ; if ( 0 > nToReturn ) { query->numToReturn = -nToReturn ; } if ( parser.more() ) { parser.nextObj( all ) ; } if ( parser.withIndex ) { cmd = commandMgr::instance()->findCommand( "listIndexes" ) ; if ( NULL == cmd ) { rc = SDB_OPTION_NOT_SUPPORT ; parser.opType = OP_CMD_NOT_SUPPORTED ; goto error ; } parser.reparse() ; sdbMsg.zero() ; rc = cmd->convertRequest( parser, sdbMsg ) ; goto done ; } if ( parser.withCmd ) { cmdStr = all.firstElementFieldName() ; cmd = commandMgr::instance()->findCommand( cmdStr ) ; if ( NULL == cmd ) { rc = SDB_OPTION_NOT_SUPPORT ; parser.opType = OP_CMD_NOT_SUPPORTED ; parser.cmdName = cmdStr ; goto error ; } parser.reparse() ; sdbMsg.zero() ; rc = cmd->convertRequest( parser, sdbMsg ) ; goto done ; } cond = fap::getCondObj( all ) ; orderby = all.getObjectField( "orderby" ) ; hint = cond.getObjectField( "$hint" ) ; if ( all.hasField( "limit" ) ) { query->numToReturn = cond.getIntField( "limit" ) ; } if ( all.hasField( "skip" ) ) { query->numToSkip = cond.getIntField( "skip" ) ; } if ( cond.getBoolField("$explain") ) { query->flags |= FLG_QUERY_EXPLAIN ; } if ( parser.more() ) { parser.nextObj( fieldToReturn ) ; } sdbMsg.write( parser.fullName, query->nameLength + 1, TRUE ) ; sdbMsg.write( cond, TRUE ) ; sdbMsg.write( fieldToReturn, TRUE ) ; sdbMsg.write( orderby, TRUE ) ; sdbMsg.write( hint, TRUE ) ; sdbMsg.doneLen() ; done: return rc ; error: goto done ; }
INT32 updateCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturned = 0 ; INT32 updateFlags = 0 ; MsgHeader *header = NULL ; MsgOpUpdate *update = NULL ; bson::BSONObj all ; bson::BSONObj cond ; bson::BSONObj updator ; bson::BSONObj hint ; std::string fullname ; bson::BSONObj obj ; bson::BSONObj subObj ; bson::BSONElement e ; std::vector< bson::BSONElement > objList ; std::vector< bson::BSONElement >::const_iterator cit ; parser.opType = OP_UPDATE ; sdbMsg.reverse( sizeof ( MsgOpUpdate ) ) ; sdbMsg.advance( sizeof ( MsgOpUpdate ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_UPDATE_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; update = ( MsgOpUpdate * )sdbMsg.data() ; update->version = 0 ; update->w = 0 ; update->padding = 0 ; update->flags = 0 ; parser.skip( parser.nsLen + 1 ) ; if ( parser.withCmd ) { parser.skip( sizeof( nToSkip ) + sizeof( nToReturned ) ) ; if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( obj ) ; fullname += parser.csName ; fullname += "." ; fullname += obj.getStringField( "update" ) ; sdbMsg.write( fullname.c_str() , fullname.length() + 1, TRUE ) ; update->nameLength = fullname.length() ; e = obj.getField( "updates" ) ; if ( bson::Array != e.type() ) { rc = SDB_INVALIDARG ; goto error ; } objList = e.Array() ; cit = objList.begin() ; while ( objList.end() != cit ) { subObj = (*cit).Obj() ; all= subObj.getObjectField( "q" ) ;// u , multi upsert cond = fap::getCondObj( all ) ; updator = subObj.getObjectField( "u" ) ; hint = all.getObjectField( "$hint" ) ; BOOLEAN tmp = 0 ; tmp = subObj.getBoolField( "multi" ) ; if ( tmp ) { update->flags |= FLG_UPDATE_MULTIUPDATE ; } tmp = subObj.getBoolField( "upsert" ) ; if ( tmp ) { update->flags |= FLG_UPDATE_UPSERT ; } sdbMsg.write( cond, TRUE ) ; sdbMsg.write( updator, TRUE ) ; sdbMsg.write( hint, TRUE ) ; ++cit ; } } else { update->nameLength = parser.nsLen ; parser.readNumber( sizeof( INT32 ), (CHAR *)&updateFlags ) ; if ( updateFlags & UPDATE_UPSERT ) { update->flags |= FLG_UPDATE_UPSERT ; } if ( updateFlags & UPDATE_MULTI ) { update->flags |= FLG_UPDATE_MULTIUPDATE ; } if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( all ) ; if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( updator ) ; cond = fap::getCondObj( all ) ; hint = all.getObjectField( "$hint" ) ; sdbMsg.write( parser.fullName, update->nameLength + 1, TRUE ) ; sdbMsg.write( cond, TRUE ) ; sdbMsg.write( updator, TRUE ) ; sdbMsg.write( hint, TRUE ) ; } sdbMsg.doneLen() ; done: return rc ; error: goto done ; }
INT32 listIndexesCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *getIndex = NULL ; bson::BSONObj cond ; bson::BSONObj indexObj ; bson::BSONObjBuilder obj ; const std::string cmdStr = "$get indexes" ; std::string fullname ; parser.opType = OP_CMD_GET_INDEX ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; getIndex = ( MsgOpQuery * )sdbMsg.data() ; getIndex->version = 0 ; getIndex->w = 0 ; getIndex->padding = 0 ; getIndex->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, getIndex->flags ) ; getIndex->nameLength = cmdStr.length() ; parser.skip( parser.nsLen + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; getIndex->numToSkip = 0 ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; getIndex->numToReturn = (0 == nToReturn ? -1 : nToReturn) ; if ( 0 > nToReturn ) { getIndex->numToReturn = -nToReturn ; } if ( parser.more() ) { parser.nextObj( cond ) ; } if ( parser.withIndex ) { if ( cond.hasField( "index" ) ) { indexObj = BSON( "indexDef.name" << cond.getStringField( "index" ) ) ; } obj.append( "Collection", cond.getStringField( "ns" ) ) ; } else if ( parser.withCmd ) { parser.opType = OP_CMD_NOT_SUPPORTED ; parser.cmdName = cond.firstElementFieldName() ; fullname = parser.csName ; fullname += "." ; fullname += cond.getStringField( "listIndexes" ) ; obj.append( "Collection", fullname.c_str() ) ; } sdbMsg.write( cmdStr.c_str(), getIndex->nameLength + 1, TRUE ) ; sdbMsg.write( indexObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( obj.obj(), TRUE ) ; sdbMsg.doneLen() ; return rc ; }
INT32 deleteIndexesCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *dropIndex = NULL ; bson::BSONObj cond ; bson::BSONObj obj ; bson::BSONObjBuilder indexObj ; bson::BSONElement e ; const std::string cmdStr = "$drop index" ; std::string fullname ; parser.opType = OP_CMD_DROP_INDEX ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; dropIndex = ( MsgOpQuery * )sdbMsg.data() ; dropIndex->version = 0 ; dropIndex->w = 0 ; dropIndex->padding = 0 ; dropIndex->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, dropIndex->flags ) ; fullname = parser.csName ; dropIndex->nameLength = cmdStr.length() ; parser.skip( parser.nsLen + 1 ) ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; dropIndex->numToSkip = 0 ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; dropIndex->numToReturn = (0 == nToReturn ? -1 : nToReturn) ; if ( 0 > nToReturn ) { dropIndex->numToReturn = -nToReturn ; } if ( parser.more() ) { parser.nextObj( cond ) ; } { std::string clname = cond.getStringField( "deleteIndexes" ) ; if ( clname.empty() ) { clname = cond.getStringField( "dropIndexes" ) ; if ( clname.empty() ) { rc = SDB_INVALIDARG ; goto error ; } } fullname += "." ; fullname += clname ; } indexObj.append( "", cond.getStringField( "index" ) ) ; obj = BSON( "Collection" << fullname.c_str() << "Index" << indexObj.obj() ); sdbMsg.write( cmdStr.c_str(), dropIndex->nameLength + 1, TRUE ) ; sdbMsg.write( obj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.doneLen() ; done: return rc ; error: goto done ; }
INT32 createIndexesCommand::convertRequest( mongoParser &parser, msgBuffer &sdbMsg ) { INT32 rc = SDB_OK ; INT32 nToSkip = 0 ; INT32 nToReturn = 0 ; MsgHeader *header = NULL ; MsgOpQuery *index = NULL ; bson::BSONObj cond ; bson::BSONObj subObj ; bson::BSONElement e ; std::vector< bson::BSONElement > objList ; std::vector< bson::BSONElement >::const_iterator cit ; bson::BSONObjBuilder obj ; bson::BSONObjBuilder indexobj ; const std::string cmdStr = "$create index" ; std::string fullname ; parser.opType = OP_ENSURE_INDEX ; sdbMsg.reverse( sizeof ( MsgOpQuery ) ) ; sdbMsg.advance( sizeof ( MsgOpQuery ) - 4 ) ; header = ( MsgHeader * )sdbMsg.data() ; header->opCode = MSG_BS_QUERY_REQ ; header->TID = 0 ; header->routeID.value = 0 ; header->requestID = parser.id ; index = ( MsgOpQuery * )sdbMsg.data() ; index->version = 0 ; index->w = 0 ; index->padding = 0 ; index->flags = 0 ; fap::setQueryFlags( parser.reservedFlags, index->flags ) ; fullname = parser.csName ; parser.skip( parser.nsLen + 1 ) ; if ( parser.withCmd ) { parser.skip( sizeof( nToSkip ) + sizeof( nToReturn ) ) ; index->numToSkip = 0 ; index->numToReturn = nToReturn <= 0 ? -1 : nToReturn ; if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; }//createIndexes parser.nextObj( cond ) ; index->nameLength = cmdStr.length() ; sdbMsg.write( cmdStr.c_str(), index->nameLength + 1, TRUE ) ; fullname += "." ; fullname += cond.getStringField( "createIndexes" ) ; obj.append( "Collection", fullname.c_str() ) ; e = cond.getField( "indexes" ) ; if ( bson::Array != e.type() ) { rc = SDB_INVALIDARG ; goto error ; } objList = e.Array() ; cit = objList.begin() ; while ( objList.end() != cit ) { subObj = (*cit).Obj() ; indexobj.append( "key", subObj.getObjectField( "key" ) ) ; indexobj.append( "name", subObj.getStringField( "name" ) ) ; indexobj.append("unique", subObj.getBoolField( "unique" ) ) ; obj.append( "Index", indexobj.obj() ) ; sdbMsg.write( obj.obj(), TRUE ) ; ++cit ; } } else { parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToSkip ) ; index->numToSkip = 0 ; parser.readNumber( sizeof( INT32 ), ( CHAR * )&nToReturn ) ; index->numToReturn = (0 == nToReturn ? -1 : nToReturn) ; if ( 0 > nToReturn ) { index->numToReturn = -nToReturn ; } index->nameLength = cmdStr.length() ; sdbMsg.write( cmdStr.c_str(), index->nameLength + 1, TRUE ) ; if ( !parser.more() ) { rc = SDB_INVALIDARG ; goto error ; } parser.nextObj( cond ) ; e = cond.getField( "documents" ) ; if ( bson::Array != e.type() ) { rc = SDB_INVALIDARG ; goto error ; } objList = e.Array() ; cit = objList.begin() ; while ( objList.end() != cit ) { subObj = (*cit).Obj() ; obj.append( "Collection", subObj.getStringField( "ns" ) ) ; indexobj.append( "key", subObj.getObjectField( "key" ) ) ; indexobj.append( "name", subObj.getStringField( "name" ) ) ; indexobj.append("unique", subObj.getBoolField( "unique" ) ) ; obj.append( "Index", indexobj.obj() ) ; sdbMsg.write( obj.obj(), TRUE ) ; ++cit ; } } sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.write( fap::emptyObj, TRUE ) ; sdbMsg.doneLen() ; done: return rc ; error: goto done ; }