BatchedCommandRequest* msgToBatchDelete( const Message& deleteMsg ) { // Parsing DbMessage throws DbMessage dbMsg( deleteMsg ); NamespaceString nss( dbMsg.getns() ); int flags = dbMsg.pullInt(); const BSONObj query = dbMsg.nextJsObj(); int limit = ( flags & RemoveOption_JustOne ) ? 1 : 0; // No exceptions from here on BatchedDeleteDocument* deleteDoc = new BatchedDeleteDocument; deleteDoc->setLimit( limit ); deleteDoc->setQuery( query ); BatchedCommandRequest* request = new BatchedCommandRequest( BatchedCommandRequest::BatchType_Delete ); request->setNS( nss.ns() ); request->getDeleteRequest()->addToDeletes( deleteDoc ); return request; }
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; }