Beispiel #1
0
/**********************************************************
 *see readFromDB in FileRec, similar structure
 * 
***********************************************************/
void VersionRec::readFromDB(mongo::DBClientConnection& conn, string versionID) {

    auto_ptr<mongo::DBClientCursor> cursor =
            conn.query("fileRecords.FileVersion", MONGO_QUERY("_id" << mongo::OID(versionID)));

    if (cursor->more()) {
        //convert to VersionRec
        BSONObj record = cursor->next();
        this->versionid = versionID;
        this->tmpname = record.getStringField("Tempname");
        this->filehash = record.getStringField("filehash");
        this->length = record.getIntField("length");
        this->modifytime.tv_nsec = record.getField("Mtnsec").numberLong();
        this->modifytime.tv_sec = record.getField("mtsec").numberLong();
        this->versionnumber = record.getIntField("Version");

        //similar to the comments collection in readfromDB in FileRec
        vector<BSONElement> hashes(record.getField("Blktable").Array());
        for (vector<BSONElement>::iterator it = hashes.begin(); it != hashes.end(); ++it) {

            BSONObj blockdata = it->Obj();
            BSONElement blocknum = blockdata.getField("Blknum");
            BSONElement blockhash = blockdata.getField("hash");

            VersionDiffBlock tmp;
            tmp.blockNo = blocknum.Int();
            tmp.blockHash = blockhash.String();
            changesAppend(tmp);
        }
    }
    else{
        cout << "could not find version " << versionID << endl;
    }
}
Beispiel #2
0
    // Copies ops out of the bgsync queue into the deque passed in as a parameter.
    // Returns true if the batch should be ended early.
    // Batch should end early if we encounter a command, or if
    // there are no further ops in the bgsync queue to read.
    // This function also blocks 1 second waiting for new ops to appear in the bgsync
    // queue.  We can't block forever because there are maintenance things we need
    // to periodically check in the loop.
    bool SyncTail::tryPopAndWaitForMore(SyncTail::OpQueue* ops, ReplicationCoordinator* replCoord) {
        BSONObj op;
        // Check to see if there are ops waiting in the bgsync queue
        bool peek_success = peek(&op);

        if (!peek_success) {
            // if we don't have anything in the queue, wait a bit for something to appear
            if (ops->empty()) {
                replCoord->signalDrainComplete();
                // block up to 1 second
                _networkQueue->waitForMore();
                return false;
            }

            // otherwise, apply what we have
            return true;
        }

        const char* ns = op["ns"].valuestrsafe();

        // check for commands
        if ((op["op"].valuestrsafe()[0] == 'c') ||
            // Index builds are acheived through the use of an insert op, not a command op.
            // The following line is the same as what the insert code uses to detect an index build.
            ( *ns != '\0' && nsToCollectionSubstring(ns) == "system.indexes" )) {

            if (ops->empty()) {
                // apply commands one-at-a-time
                ops->push_back(op);
                _networkQueue->consume();
            }

            // otherwise, apply what we have so far and come back for the command
            return true;
        }

        // check for oplog version change
        BSONElement elemVersion = op["v"];
        int curVersion = 0;
        if (elemVersion.eoo())
            // missing version means version 1
            curVersion = 1;
        else
            curVersion = elemVersion.Int();
        
        if (curVersion != OPLOG_VERSION) {
            severe() << "expected oplog version " << OPLOG_VERSION << " but found version " 
                     << curVersion << " in oplog entry: " << op;
            fassertFailedNoTrace(18820);
        }
    
        // Copy the op to the deque and remove it from the bgsync queue.
        ops->push_back(op);
        _networkQueue->consume();

        // Go back for more ops
        return false;
    }
Beispiel #3
0
TEST(ExtractBSON, ExtractField) {
    BSONObj obj = BSON("a" << 1 << "b" << "hello");
    BSONElement element;
    ASSERT_OK(bsonExtractField(obj, "a", &element));
    ASSERT_EQUALS(1, element.Int());
    ASSERT_OK(bsonExtractField(obj, "b", &element));
    ASSERT_EQUALS(std::string("hello"), element.str());
    ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractField(obj, "c", &element));
}
Beispiel #4
0
TEST(ExtractBSON, ExtractTypedField) {
    BSONObj obj = BSON("a" << 1 << "b" << "hello");
    BSONElement element;
    ASSERT_OK(bsonExtractTypedField(obj, "a", NumberInt, &element));
    ASSERT_EQUALS(1, element.Int());
    ASSERT_OK(bsonExtractTypedField(obj, "b", String, &element));
    ASSERT_EQUALS(std::string("hello"), element.str());
    ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractTypedField(obj, "c", String, &element));
    ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "a", String, &element));
    ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "b", NumberDouble, &element));
}
Beispiel #5
0
   BOOLEAN omRemoveBusinessCommand::_isDiscoveredBusiness( BSONObj &buzInfo )
   {
      BSONElement eleAddType = buzInfo.getField( OM_BUSINESS_FIELD_ADDTYPE ) ;

      if ( eleAddType.isNumber() &&
           OM_BUSINESS_ADDTYPE_DISCOVERY == eleAddType.Int())
      {
         return TRUE ;
      }

      return FALSE ;
   }
Beispiel #6
0
 void SyncTail::setOplogVersion(const BSONObj& op) {
     BSONElement version = op["v"];
     // old primaries do not get the unique index ignoring feature
     // because some of their ops are not imdepotent, see
     // SERVER-7186
     if (version.eoo()) {
         theReplSet->oplogVersion = 1;
         RARELY log() << "warning replset primary is an older version than we are; upgrade recommended" << endl;
     } else {
         theReplSet->oplogVersion = version.Int();
     }
 }
    // Takes the authentication state from the given BSONObj
    void AuthenticationTable::setFromBSON( const BSONObj& obj ) {
        _dbs.clear();

        BSONObjIterator it( obj );
        while ( it.more() ) {
            BSONElement dbInfo = it.next();
            BSONElement subObj = dbInfo.Obj().firstElement();
            Auth auth;
            auth.user = subObj.fieldName();
            auth.level = static_cast<Auth::Level>(subObj.Int());
            _dbs[dbInfo.fieldName()] = auth;
        }
    }
Beispiel #8
0
/**********************************************************
 *reads from db and converts bson to FileRec object
 * 
***********************************************************/
void FileRec::readFromDB(mongo::DBClientConnection& conn, string filename) {

    boost::filesystem::path p(filename); //get filename from path
    string file(p.filename().c_str());
    auto_ptr<mongo::DBClientCursor> cursor = conn.query("fileRecords.Filerec", MONGO_QUERY("filename" << file));

    if (cursor->more()) {

        BSONObj record = cursor->next();
        //get data from db and store in the FileRec
        this->filename = record.getStringField("filename");
        this->tempname = record.getStringField("Tempname");
        this->recentHash = record.getStringField("curhash");
        this->origHash = record.getStringField("ovhash");
        this->length = record.getIntField("length");
        this->versionCount = record.getIntField("nversions");
        this->modifytime.tv_nsec = record.getField("Mtnsec").numberLong();
        this->modifytime.tv_sec = record.getField("mtsec").numberLong();
        this->refNum = record.getIntField("currentversion");

        vector<BSONElement> hashes(record.getField("FileBlkHashes").Array());
        for (vector<BSONElement>::iterator it = hashes.begin(); it != hashes.end(); ++it) {
            appendBlock((*it).String());
        }

        //comments is an array of objects so it takes a bit of nesting to convert
        vector<BSONElement> array = record["comments"].Array(); //convert to array
        for (vector<BSONElement>::iterator ar = array.begin(); ar != array.end(); ++ar) {
            BSONObj commentdata = ar->Obj(); //store object at array[x] into BSONObj
            BSONElement version = commentdata.getField("version"); //convert
            BSONElement commentdb = commentdata.getField("comment");

            comment data;
            data.comment = commentdb.String();
            data.version = version.Int();
            appendComment(data);
        }


        if (record.hasElement("versionrec")) { //again an array of objects
            vector<BSONElement> array = record["versionrec"].Array();
            for (vector<BSONElement>::iterator it = array.begin(); it != array.end(); ++it) {

                BSONObj versionRecord = it->Obj();
                BSONElement id = versionRecord.getField("id");
                appendVersion(id.String());
            }
        } 
    }
}
Beispiel #9
0
    auto_ptr<DBClientCursor> DBClientReplicaSet::checkSlaveQueryResult( auto_ptr<DBClientCursor> result ){
        BSONObj error;
        bool isError = result->peekError( &error );
        if( ! isError ) return result;

        // We only check for "not master or secondary" errors here

        // If the error code here ever changes, we need to change this code also
        BSONElement code = error["code"];
        if( code.isNumber() && code.Int() == 13436 /* not master or secondary */ ){
            isntSecondary();
            throw DBException( str::stream() << "slave " << _slaveHost.toString() << " is no longer secondary", 14812 );
        }

        return result;
    }
Beispiel #10
0
SafeNum::SafeNum(const BSONElement& element) {
    switch (element.type()) {
        case NumberInt:
            _type = NumberInt;
            _value.int32Val = element.Int();
            break;
        case NumberLong:
            _type = NumberLong;
            _value.int64Val = element.Long();
            break;
        case NumberDouble:
            _type = NumberDouble;
            _value.doubleVal = element.Double();
            break;
        default:
            _type = EOO;
    }
}
Beispiel #11
0
   // PD_TRACE_DECLARE_FUNCTION ( SDB__RTNCONTEXTLOB_OPEN, "_rtnContextLob::open" )
   INT32 _rtnContextLob::open( const BSONObj &lob,
                               BOOLEAN isLocal, 
                               _pmdEDUCB *cb,
                               SDB_DPSCB *dpsCB )
   {
      INT32 rc = SDB_OK ;
      PD_TRACE_ENTRY( SDB__RTNCONTEXTLOB_OPEN ) ;
      BSONElement mode ;
      BSONElement oid ;
      BSONElement fullName = lob.getField( FIELD_NAME_COLLECTION ) ;
      if ( String != fullName.type() )
      {
         PD_LOG( PDERROR, "can not find collection name in lob[%s]",
                 lob.toString( FALSE, TRUE ).c_str() ) ;
         rc = SDB_INVALIDARG ;
         goto error ;
      }

      oid = lob.getField( FIELD_NAME_LOB_OID ) ;
      if ( jstOID != oid.type() )
      {
         PD_LOG( PDERROR, "invalid oid in meta bsonobj:%s",
                 lob.toString( FALSE, TRUE ).c_str() ) ;
         rc = SDB_INVALIDARG ;
         goto error ;
      }

      mode = lob.getField( FIELD_NAME_LOB_OPEN_MODE ) ;
      if ( NumberInt != mode.type() )
      {
         PD_LOG( PDERROR, "invalid mode in meta bsonobj:%s",
                 lob.toString( FALSE, TRUE ).c_str() ) ;
         rc = SDB_INVALIDARG ;
         goto error ;
      }

      if ( isLocal )
      {
         _stream = SDB_OSS_NEW _rtnLocalLobStream() ;
      }
      else
      {
         _stream = SDB_OSS_NEW _rtnCoordLobStream() ;
      }

      if ( NULL == _stream )
      {
         PD_LOG( PDERROR, "failed to allocate mem." ) ;
         rc = SDB_OOM ;
         goto error ;
      }

      _stream->setDPSCB( dpsCB ) ;
      rc = _stream->open( fullName.valuestr(),
                          oid.OID(),
                          mode.Int(), cb ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDERROR, "failed to open lob stream:%d", rc ) ;
         goto error ;
      }

      _isOpened = TRUE ;
      _hitEnd = FALSE ;
   done:
      PD_TRACE_EXITRC( SDB__RTNCONTEXTLOB_OPEN, rc ) ;
      return rc ;
   error:
      goto done ;
   }
Beispiel #12
0
    // Copies ops out of the bgsync queue into the deque passed in as a parameter.
    // Returns true if the batch should be ended early.
    // Batch should end early if we encounter a command, or if
    // there are no further ops in the bgsync queue to read.
    // This function also blocks 1 second waiting for new ops to appear in the bgsync
    // queue.  We can't block forever because there are maintenance things we need
    // to periodically check in the loop.
    bool SyncTail::tryPopAndWaitForMore(SyncTail::OpQueue* ops) {
        BSONObj op;
        // Check to see if there are ops waiting in the bgsync queue
        bool peek_success = peek(&op);

        if (!peek_success) {
            // if we don't have anything in the queue, wait a bit for something to appear
            if (ops->empty()) {
                // block up to 1 second
                _networkQueue->waitForMore();
                return false;
            }

            // otherwise, apply what we have
            return true;
        }

        const char* ns = op["ns"].valuestrsafe();

        // check for commands
        if ((op["op"].valuestrsafe()[0] == 'c') ||
            // Index builds are acheived through the use of an insert op, not a command op.
            // The following line is the same as what the insert code uses to detect an index build.
            ( *ns != '\0' && nsToCollectionSubstring(ns) == "system.indexes" )) {

            if (ops->empty()) {
                // apply commands one-at-a-time
                ops->push_back(op);
                _networkQueue->consume();
            }

            // otherwise, apply what we have so far and come back for the command
            return true;
        }

        // check for oplog version change
        BSONElement elemVersion = op["v"];
        int curVersion = 0;
        if (elemVersion.eoo())
            // missing version means version 1
            curVersion = 1;
        else
            curVersion = elemVersion.Int();

        if (curVersion != oplogVersion) {
            // Version changes cause us to end a batch.
            // If we are starting a new batch, reset version number
            // and continue.
            if (ops->empty()) {
                oplogVersion = curVersion;
            } 
            else {
                // End batch early
                return true;
            }
        }
    
        // Copy the op to the deque and remove it from the bgsync queue.
        ops->push_back(op);
        _networkQueue->consume();

        // Go back for more ops
        return false;
    }
Beispiel #13
0
   INT32 _spdFMP::_extractMsg( BSONObj &msg, BOOLEAN &extracted )
   {
      INT32 rc = SDB_OK ;
      extracted = FALSE ;
      SDB_ASSERT( 0 <= _expect, "impossible" ) ;

      /// magic has already been found.
      if ( sizeof( SPD_MAGIC ) == _expect )
      {
found:
         if ( (_totalRead - _itr) < (INT32)sizeof(INT32) )
         {
            extracted = FALSE ;
            goto done ;
         }
         else
         {
            SINT32 bsonLen = *((SINT32 *)(_readBuf+_itr)) ;
            if ( (_totalRead - _itr) < bsonLen )
            {
               rc = FALSE ;
               goto done ;
            }
            else if ( (_totalRead - _itr) == bsonLen )
            {
               SDB_ASSERT( _itr >= (INT32)sizeof( SPD_MAGIC ) ,
                           "impossible" ) ;
               BSONObj tmp ;

               try
               {
                  tmp = BSONObj( _readBuf + _itr ) ;
               }
               catch ( std::exception &e )
               {
                  PD_LOG( PDERROR, "unexpected err happened:%s", e.what() ) ;
                  rc = SDB_SYS ;
                  goto error ;
               }

               if ( sizeof( SPD_MAGIC ) == _itr )
               {
                  /// only a bson msg.
                  msg = tmp ;
                  extracted = TRUE ;
               }
               else
               {
                  /// not only a bson msg.
                  _readBuf[_itr - 4] = '\0' ;
                  BSONElement retCode = tmp.getField( FMP_RES_CODE ) ;
                  BSONElement errMsg = tmp.getField( FMP_ERR_MSG ) ;

                  /// some code like 'print' may return msg more than a bsonobj.
                  /// we must parse it's return code. if it is ok, we ignore
                  /// print. else we put it into errmsg.
                  if ( !retCode.eoo() && NumberInt != retCode.type() )
                  {
                     rc = SDB_SYS ;
                     PD_LOG( PDERROR,
                             "invalid type of retCode:%d", retCode.type() ) ;
                     goto error ;
                  }
                  else if ( !retCode.eoo() ) 
                  {
                     if ( SDB_OK != retCode.Int() )
                     {
                        if ( !errMsg.eoo() )
                        {
                           msg = tmp ;
                        }
                        else
                        {
                           BSONObjBuilder builder ;
                           builder.append( FMP_ERR_MSG, _readBuf ) ;
                           builder.append( retCode ) ;
                           msg = builder.obj() ;
                        }
                     }
                     else
                     {
                        msg = tmp ;
                     }
                  }
                  else
                  {
                     /// retCode is eoo.
                     msg = tmp ;
                  }

                  extracted = TRUE ;
               }
            }
            else
            {
               SDB_ASSERT( FALSE, "impossible" ) ;
               rc = SDB_SYS ;
               PD_LOG( PDERROR, "left len can not be lager than objsize" ) ;
               goto error ;
            }
         }
      }
      else
      {
         while ( _itr < _totalRead  && (UINT32)_expect < sizeof( SPD_MAGIC ) )
         {
            if ( SPD_MAGIC[_expect] == _readBuf[_itr] )
            {
               ++_itr ;
               ++_expect ;
               if ( sizeof( SPD_MAGIC ) == _expect )
               {
                  goto found ;
               }
            }
            else if ( 0 == _expect )
            {
               ++_itr ;
            }
            else
            {
               _expect = 0 ;
            }
         }
      }

   done:
      return rc ;
   error:
      goto done ;
   }
Beispiel #14
0
static void bson2bamboo(const dclass::DistributedType *type,
                        const BSONElement &element,
                        Datagram &dg)
{
    switch(type->get_type()) {
    case dclass::Type::T_INT8: {
        dg.add_int8(element.Int());
    }
    break;
    case dclass::Type::T_INT16: {
        dg.add_int16(element.Int());
    }
    break;
    case dclass::Type::T_INT32: {
        dg.add_int32(element.Int());
    }
    break;
    case dclass::Type::T_INT64: {
        dg.add_int64(element.Int());
    }
    break;
    case dclass::Type::T_UINT8: {
        dg.add_uint8(element.Int());
    }
    break;
    case dclass::Type::T_UINT16: {
        dg.add_uint16(element.Int());
    }
    break;
    case dclass::Type::T_UINT32: {
        dg.add_uint32(element.Int());
    }
    break;
    case dclass::Type::T_UINT64: {
        dg.add_uint64(element.Int());
    }
    break;
    case dclass::Type::T_CHAR: {
        string str = element.String();
        if(str.size() != 1) {
            throw mongo::DBException("Expected single-length string for char field", 0);
        }
        dg.add_uint8(str[0]);
    }
    break;
    case dclass::Type::T_FLOAT32: {
        dg.add_float32(element.Number());
    }
    break;
    case dclass::Type::T_FLOAT64: {
        dg.add_float64(element.Number());
    }
    break;
    case dclass::Type::T_STRING: {
        dg.add_data(element.String());
    }
    break;
    case dclass::Type::T_VARSTRING: {
        dg.add_string(element.String());
    }
    break;
    case dclass::Type::T_BLOB: {
        int len;
        const uint8_t *rawdata = (const uint8_t *)element.binData(len);
        dg.add_data(rawdata, len);
    }
    break;
    case dclass::Type::T_VARBLOB: {
        int len;
        const uint8_t *rawdata = (const uint8_t *)element.binData(len);
        dg.add_blob(rawdata, len);
    }
    break;
    case dclass::Type::T_ARRAY: {
        const dclass::ArrayType *array = type->as_array();
        std::vector<BSONElement> data = element.Array();

        for(auto it = data.begin(); it != data.end(); ++it) {
            bson2bamboo(array->get_element_type(), *it, dg);
        }
    }
    break;
    case dclass::Type::T_VARARRAY: {
        const dclass::ArrayType *array = type->as_array();
        std::vector<BSONElement> data = element.Array();

        DatagramPtr newdg = Datagram::create();

        for(auto it = data.begin(); it != data.end(); ++it) {
            bson2bamboo(array->get_element_type(), *it, *newdg);
        }

        dg.add_blob(newdg->get_data(), newdg->size());
    }
    break;
    case dclass::Type::T_STRUCT: {
        const dclass::Struct *s = type->as_struct();
        size_t fields = s->get_num_fields();
        for(unsigned int i = 0; i < fields; ++i) {
            const dclass::Field *field = s->get_field(i);
            bson2bamboo(field->get_type(), element[field->get_name()], dg);
        }
    }
    break;
    case dclass::Type::T_METHOD: {
        const dclass::Method *m = type->as_method();
        size_t parameters = m->get_num_parameters();
        for(unsigned int i = 0; i < parameters; ++i) {
            const dclass::Parameter *parameter = m->get_parameter(i);
            string name = parameter->get_name();
            if(name.empty() || element[name].eoo()) {
                stringstream n;
                n << "_" << i;
                name = n.str();
            }
            bson2bamboo(parameter->get_type(), element[name], dg);
        }
    }
    break;
    case dclass::Type::T_INVALID:
    default:
        assert(false);
        break;
    }
}
Beispiel #15
0
INT32 _fmpController::_handleOneLoop( const BSONObj &obj,
                                      INT32 step )
{
   INT32 rc = SDB_OK ;
   BSONObj res ;

   if ( FMP_CONTROL_STEP_BEGIN == step )
   {
      UINT32 seqID = 1 ;
      BSONElement beSeq = obj.getField( FMP_SEQ_ID ) ;
      if ( beSeq.isNumber() )
      {
         seqID = (UINT32)beSeq.numberInt() ;
      }
      BSONElement diag = obj.getField( FMP_DIAG_PATH ) ;
      if ( !diag.eoo() && String == diag.type() )
      {
         CHAR diaglogShort[ OSS_MAX_PATHSIZE + 1 ] = { 0 } ;
         ossSnprintf( diaglogShort, OSS_MAX_PATHSIZE, "%s_%u.%s",
                      PD_FMP_DIAGLOG_PREFIX, seqID, PD_FMP_DIAGLOG_SUBFIX ) ;

         CHAR diaglog[ OSS_MAX_PATHSIZE + 1 ] = {0} ;
         engine::utilBuildFullPath( diag.valuestrsafe(), diaglogShort,
                                    OSS_MAX_PATHSIZE, diaglog ) ;
         sdbEnablePD( diaglog ) ;
      }
      BSONElement localService = obj.getField( FMP_LOCAL_SERVICE ) ;
      if ( !localService.eoo() && String == localService.type() &&
           0 == ossStrlen(FMP_COORD_SERVICE) )
      {
         ossMemcpy( FMP_COORD_SERVICE, localService.valuestrsafe(),
                    ossStrlen( localService.valuestrsafe() ) + 1 ) ;
      }
      BSONElement localUser = obj.getField( FMP_LOCAL_USERNAME ) ;
      if ( String == localUser.type() )
      {
         ossStrncpy( g_UserName, localUser.valuestrsafe(),
                     OSS_MAX_PATHSIZE ) ;
      }
      BSONElement localPass = obj.getField( FMP_LOCAL_PASSWORD ) ;
      if ( String == localPass.type() )
      {
         ossStrncpy( g_Password, localPass.valuestrsafe(),
                     OSS_MAX_PATHSIZE ) ;
      }
      BSONElement fType = obj.getField( FMP_FUNC_TYPE ) ;
      if ( fType.eoo() )
      {
         rc = _createVM( FMP_FUNC_TYPE_JS ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG(PDERROR, "failed to create vm:%d", rc ) ;
            res = BSON( FMP_ERR_MSG << "failed to create vm" <<
                        FMP_RES_CODE << rc ) ;
            goto error ;
         }

         rc = _vm->init( obj ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG(PDERROR, "failed to init vm:%d", rc ) ;
            res = BSON( FMP_ERR_MSG << "failed to init vm" <<
                        FMP_RES_CODE << rc ) ;
            goto error ;
         }
      }
      else if ( NumberInt != fType.type() )
      {
         PD_LOG( PDERROR, "invalid type of func type:%s",
                 fType.toString().c_str() ) ;
         rc = SDB_SYS ;
         res = BSON( FMP_ERR_MSG << "invalid type of func type" <<
                     FMP_RES_CODE << SDB_SYS ) ;
         goto error ;
      }
      else
      {
         rc = _createVM( fType.Int() ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG(PDERROR, "failed to create vm:%d", rc ) ;
            res = BSON( FMP_ERR_MSG << "failed to create vm" <<
                        FMP_RES_CODE << rc ) ;
            goto error ;
         }

         rc = _vm->init( obj ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG(PDERROR, "failed to init vm:%d", rc ) ;
            res = BSON( FMP_ERR_MSG << "failed to init vm" <<
                        FMP_RES_CODE << rc ) ;
            goto error ;
         }
      }
   }
   else if ( FMP_CONTROL_STEP_DOWNLOAD == step )
   {
      SDB_ASSERT( NULL != _vm, "impossible" ) ;
      rc = _vm->eval( obj, res ) ;
      if ( SDB_OK  != rc )
      {
         PD_LOG( PDERROR, "failed to pre eval func:%s, rc:%d",
                 obj.toString(FALSE, TRUE).c_str(), rc ) ;
         if ( res.isEmpty() )
         {
            res = BSON( FMP_ERR_MSG << "failed to pre eval func" <<
                        FMP_RES_CODE << rc ) ;
         }
         goto error ;
      }
   }
   else if ( FMP_CONTROL_STEP_EVAL == step )
   {
      rc = _vm->initGlobalDB( res ) ;
      if ( rc )
      {
         PD_LOG( PDWARNING, "Failed to init global db: %s",
                 res.toString( FALSE, TRUE ).c_str() ) ;
      }

      rc = _vm->eval( obj, res ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDERROR, "failed to eval func:%s, rc:%d",
                 obj.toString(FALSE, TRUE).c_str(), rc ) ;
         if ( res.isEmpty() )
         {
            res = BSON( FMP_ERR_MSG << "failed to eval func" <<
                        FMP_RES_CODE << rc ) ;
         }
         goto error ;
      }
   }
   else if ( FMP_CONTROL_STEP_FETCH == step )
   {
      BSONObj next ;
      rc = _vm->fetch( next ) ;
      if ( !next.isEmpty() )
      {
         res = next ;
      }
      else
      {
         PD_LOG( PDERROR, "a empty obj was fetched out" ) ;
         rc = SDB_SYS ;
         res = BSON( FMP_ERR_MSG << "a empty obj was fetched out" <<
                     FMP_RES_CODE << rc ) ;
         goto error ;
      }

      if ( SDB_DMS_EOC == rc )
      {
         _clear() ;
      }
      else if ( SDB_OK != rc )
      {
         goto error ;
      }
   }
   else
   {
      SDB_ASSERT( FALSE, "impossible" ) ;
   }

done:
   {
   INT32 rrc = SDB_OK ;
   if ( !res.isEmpty() )
   {
      rrc = _writeMsg( res ) ;
   }
   else
   {
      rrc = _writeMsg( BSON( FMP_RES_CODE << rc ) ) ;
   }
   if ( SDB_OK != rrc )
   {
      rc = rrc ;
      PD_LOG( PDERROR, "failed to write msg:%d", rc ) ;
   }
   }
   return rc ;
error:
   goto done ;
}
Beispiel #16
0
INT32 _fmpController::_runLoop()
{
   INT32 rc = SDB_OK ;
   BSONObj obj ;
   BSONElement ele ;

   while ( TRUE )
   {
      INT32 step = FMP_CONTROL_STEP_INVALID ;
      rc = _readMsg( obj ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDERROR, "failed to read msg:%d",rc ) ;
         goto error ;
      }

      ele = obj.getField( FMP_CONTROL_FIELD ) ;
      if ( ele.eoo() )
      {
         step = FMP_CONTROL_STEP_DOWNLOAD ;
      }
      else if ( NumberInt != ele.type() )
      {
         PD_LOG( PDERROR, "failed to find control filed:%s",
                 obj.toString().c_str() ) ;
         rc = SDB_SYS ;
         goto error ;
      }
      else
      {
         step = ele.Int() ;
      }

      if ( FMP_CONTROL_STEP_QUIT == step )
      {
         _clear() ;
         rc = _writeMsg( OK_RES ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG( PDERROR, "failed to write res of reset:%d", rc  ) ;
            goto error ;
         }
         break ;
      }
      else if ( FMP_CONTROL_STEP_RESET == step )
      {
         _clear() ;
         rc = _writeMsg( OK_RES ) ;
         if ( SDB_OK != rc )
         {
            PD_LOG( PDERROR, "failed to write res of reset:%d", rc  ) ;
            goto error ;
         }
         continue ;
      }
      else
      {
      }

      if ( !FMP_VALID_STEP(step) )
      {
         PD_LOG( PDERROR, "invalid step number[%d], now step[%d]",
                 ele.Int(), _step ) ;
         rc = SDB_SYS ;
         goto error ;
      }

      rc = _handleOneLoop( obj, step ) ;
      if ( SDB_OK != rc )
      {
         PD_LOG( PDERROR, "failed to handle one loop:%d", rc) ;
         _clear() ;
      }

      FMP_STEP_AUTO_CHANGE( step ) ;
   }
done:
   return rc ;
error:
   goto done ;
}