TransactionResult::Enum RunCommitTransaction() { TransactionResult::Enum tret; for (TouchedFilesList::iterator p = TouchedFiles.begin(), end = TouchedFiles.end(); p != end; ++p) { tret = MarkAsProcessed(*p); if (tret != TransactionResult::COMMIT) { return tret; } } Statement stmt; tret = stmt.TxnPrepare (*DB, "INSERT INTO files (path, mtime, size) VALUES (?, ?, ?)"); if (tret != TransactionResult::COMMIT) { return tret; } for (FTableMap::const_iterator p = FTable.begin(), end = FTable.end(); p != end; ++p) { const FileIdentification &FI(p->second->Ident); if (p->first != FI.Path) { // This is a duplicate, secondary entry. Avoid // shadowing the real entry. continue; } sqlite3_reset(stmt.Ptr); sqlite3_bind_text(stmt.Ptr, 1, FI.Path.data(), FI.Path.size(), SQLITE_TRANSIENT); sqlite3_bind_int64(stmt.Ptr, 2, FI.Mtime); sqlite3_bind_int64(stmt.Ptr, 3, FI.Size); if (sqlite3_step(stmt.Ptr) != SQLITE_DONE) { return DB->SetTransactionError(sqlite3_sql(stmt.Ptr)); } p->second->ID = sqlite3_last_insert_rowid(DB->Ptr); } tret = stmt.TxnPrepare (*DB, "INSERT INTO reports (file, line, column, tool, message) " "VALUES (?, ?, ?, ?, ?);"); if (tret != TransactionResult::COMMIT) { return tret; } for (std::vector<Report>::const_iterator p = Reports.begin(), end = Reports.end(); p != end; ++p) { sqlite3_reset(stmt.Ptr); sqlite3_bind_int64(stmt.Ptr, 1, p->FI->ID); sqlite3_bind_int64(stmt.Ptr, 2, p->Line); sqlite3_bind_int64(stmt.Ptr, 3, p->Column); sqlite3_bind_text(stmt.Ptr, 4, p->Tool.data(), p->Tool.size(), SQLITE_TRANSIENT); sqlite3_bind_text(stmt.Ptr, 5, p->Message.data(), p->Message.size(), SQLITE_TRANSIENT); if (sqlite3_step(stmt.Ptr) != SQLITE_DONE) { return DB->SetTransactionError(sqlite3_sql(stmt.Ptr)); } } return TransactionResult::COMMIT; }
TransactionResult::Enum MarkAsProcessed(const std::string &Path) { std::string Absolute; if (!ResolvePath(Path.c_str(), Absolute)) { DB->ErrorMessage = "could not find file on disk: "; DB->ErrorMessage += Path; return TransactionResult::ERROR; } Statement SQL; TransactionResult::Enum tret = SQL.TxnPrepare(*DB, "SELECT id FROM files " "WHERE path = ? ORDER BY id DESC LIMIT 1"); if (tret != TransactionResult::COMMIT) { return tret; } sqlite3_bind_text(SQL.Ptr, 1, Absolute.data(), Absolute.size(), SQLITE_TRANSIENT); int ret = sqlite3_step(SQL.Ptr); if (ret == SQLITE_DONE) { // File is not in the database. No need to mask older errors. return TransactionResult::COMMIT; } if (ret != SQLITE_ROW) { return DB->SetTransactionError(sqlite3_sql(SQL.Ptr)); } // Add an entry for the file, hiding the previous reports. // TODO: Only hide changed files? What about plugin changes? if (Resolve(Path) == NULL) { return TransactionResult::ERROR; } return TransactionResult::COMMIT; }