From 62dfd40ce984b18267409ba9e47a3b24d565772d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Jun 2012 10:57:10 -0700 Subject: [PATCH] Make SQL updates more sane. --- src/Ledger.cpp | 58 ++++++++++++++++++++++++++------------------- src/Transaction.cpp | 6 ++++- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/Ledger.cpp b/src/Ledger.cpp index f0e9d5f376..753f238726 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -270,36 +270,46 @@ void Ledger::saveAcceptedLedger(Ledger::pointer ledger) { SerializerIterator sit(item->peekSerializer()); SerializedTransaction txn(sit); - std::vector accts = txn.getAffectedAccounts(); - - std::string sql = "INSERT INTO AccountTransactions (TransID, Account, LedgerSeq) VALUES "; - bool first = true; - for (std::vector::iterator it = accts.begin(), end = accts.end(); it != end; ++it) + if (!SQL_EXISTS(db, + boost::str(boost::format("SELECT LedgerSeq FROM AccountTransactions WHERE TransId = '%s';") + % item->getTag().GetHex()))) { - if (!first) - sql += ", ('"; - else + std::vector accts = txn.getAffectedAccounts(); + + std::string sql = "INSERT INTO AccountTransactions (TransID, Account, LedgerSeq) VALUES "; + bool first = true; + for (std::vector::iterator it = accts.begin(), end = accts.end(); it != end; ++it) { - sql += "('"; - first = false; + if (!first) + sql += ", ('"; + else + { + sql += "('"; + first = false; + } + sql += txn.getTransactionID().GetHex(); + sql += "','"; + sql += it->humanAccountID(); + sql += "',"; + sql += boost::lexical_cast(ledger->getLedgerSeq()); + sql += ")"; } - sql += txn.getTransactionID().GetHex(); - sql += "','"; - sql += it->humanAccountID(); - sql += "',"; - sql += boost::lexical_cast(ledger->getLedgerSeq()); - sql += ")"; + sql += ";"; + Log(lsTRACE) << "ActTx: " << sql; + db->executeSQL(sql); // may already be in there } - sql += ";"; - Log(lsTRACE) << "ActTx: " << sql; - db->executeSQL(sql, true); // may already be in there - if (!db->executeSQL( - txn.getSQLInsertHeader() + txn.getSQL(ledger->getLedgerSeq(), TXN_SQL_VALIDATED) + ";"), true) - { // transaction already in DB, update - db->executeSQL(boost::str(boost::format( - "UPDATE Transactions SET LedgerSeq = '%d', Status = '%c' WHERE TransID = '%s';") % + if (SQL_EXISTS(db, boost::str(boost::format("SELECT Status from Transactions where TransID = '%s';") % + txn.getTransactionID().GetHex()))) + { + db->executeSQL(boost::str( + boost::format("UPDATE Transactions SET LedgerSeq = '%d', Status = '%c' WHERE TransID = '%s';") % ledger->getLedgerSeq() % TXN_SQL_VALIDATED % txn.getTransactionID().GetHex())); } + else + { + db->executeSQL( + txn.getSQLInsertHeader() + txn.getSQL(ledger->getLedgerSeq(), TXN_SQL_VALIDATED) + ";"); + } } db->executeSQL("COMMIT TRANSACTION;"); } diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 5a3b87e42b..934304195e 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -523,10 +523,14 @@ bool Transaction::save() default: status = TXN_SQL_UNKNOWN; } + std::string exists = boost::str(boost::format("SELECT Status FROM Transactions WHERE TransID = '%s';") + % mTransaction->getTransactionID().GetHex()); + Database *db = theApp->getTxnDB()->getDB(); ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + if (!SQL_EXISTS(db, exists)) return false; return - db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";", true); + db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";"); } Transaction::pointer Transaction::transactionFromSQL(const std::string& sql)