void BatchSafeWriter::safeWriteBatch( DBClientBase* conn, const BatchedCommandRequest& request, BatchedCommandResponse* response ) { // N starts at zero, and we add to it for each item response->setN( 0 ); for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) { BatchItemRef itemRef( &request, static_cast<int>( i ) ); LastError lastError; _safeWriter->safeWrite( conn, itemRef, &lastError ); // Register the error if we need to BatchedErrorDetail* batchError = lastErrorToBatchError( lastError ); if ( batchError ) { batchError->setIndex( i ); response->addToErrDetails( batchError ); } response->setN( response->getN() + lastError.nObjects ); if ( !lastError.upsertedId.isEmpty() ) { BatchedUpsertDetail* upsertedId = new BatchedUpsertDetail; upsertedId->setIndex( i ); upsertedId->setUpsertedID( lastError.upsertedId ); response->addToUpsertDetails( upsertedId ); } // Break on first error if we're ordered if ( request.getOrdered() && BatchSafeWriter::isFailedOp( lastError ) ) break; } if ( request.sizeWriteOps() == 1 && response->isErrDetailsSet() && !response->isErrCodeSet() ) { // Promote single error to batch error const BatchedErrorDetail* error = response->getErrDetailsAt( 0 ); response->setErrCode( error->getErrCode() ); if ( error->isErrInfoSet() ) response->setErrInfo( error->getErrInfo() ); response->setErrMessage( error->getErrMessage() ); response->unsetErrDetails(); } if ( request.sizeWriteOps() == 1 && response->isUpsertDetailsSet() ) { // Promote single upsert to batch upsert const BatchedUpsertDetail* upsertedId = response->getUpsertDetailsAt( 0 ); response->setSingleUpserted( upsertedId->getUpsertedID() ); response->unsetUpsertDetails(); } response->setOk( !response->isErrCodeSet() ); dassert( response->isValid( NULL ) ); }
void HTMLElement::getItemRefElements(Vector<HTMLElement*>& itemRefElements) { if (!fastHasAttribute(itemscopeAttr)) return; if (!fastHasAttribute(itemrefAttr) || !itemRef()->length()) { itemRefElements.append(this); return; } DOMSettableTokenList* itemRefs = itemRef(); RefPtr<DOMSettableTokenList> processedItemRef = DOMSettableTokenList::create(); Node* rootNode; if (inDocument()) rootNode = document(); else { rootNode = this; while (Node* parent = rootNode->parentNode()) rootNode = parent; } for (Node* current = rootNode; current; current = NodeTraversal::next(current, rootNode)) { if (!current->isHTMLElement()) continue; HTMLElement* element = toHTMLElement(current); if (element == this) { itemRefElements.append(element); continue; } const AtomicString& id = element->getIdAttribute(); if (!processedItemRef->tokens().contains(id) && itemRefs->tokens().contains(id)) { processedItemRef->setValue(id); if (!element->isDescendantOf(this)) itemRefElements.append(element); } } }
void BatchSafeWriter::safeWriteBatch( DBClientBase* conn, const BatchedCommandRequest& request, BatchedCommandResponse* response ) { for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) { BatchItemRef itemRef( &request, static_cast<int>( i ) ); LastError lastError; _safeWriter->safeWrite( conn, itemRef, &lastError ); // Register the error if we need to BatchedErrorDetail* batchError = lastErrorToBatchError( lastError ); batchError->setIndex( i ); response->addToErrDetails( batchError ); // TODO: Other stats, etc. // Break on first error if we're ordered if ( request.getOrdered() && BatchSafeWriter::isFailedOp( lastError ) ) break; } }
/** \brief Populate a displayed menu * * This method peruses an array of menu items, calling the pure virtual methods * which the derived class should build a displayed menu. * * \param[in] path Path to this menu * \param[in] array An array of menu items * * \sa PopulateMenu */ void moMenuManager::PopulateMenu( const moWCString& path, moPropArrayRef array ) { const moNamePool& pool = moNamePool::GetNamePool(); const mo_name_t menuName = pool.Get("Menu"); const mo_name_t itemName = pool.Get("Item"); const mo_name_t sepName = pool.Get("Separator"); //const mo_name_t tbName = pool.Get("Toolbar"); unsigned long idx = 0; const unsigned long end = array.CountIndexes(); for( ; idx < end; idx++ ) { moPropSPtr itemProp = array.GetAtIndex( idx ); moProp::prop_type_t type = itemProp->GetType(); moName name = itemProp->GetName(); mo_name_t name_t = (mo_name_t) name; switch( type ) { case moProp::MO_PROP_TYPE_PROP_BAG: { moPropBagRef itemRef(name); itemRef.NewProp(); itemRef.GetProperty()->Copy(*itemProp); moMenuItemSPtr menu_item = new moMenuItem( itemRef ); if( name_t == menuName ) { // Signal menu start // Menu( path, menu_item ); // Populate the menu // moWCString item_name( menu_item->Value("Name") ); moWCString p = path + "/" + item_name; PopulateMenu( p, itemRef ); // Signal menu finish // EndMenu( path, menu_item ); } else if( name_t == itemName ) { Item( path, menu_item ); } else if( name_t == sepName ) { menu_item->IsSeparator( true ); Separator( path, menu_item ); } } break; default: std::cerr << "PopulateMenu(): Unsupported property type for this structure!" << std::endl; } } }
void BatchSafeWriter::safeWriteBatch( DBClientBase* conn, const BatchedCommandRequest& request, BatchedCommandResponse* response ) { const NamespaceString nss( request.getNS() ); // N starts at zero, and we add to it for each item response->setN( 0 ); for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) { // Break on first error if we're ordered if ( request.getOrdered() && response->isErrDetailsSet() ) break; BatchItemRef itemRef( &request, static_cast<int>( i ) ); bool isLastItem = ( i == request.sizeWriteOps() - 1 ); BSONObj writeConcern; if ( isLastItem && request.isWriteConcernSet() ) { writeConcern = request.getWriteConcern(); // Pre-2.4.2 mongods react badly to 'w' being set on config servers if ( nss.db() == "config" ) writeConcern = fixWCForConfig( writeConcern ); } BSONObj gleResult; GLEErrors errors; Status status = _safeWriter->safeWrite( conn, itemRef, writeConcern, &gleResult ); if ( status.isOK() ) { status = extractGLEErrors( gleResult, &errors ); } if ( !status.isOK() ) { response->clear(); response->setOk( false ); response->setErrCode( status.code() ); response->setErrMessage( status.reason() ); return; } // // STATS HANDLING // GLEStats stats; extractGLEStats( gleResult, &stats ); // Special case for making legacy "n" field result for insert match the write // command result. if ( request.getBatchType() == BatchedCommandRequest::BatchType_Insert && !errors.writeError.get() ) { // n is always 0 for legacy inserts. dassert( stats.n == 0 ); stats.n = 1; } response->setN( response->getN() + stats.n ); if ( !stats.upsertedId.isEmpty() ) { BatchedUpsertDetail* upsertedId = new BatchedUpsertDetail; upsertedId->setIndex( i ); upsertedId->setUpsertedID( stats.upsertedId ); response->addToUpsertDetails( upsertedId ); } response->setLastOp( stats.lastOp ); // // WRITE ERROR HANDLING // // If any error occurs (except stale config) the previous GLE was not enforced bool enforcedWC = !errors.writeError.get() || errors.writeError->getErrCode() == ErrorCodes::StaleShardVersion; // Save write error if ( errors.writeError.get() ) { errors.writeError->setIndex( i ); response->addToErrDetails( errors.writeError.release() ); } // // WRITE CONCERN ERROR HANDLING // // The last write is weird, since we enforce write concern and check the error through // the same GLE if possible. If the last GLE was an error, the write concern may not // have been enforced in that same GLE, so we need to send another after resetting the // error. if ( isLastItem ) { // Try to enforce the write concern if everything succeeded (unordered or ordered) // OR if something succeeded and we're unordered. bool needToEnforceWC = !response->isErrDetailsSet() || ( !request.getOrdered() && response->sizeErrDetails() < request.sizeWriteOps() ); if ( !enforcedWC && needToEnforceWC ) { dassert( !errors.writeError.get() ); // emptied above // Might have gotten a write concern validity error earlier, these are // enforced even if the wc isn't applied, so we ignore. errors.wcError.reset(); Status status = _safeWriter->enforceWriteConcern( conn, nss.db().toString(), writeConcern, &gleResult ); if ( status.isOK() ) { status = extractGLEErrors( gleResult, &errors ); } if ( !status.isOK() ) { response->clear(); response->setOk( false ); response->setErrCode( status.code() ); response->setErrMessage( status.reason() ); return; } } // END Write concern retry if ( errors.wcError.get() ) { response->setWriteConcernError( errors.wcError.release() ); } } } response->setOk( true ); dassert( response->isValid( NULL ) ); }
void BatchSafeWriter::safeWriteBatch( DBClientBase* conn, const BatchedCommandRequest& request, BatchedCommandResponse* response ) { const NamespaceString nss( request.getNS() ); // N starts at zero, and we add to it for each item response->setN( 0 ); // GLE path always sets nModified to -1 (sentinel) to indicate we should omit it later. response->setNModified(-1); for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) { // Break on first error if we're ordered if ( request.getOrdered() && response->isErrDetailsSet() ) break; BatchItemRef itemRef( &request, static_cast<int>( i ) ); BSONObj gleResult; GLEErrors errors; Status status = _safeWriter->safeWrite( conn, itemRef, WriteConcernOptions::Acknowledged, &gleResult ); if ( status.isOK() ) { status = extractGLEErrors( gleResult, &errors ); } if ( !status.isOK() ) { response->clear(); response->setOk( false ); response->setErrCode( ErrorCodes::RemoteResultsUnavailable ); StringBuilder builder; builder << "could not get write error from safe write"; builder << causedBy( status.toString() ); response->setErrMessage( builder.str() ); return; } if ( errors.wcError.get() ) { response->setWriteConcernError( errors.wcError.release() ); } // // STATS HANDLING // GLEStats stats; extractGLEStats( gleResult, &stats ); // Special case for making legacy "n" field result for insert match the write // command result. if ( request.getBatchType() == BatchedCommandRequest::BatchType_Insert && !errors.writeError.get() ) { // n is always 0 for legacy inserts. dassert( stats.n == 0 ); stats.n = 1; } response->setN( response->getN() + stats.n ); if ( !stats.upsertedId.isEmpty() ) { BatchedUpsertDetail* upsertedId = new BatchedUpsertDetail; upsertedId->setIndex( i ); upsertedId->setUpsertedID( stats.upsertedId ); response->addToUpsertDetails( upsertedId ); } response->setLastOp( stats.lastOp ); // Save write error if ( errors.writeError.get() ) { errors.writeError->setIndex( i ); response->addToErrDetails( errors.writeError.release() ); } } // // WRITE CONCERN ERROR HANDLING // // The last write is weird, since we enforce write concern and check the error through // the same GLE if possible. If the last GLE was an error, the write concern may not // have been enforced in that same GLE, so we need to send another after resetting the // error. BSONObj writeConcern; if ( request.isWriteConcernSet() ) { writeConcern = request.getWriteConcern(); // Pre-2.4.2 mongods react badly to 'w' being set on config servers if ( nss.db() == "config" ) writeConcern = fixWCForConfig( writeConcern ); } bool needToEnforceWC = WriteConcernOptions::Acknowledged.woCompare(writeConcern) != 0 && WriteConcernOptions::Unacknowledged.woCompare(writeConcern) != 0; if ( needToEnforceWC && ( !response->isErrDetailsSet() || ( !request.getOrdered() && // Not all errored. Note: implicit response->isErrDetailsSet(). response->sizeErrDetails() < request.sizeWriteOps() ))) { // Might have gotten a write concern validity error earlier, these are // enforced even if the wc isn't applied, so we ignore. response->unsetWriteConcernError(); const string dbName( nss.db().toString() ); Status status( Status::OK() ); if ( response->isErrDetailsSet() ) { const WriteErrorDetail* lastError = response->getErrDetails().back(); // If last write op was an error. if ( lastError->getIndex() == static_cast<int>( request.sizeWriteOps() - 1 )) { // Reset previous errors so we can apply the write concern no matter what // as long as it is valid. status = _safeWriter->clearErrors( conn, dbName ); } } BSONObj gleResult; if ( status.isOK() ) { status = _safeWriter->enforceWriteConcern( conn, dbName, writeConcern, &gleResult ); } GLEErrors errors; if ( status.isOK() ) { status = extractGLEErrors( gleResult, &errors ); } if ( !status.isOK() ) { auto_ptr<WCErrorDetail> wcError( new WCErrorDetail ); wcError->setErrCode( status.code() ); wcError->setErrMessage( status.reason() ); response->setWriteConcernError( wcError.release() ); } else if ( errors.wcError.get() ) { response->setWriteConcernError( errors.wcError.release() ); } } response->setOk( true ); dassert( response->isValid( NULL ) ); }