Esempio n. 1
0
    BatchedCommandRequest* msgToBatchUpdate( const Message& updateMsg ) {

        // Parsing DbMessage throws
        DbMessage dbMsg( updateMsg );
        NamespaceString nss( dbMsg.getns() );
        int flags = dbMsg.pullInt();
        bool upsert = flags & UpdateOption_Upsert;
        bool multi = flags & UpdateOption_Multi;
        const BSONObj query = dbMsg.nextJsObj();
        const BSONObj updateExpr = dbMsg.nextJsObj();

        // No exceptions from here on
        BatchedUpdateDocument* updateDoc = new BatchedUpdateDocument;
        updateDoc->setQuery( query );
        updateDoc->setUpdateExpr( updateExpr );
        updateDoc->setUpsert( upsert );
        updateDoc->setMulti( multi );

        BatchedCommandRequest* request =
            new BatchedCommandRequest( BatchedCommandRequest::BatchType_Update );
        request->setNS( nss.ns() );
        request->getUpdateRequest()->addToUpdates( updateDoc );

        return request;
    }
Esempio n. 2
0
bool BatchedCommandRequest::containsNoIDUpsert(const BatchedCommandRequest& request) {
    if (request.getBatchType() != BatchedCommandRequest::BatchType_Update)
        return false;

    const vector<BatchedUpdateDocument*>& updates = request.getUpdateRequest()->getUpdates();

    for (vector<BatchedUpdateDocument*>::const_iterator it = updates.begin(); it != updates.end();
         ++it) {
        const BatchedUpdateDocument* updateDoc = *it;
        if (updateDoc->getUpsert() && updateDoc->getQuery()["_id"].eoo())
            return true;
    }

    return false;
}
Esempio n. 3
0
bool WriteBatchExecutor::applyWriteItem( const BatchedCommandRequest& request,
        int index,
        WriteStats* stats,
        BatchedErrorDetail* error ) {
    const string& ns = request.getNS();

    // Clear operation's LastError before starting.
    _le->reset( true );

    //uint64_t itemTimeMicros = 0;
    bool opSuccess = true;

    // Each write operation executes in its own PageFaultRetryableSection.  This means that
    // a single batch can throw multiple PageFaultException's, which is not the case for
    // other operations.
    PageFaultRetryableSection s;
    while ( true ) {
        try {
            // Execute the write item as a child operation of the current operation.
            CurOp childOp( _client, _client->curop() );

            // TODO Modify CurOp "wrapped" constructor to take an opcode, so calling .reset()
            // is unneeded
            childOp.reset( _client->getRemote(), getOpCode( request.getBatchType() ) );

            childOp.ensureStarted();
            OpDebug& opDebug = childOp.debug();
            opDebug.ns = ns;
            {
                Client::WriteContext ctx( ns );

                switch ( request.getBatchType() ) {
                case BatchedCommandRequest::BatchType_Insert:
                    opSuccess =
                        applyInsert( ns,
                                     request.getInsertRequest()->getDocumentsAt( index ),
                                     &childOp,
                                     stats,
                                     error );
                    break;
                case BatchedCommandRequest::BatchType_Update:
                    opSuccess = applyUpdate( ns,
                                             *request.getUpdateRequest()->getUpdatesAt( index ),
                                             &childOp,
                                             stats,
                                             error );
                    break;
                default:
                    dassert( request.getBatchType() ==
                             BatchedCommandRequest::BatchType_Delete );
                    opSuccess = applyDelete( ns,
                                             *request.getDeleteRequest()->getDeletesAt( index ),
                                             &childOp,
                                             stats,
                                             error );
                    break;
                }
            }
            childOp.done();
            //itemTimeMicros = childOp.totalTimeMicros();

            opDebug.executionTime = childOp.totalTimeMillis();
            opDebug.recordStats();

            // Log operation if running with at least "-v", or if exceeds slow threshold.
            if ( logger::globalLogDomain()->shouldLog( logger::LogSeverity::Debug( 1 ) )
                    || opDebug.executionTime > cmdLine.slowMS + childOp.getExpectedLatencyMs() ) {

                MONGO_TLOG(1) << opDebug.report( childOp ) << endl;
            }

            // TODO Log operation if logLevel >= 3 and assertion thrown (as assembleResponse()
            // does).

            // Save operation to system.profile if shouldDBProfile().
            if ( childOp.shouldDBProfile( opDebug.executionTime ) ) {
                profile( *_client, getOpCode( request.getBatchType() ), childOp );
            }
            break;
        }
        catch ( PageFaultException& e ) {
            e.touch();
        }
    }

    return opSuccess;
}