int applyInstruction(const Instruction* instr, sqlite3* db) { switch(instr->iType) { case SQLITE_INSERT: return applyInsert(db, instr); case SQLITE_UPDATE: return applyUpdate(db, instr); case SQLITE_DELETE: return applyDelete(db, instr); default: return CHANGESET_CORRUPT; } }
bool WriteBatchExecutor::applyWriteItem(const string& ns, const WriteBatch::WriteItem& writeItem, BSONObjBuilder* results) { // 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(writeItem.getWriteType())); childOp.ensureStarted(); OpDebug& opDebug = childOp.debug(); opDebug.ns = ns; { Client::WriteContext ctx(ns); switch(writeItem.getWriteType()) { case WriteBatch::WRITE_INSERT: opSuccess = applyInsert(ns, writeItem, &childOp); break; case WriteBatch::WRITE_UPDATE: opSuccess = applyUpdate(ns, writeItem, &childOp); break; case WriteBatch::WRITE_DELETE: opSuccess = applyDelete(ns, writeItem, &childOp); 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(writeItem.getWriteType()), childOp); } break; } catch (PageFaultException& e) { e.touch(); } } // Fill caller's builder with results of operation, using LastError. results->append("ok", opSuccess); _le->appendSelf(*results, false); results->append("micros", static_cast<long long>(itemTimeMicros)); return opSuccess; }