static bool areResponsesEqual( const BatchedCommandResponse& responseA, const BatchedCommandResponse& responseB ) { // TODO: Better reporting of why not equal if ( responseA.getOk() != responseB.getOk() ) return false; if ( responseA.getN() != responseB.getN() ) return false; if ( responseA.isSingleUpsertedSet() != responseB.isSingleUpsertedSet() ) return false; if ( responseA.isUpsertDetailsSet() != responseB.isUpsertDetailsSet() ) return false; if ( responseA.isSingleUpsertedSet() ) { BSONObj upsertA = responseA.getSingleUpserted(); BSONObj upsertB = responseB.getSingleUpserted(); if ( upsertA.woCompare( upsertB ) != 0 ) return false; } if ( responseA.isUpsertDetailsSet() ) { // TODO: } if ( responseA.getOk() ) return true; // TODO: Compare errors here return true; }
void batchErrorToLastError( const BatchedCommandRequest& request, const BatchedCommandResponse& response, LastError* error ) { scoped_ptr<BatchedErrorDetail> topLevelError; BatchedErrorDetail* lastBatchError = NULL; if ( !response.getOk() ) { int code = response.getErrCode(); // Check for batch error // We don't care about write concern errors, these happen in legacy mode in GLE if ( code != ErrorCodes::WriteConcernFailed && !response.isErrDetailsSet() ) { // Top-level error, all writes failed topLevelError.reset( new BatchedErrorDetail ); buildErrorFromResponse( response, topLevelError.get() ); lastBatchError = topLevelError.get(); } else if ( response.isErrDetailsSet() ) { // The last error in the batch is always reported - this matches expected COE // semantics for insert batches and works for single writes lastBatchError = response.getErrDetails().back(); } } // Record an error if one exists if ( lastBatchError ) { error->raiseError( lastBatchError->getErrCode(), lastBatchError->getErrMessage().c_str() ); return; } // Record write stats otherwise // NOTE: For multi-write batches, our semantics change a little because we don't have // un-aggregated "n" stats. if ( request.getBatchType() == BatchedCommandRequest::BatchType_Update ) { BSONObj upsertedId; if ( response.isSingleUpsertedSet() ) upsertedId = response.getSingleUpserted(); else if( response.isUpsertDetailsSet() ) { // Only report the very last item's upserted id if applicable if ( response.getUpsertDetails().back()->getIndex() + 1 == static_cast<int>( request.sizeWriteOps() ) ) { upsertedId = response.getUpsertDetails().back()->getUpsertedID(); } } int numUpserted = 0; if ( response.isSingleUpsertedSet() ) ++numUpserted; else if ( response.isUpsertDetailsSet() ) numUpserted += response.sizeUpsertDetails(); int numUpdated = response.getN() - numUpserted; dassert( numUpdated >= 0 ); error->recordUpdate( numUpdated > 0, response.getN(), upsertedId ); } else if ( request.getBatchType() == BatchedCommandRequest::BatchType_Delete ) { error->recordDelete( response.getN() ); } }