From d210441a1b306483b8de1726dc2d452d400afcc5 Mon Sep 17 00:00:00 2001 From: "nasihudeen04@gmail.com" Date: Fri, 13 Mar 2026 19:00:11 +0100 Subject: [PATCH 1/2] Remove redundant StatementContext class and replace with direct soci::statement usage --- src/database/Database.cpp | 31 +++-- src/database/Database.h | 42 +------ src/database/test/DatabaseTests.cpp | 42 +++---- src/herder/HerderPersistenceImpl.cpp | 77 ++++++------- src/herder/test/HerderTests.cpp | 11 +- src/ledger/LedgerHeaderUtils.cpp | 30 +++-- src/ledger/LedgerTxnImpl.h | 4 +- src/ledger/LedgerTxnOfferSQL.cpp | 164 +++++++++++++-------------- src/main/PersistentState.cpp | 77 ++++++------- src/overlay/BanManagerImpl.cpp | 34 +++--- src/overlay/PeerManager.cpp | 90 +++++++-------- 11 files changed, 260 insertions(+), 342 deletions(-) diff --git a/src/database/Database.cpp b/src/database/Database.cpp index 23cc94ac46..b3d63e19da 100644 --- a/src/database/Database.cpp +++ b/src/database/Database.cpp @@ -338,11 +338,10 @@ migrateLedgerHeadersToStoreState(Database& db) auto prep = db.getPreparedStatement( "SELECT state FROM storestate WHERE statename = 'lastclosedledger'", session); - auto& stmt = prep.statement(); - stmt.exchange(soci::into(lclHash)); - stmt.define_and_bind(); - stmt.execute(true); - gotData = stmt.got_data(); + prep.exchange(soci::into(lclHash)); + prep.define_and_bind(); + prep.execute(true); + gotData = prep.got_data(); } // When we're doing this migration for a new db, storestate will be empty. @@ -365,10 +364,9 @@ migrateLedgerHeadersToStoreState(Database& db) db.getPreparedStatement("INSERT INTO storestate (statename, state) " "VALUES ('lastclosedledgerheader', :v)", session); - auto& stmt = prep.statement(); - stmt.exchange(soci::use(headerData)); - stmt.define_and_bind(); - stmt.execute(true); + prep.exchange(soci::use(headerData)); + prep.define_and_bind(); + prep.execute(true); raw << "DELETE FROM storestate WHERE statename = 'lastclosedledger'"; } @@ -571,9 +569,8 @@ Database::setCurrentTransactionReadOnly() { auto prep = getPreparedStatement("SET TRANSACTION READ ONLY", getSession()); - auto& st = prep.statement(); - st.define_and_bind(); - st.execute(false); + prep.define_and_bind(); + prep.execute(false); } } @@ -739,13 +736,13 @@ Database::getMiscPool() Database::getMiscDBName(mApp.getConfig().DATABASE.value)); } -StatementContext +soci::statement Database::getPreparedStatement(std::string const& query, SessionWrapper& session) { - auto p = std::make_shared(session.session()); - p->alloc(); - p->prepare(query); - return StatementContext(p); + soci::statement p(session.session()); + p.alloc(); + p.prepare(query); + return p; } } diff --git a/src/database/Database.h b/src/database/Database.h index c77aad4fab..aec4b3ed47 100644 --- a/src/database/Database.h +++ b/src/database/Database.h @@ -35,39 +35,6 @@ static constexpr unsigned long FIRST_MAIN_VERSION_WITH_MISC = 26; static constexpr unsigned long MIN_MISC_SCHEMA_VERSION = 0; static constexpr unsigned long MISC_SCHEMA_VERSION = 1; -/** - * Helper class for borrowing a SOCI prepared statement handle into a local - * scope and cleaning it up once done with it. Returned by - * Database::getPreparedStatement below. - */ -class StatementContext : NonCopyable -{ - std::shared_ptr mStmt; - - public: - StatementContext(std::shared_ptr stmt) : mStmt(stmt) - { - mStmt->clean_up(false); - } - StatementContext(StatementContext&& other) - { - mStmt = other.mStmt; - other.mStmt.reset(); - } - ~StatementContext() - { - if (mStmt) - { - mStmt->clean_up(false); - } - } - soci::statement& - statement() - { - return *mStmt; - } -}; - class SessionWrapper : NonCopyable { soci::session mSession; @@ -160,12 +127,9 @@ class Database : NonMovableOrCopyable { } - // Return a helper object that borrows, from the Database, a prepared - // statement handle for the provided query. The prepared statement handle - // is created and reset (unbound from data) when the statement context - // is destroyed. - StatementContext getPreparedStatement(std::string const& query, - SessionWrapper& session); + // Return a prepared statement handle for the provided query. + soci::statement getPreparedStatement(std::string const& query, + SessionWrapper& session); // Return metric-gathering timers for various families of SQL operation. // These timers automatically count the time they are alive for, diff --git a/src/database/test/DatabaseTests.cpp b/src/database/test/DatabaseTests.cpp index bdd5c1b675..54a6a301f4 100644 --- a/src/database/test/DatabaseTests.cpp +++ b/src/database/test/DatabaseTests.cpp @@ -435,9 +435,8 @@ TEST_CASE("Database splitting migration works correctly", "[db]") // Helper to execute SQL on a session auto execSQL = [&](std::string const& sql, SessionWrapper& session) { auto prep = db.getPreparedStatement(sql, session); - auto& st = prep.statement(); - st.define_and_bind(); - st.execute(true); + prep.define_and_bind(); + prep.execute(true); }; // Helper to count rows in a table @@ -446,10 +445,9 @@ TEST_CASE("Database splitting migration works correctly", "[db]") int count = 0; auto prep = db.getPreparedStatement("SELECT COUNT(*) FROM " + table, session); - auto& st = prep.statement(); - st.exchange(soci::into(count)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(count)); + prep.define_and_bind(); + prep.execute(true); return count; }; @@ -462,10 +460,9 @@ TEST_CASE("Database splitting migration works correctly", "[db]") "name='" + table + "'", session); - auto& st = prep.statement(); - st.exchange(soci::into(count)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(count)); + prep.define_and_bind(); + prep.execute(true); return count > 0; }; @@ -527,10 +524,9 @@ TEST_CASE("Database splitting migration works correctly", "[db]") "SELECT state FROM storestate WHERE statename = " "'lastclosedledgerheader'", db.getSession()); - auto& st = prep.statement(); - st.exchange(soci::into(result)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(result)); + prep.define_and_bind(); + prep.execute(true); REQUIRE(result == headerEncoded); } @@ -564,11 +560,10 @@ TEST_CASE("Database splitting migration works correctly", "[db]") int port = 0; auto prep = db.getPreparedStatement("SELECT ip, port FROM peers", db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(ip)); - st.exchange(soci::into(port)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(ip)); + prep.exchange(soci::into(port)); + prep.define_and_bind(); + prep.execute(true); REQUIRE(ip == "127.0.0.1"); REQUIRE(port == 11625); } @@ -578,10 +573,9 @@ TEST_CASE("Database splitting migration works correctly", "[db]") "SELECT state FROM slotstate WHERE statename = " "'ledgerupgrades'", db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(state)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(state)); + prep.define_and_bind(); + prep.execute(true); REQUIRE(state == "testvalue"); } } diff --git a/src/herder/HerderPersistenceImpl.cpp b/src/herder/HerderPersistenceImpl.cpp index 62c56e457b..e7b66dea54 100644 --- a/src/herder/HerderPersistenceImpl.cpp +++ b/src/herder/HerderPersistenceImpl.cpp @@ -56,12 +56,11 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, auto prepClean = db.getPreparedStatement( "DELETE FROM scphistory WHERE ledgerseq =:l", sess); - auto& st = prepClean.statement(); - st.exchange(soci::use(seq)); - st.define_and_bind(); + prepClean.exchange(soci::use(seq)); + prepClean.define_and_bind(); { ZoneNamedN(deleteSCPHistoryZone, "delete scphistory", true); - st.execute(true); + prepClean.execute(true); } } @@ -96,16 +95,15 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, "(nodeid, ledgerseq, envelope) VALUES " "(:n, :l, :e)", sess); - auto& st = prepEnv.statement(); - st.exchange(soci::use(nodeIDs, "n")); - st.exchange(soci::use(seqs, "l")); - st.exchange(soci::use(envelopes, "e")); - st.define_and_bind(); + prepEnv.exchange(soci::use(nodeIDs, "n")); + prepEnv.exchange(soci::use(seqs, "l")); + prepEnv.exchange(soci::use(envelopes, "e")); + prepEnv.define_and_bind(); { ZoneNamedN(insertSCPHistoryZone, "insert scphistory", true); - st.execute(true); + prepEnv.execute(true); } - if (st.get_affected_rows() != envs.size()) + if (prepEnv.get_affected_rows() != envs.size()) { throw std::runtime_error("Could not update data in SQL"); } @@ -128,28 +126,26 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, auto prep = db.getPreparedStatement( "UPDATE quoruminfo SET qsethash = :h WHERE nodeid = :id", sess); - auto& st = prep.statement(); - st.exchange(soci::use(qSetHHex)); - st.exchange(soci::use(nodeIDStrKey)); - st.define_and_bind(); + prep.exchange(soci::use(qSetHHex)); + prep.exchange(soci::use(nodeIDStrKey)); + prep.define_and_bind(); { ZoneNamedN(updateQsetZone, "update quoruminfo", true); - st.execute(true); + prep.execute(true); } - if (st.get_affected_rows() != 1) + if (prep.get_affected_rows() != 1) { auto prepI = db.getPreparedStatement( "INSERT INTO quoruminfo (nodeid, qsethash) VALUES (:id, :h)", sess); - auto& stI = prepI.statement(); - stI.exchange(soci::use(nodeIDStrKey)); - stI.exchange(soci::use(qSetHHex)); - stI.define_and_bind(); + prepI.exchange(soci::use(nodeIDStrKey)); + prepI.exchange(soci::use(qSetHHex)); + prepI.define_and_bind(); { ZoneNamedN(insertQsetZone, "insert quoruminfo", true); - stI.execute(true); + prepI.execute(true); } - if (stI.get_affected_rows() != 1) + if (prepI.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } @@ -163,16 +159,15 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, uint32_t lastSeenSeq; auto prepSelQSet = db.getPreparedStatement( "SELECT lastledgerseq FROM scpquorums WHERE qsethash = :h", sess); - auto& stSel = prepSelQSet.statement(); - stSel.exchange(soci::into(lastSeenSeq)); - stSel.exchange(soci::use(qSetH)); - stSel.define_and_bind(); + prepSelQSet.exchange(soci::into(lastSeenSeq)); + prepSelQSet.exchange(soci::use(qSetH)); + prepSelQSet.define_and_bind(); { ZoneNamedN(selectSCPQuorumsZone, "select scpquorums", true); - stSel.execute(true); + prepSelQSet.execute(true); } - if (stSel.got_data()) + if (prepSelQSet.got_data()) { if (lastSeenSeq >= seq) { @@ -184,15 +179,14 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, "lastledgerseq = :l WHERE qsethash = :h", sess); - auto& stUp = prepUpQSet.statement(); - stUp.exchange(soci::use(seq)); - stUp.exchange(soci::use(qSetH)); - stUp.define_and_bind(); + prepUpQSet.exchange(soci::use(seq)); + prepUpQSet.exchange(soci::use(qSetH)); + prepUpQSet.define_and_bind(); { ZoneNamedN(updateSCPQuorumsZone, "update scpquorums", true); - stUp.execute(true); + prepUpQSet.execute(true); } - if (stUp.get_affected_rows() != 1) + if (prepUpQSet.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } @@ -210,16 +204,15 @@ HerderPersistenceImpl::saveSCPHistory(uint32_t seq, "(:h, :l, :v);", sess); - auto& stIns = prepInsQSet.statement(); - stIns.exchange(soci::use(qSetH)); - stIns.exchange(soci::use(seq)); - stIns.exchange(soci::use(qSetEncoded)); - stIns.define_and_bind(); + prepInsQSet.exchange(soci::use(qSetH)); + prepInsQSet.exchange(soci::use(seq)); + prepInsQSet.exchange(soci::use(qSetEncoded)); + prepInsQSet.define_and_bind(); { ZoneNamedN(insertSCPQuorumsZone, "insert scpquorums", true); - stIns.execute(true); + prepInsQSet.execute(true); } - if (stIns.get_affected_rows() != 1) + if (prepInsQSet.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } diff --git a/src/herder/test/HerderTests.cpp b/src/herder/test/HerderTests.cpp index f6a327b62b..43bfbdc89c 100644 --- a/src/herder/test/HerderTests.cpp +++ b/src/herder/test/HerderTests.cpp @@ -6408,16 +6408,15 @@ TEST_CASE("SCP message capture from previous ledger", "[herder]") auto prep = db.getPreparedStatement( "SELECT envelope FROM scphistory WHERE ledgerseq = :l", db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::use(ledgerNum)); + prep.exchange(soci::use(ledgerNum)); std::string envStr; - st.exchange(soci::into(envStr)); - st.define_and_bind(); - st.execute(false); + prep.exchange(soci::into(envStr)); + prep.define_and_bind(); + prep.execute(false); // Count the number of entries of each type UnorderedMap actualTypes; - while (st.fetch()) + while (prep.fetch()) { Value v; decoder::decode_b64(envStr, v); diff --git a/src/ledger/LedgerHeaderUtils.cpp b/src/ledger/LedgerHeaderUtils.cpp index 24f4132ae2..283f813c1b 100644 --- a/src/ledger/LedgerHeaderUtils.cpp +++ b/src/ledger/LedgerHeaderUtils.cpp @@ -81,19 +81,18 @@ storeInDatabase(Database& db, LedgerHeader const& header, SessionWrapper& sess) "VALUES " "(:h, :ph, :blh, :seq, :ct, :data)", sess); - auto& st = prep.statement(); - st.exchange(soci::use(hash)); - st.exchange(soci::use(prevHash)); - st.exchange(soci::use(bucketListHash)); - st.exchange(soci::use(header.ledgerSeq)); - st.exchange(soci::use(header.scpValue.closeTime)); - st.exchange(soci::use(headerEncoded)); - st.define_and_bind(); + prep.exchange(soci::use(hash)); + prep.exchange(soci::use(prevHash)); + prep.exchange(soci::use(bucketListHash)); + prep.exchange(soci::use(header.ledgerSeq)); + prep.exchange(soci::use(header.scpValue.closeTime)); + prep.exchange(soci::use(headerEncoded)); + prep.define_and_bind(); { ZoneNamedN(insertLedgerHeadersZone, "insert ledgerheaders", true); - st.execute(true); + prep.execute(true); } - if (st.get_affected_rows() != 1) + if (prep.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } @@ -134,15 +133,14 @@ getHeaderDataForHash(Database& db, Hash const& hash) auto prep = db.getPreparedStatement("SELECT data FROM ledgerheaders " "WHERE ledgerhash = :h", db.getSession()); - auto& st = prep.statement(); - st.exchange(soci::into(headerEncoded)); - st.exchange(soci::use(hash_s)); - st.define_and_bind(); + prep.exchange(soci::into(headerEncoded)); + prep.exchange(soci::use(hash_s)); + prep.define_and_bind(); { ZoneNamedN(selectLedgerHeadersZone, "select ledgerheaders", true); - st.execute(true); + prep.execute(true); } - if (st.got_data()) + if (prep.got_data()) { auto lh = decodeFromData(headerEncoded); auto ledgerHash = xdrSha256(lh); diff --git a/src/ledger/LedgerTxnImpl.h b/src/ledger/LedgerTxnImpl.h index 30057b545f..1384743b48 100644 --- a/src/ledger/LedgerTxnImpl.h +++ b/src/ledger/LedgerTxnImpl.h @@ -646,7 +646,7 @@ class LedgerTxnRoot::Impl std::shared_ptr loadOffer(LedgerKey const& key) const; std::vector loadAllOffers() const; std::deque::const_iterator - loadOffers(StatementContext& prep, std::deque& offers) const; + loadOffers(soci::statement& prep, std::deque& offers) const; std::deque::const_iterator loadBestOffers(std::deque& offers, Asset const& buying, Asset const& selling, size_t numOffers) const; @@ -657,7 +657,7 @@ class LedgerTxnRoot::Impl std::vector loadOffersByAccountAndAsset(AccountID const& accountID, Asset const& asset) const; - std::vector loadOffers(StatementContext& prep) const; + std::vector loadOffers(soci::statement& prep) const; void bulkApply(BulkLedgerEntryChangeAccumulator& bleca, size_t bufferThreshold, LedgerTxnConsistency cons); diff --git a/src/ledger/LedgerTxnOfferSQL.cpp b/src/ledger/LedgerTxnOfferSQL.cpp index 0c400e97c8..517843f69f 100644 --- a/src/ledger/LedgerTxnOfferSQL.cpp +++ b/src/ledger/LedgerTxnOfferSQL.cpp @@ -40,9 +40,8 @@ LedgerTxnRoot::Impl::loadOffer(LedgerKey const& key) const "FROM offers " "WHERE sellerid= :id AND offerid= :offerid"; auto prep = mApp.getDatabase().getPreparedStatement(sql, getSession()); - auto& st = prep.statement(); - st.exchange(soci::use(actIDStrKey)); - st.exchange(soci::use(offerID)); + prep.exchange(soci::use(actIDStrKey)); + prep.exchange(soci::use(offerID)); std::vector offers; { @@ -90,10 +89,9 @@ LedgerTxnRoot::Impl::loadBestOffers(std::deque& offers, sellingAsset = decoder::encode_b64(xdr::xdr_to_opaque(selling)); auto prep = mApp.getDatabase().getPreparedStatement(sql, getSession()); - auto& st = prep.statement(); - st.exchange(soci::use(sellingAsset)); - st.exchange(soci::use(buyingAsset)); - st.exchange(soci::use(numOffers)); + prep.exchange(soci::use(sellingAsset)); + prep.exchange(soci::use(buyingAsset)); + prep.exchange(soci::use(numOffers)); { auto timer = mApp.getDatabase().getSelectTimer("offer"); @@ -146,17 +144,16 @@ LedgerTxnRoot::Impl::loadBestOffers(std::deque& offers, int64_t worseThanOfferID = worseThan.offerID + 1; auto prep = mApp.getDatabase().getPreparedStatement(sql, getSession()); - auto& st = prep.statement(); - st.exchange(soci::use(sellingAsset)); - st.exchange(soci::use(buyingAsset)); - st.exchange(soci::use(worseThanPrice)); - st.exchange(soci::use(numOffers)); - st.exchange(soci::use(sellingAsset)); - st.exchange(soci::use(buyingAsset)); - st.exchange(soci::use(worseThanPrice)); - st.exchange(soci::use(worseThanOfferID)); - st.exchange(soci::use(numOffers)); - st.exchange(soci::use(numOffers)); + prep.exchange(soci::use(sellingAsset)); + prep.exchange(soci::use(buyingAsset)); + prep.exchange(soci::use(worseThanPrice)); + prep.exchange(soci::use(numOffers)); + prep.exchange(soci::use(sellingAsset)); + prep.exchange(soci::use(buyingAsset)); + prep.exchange(soci::use(worseThanPrice)); + prep.exchange(soci::use(worseThanOfferID)); + prep.exchange(soci::use(numOffers)); + prep.exchange(soci::use(numOffers)); { auto timer = mApp.getDatabase().getSelectTimer("offer"); @@ -228,10 +225,9 @@ LedgerTxnRoot::Impl::loadOffersByAccountAndAsset(AccountID const& accountID, std::string assetStr = decoder::encode_b64(xdr::xdr_to_opaque(asset)); auto prep = mApp.getDatabase().getPreparedStatement(sql, getSession()); - auto& st = prep.statement(); - st.exchange(soci::use(accountStr)); - st.exchange(soci::use(assetStr)); - st.exchange(soci::use(assetStr)); + prep.exchange(soci::use(accountStr)); + prep.exchange(soci::use(assetStr)); + prep.exchange(soci::use(assetStr)); std::vector offers; { @@ -253,7 +249,7 @@ processAsset(std::string const& asset) template static typename T::const_iterator -loadOffersHelper(StatementContext& prep, T& offers) +loadOffersHelper(soci::statement& prep, T& offers) { ZoneScoped; @@ -266,23 +262,22 @@ loadOffersHelper(StatementContext& prep, T& offers) std::string extensionStr; std::string ledgerExtStr; - auto& st = prep.statement(); - st.exchange(soci::into(actIDStrKey)); - st.exchange(soci::into(offerID)); - st.exchange(soci::into(sellingAsset)); - st.exchange(soci::into(buyingAsset)); - st.exchange(soci::into(amount)); - st.exchange(soci::into(price.n)); - st.exchange(soci::into(price.d)); - st.exchange(soci::into(flags)); - st.exchange(soci::into(lastModified)); - st.exchange(soci::into(extensionStr)); - st.exchange(soci::into(ledgerExtStr)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(actIDStrKey)); + prep.exchange(soci::into(offerID)); + prep.exchange(soci::into(sellingAsset)); + prep.exchange(soci::into(buyingAsset)); + prep.exchange(soci::into(amount)); + prep.exchange(soci::into(price.n)); + prep.exchange(soci::into(price.d)); + prep.exchange(soci::into(flags)); + prep.exchange(soci::into(lastModified)); + prep.exchange(soci::into(extensionStr)); + prep.exchange(soci::into(ledgerExtStr)); + prep.define_and_bind(); + prep.execute(true); size_t n = 0; - while (st.got_data()) + while (prep.got_data()) { ++n; offers.emplace_back(); @@ -303,21 +298,21 @@ loadOffersHelper(StatementContext& prep, T& offers) decodeOpaqueXDR(ledgerExtStr, le.ext); - st.fetch(); + prep.fetch(); } return offers.cend() - n; } std::deque::const_iterator -LedgerTxnRoot::Impl::loadOffers(StatementContext& prep, +LedgerTxnRoot::Impl::loadOffers(soci::statement& prep, std::deque& offers) const { return loadOffersHelper(prep, offers); } std::vector -LedgerTxnRoot::Impl::loadOffers(StatementContext& prep) const +LedgerTxnRoot::Impl::loadOffers(soci::statement& prep) const { std::vector offers; loadOffersHelper(prep, offers); @@ -445,25 +440,24 @@ class BulkUpsertOffersOperation : public DatabaseTypeSpecificOperation "extension = excluded.extension, " "ledgerext = excluded.ledgerext"; auto prep = mDB.getPreparedStatement(sql, mSession); - soci::statement& st = prep.statement(); - st.exchange(soci::use(mSellerIDs)); - st.exchange(soci::use(mOfferIDs)); - st.exchange(soci::use(mSellingAssets)); - st.exchange(soci::use(mBuyingAssets)); - st.exchange(soci::use(mAmounts)); - st.exchange(soci::use(mPriceNs)); - st.exchange(soci::use(mPriceDs)); - st.exchange(soci::use(mPrices)); - st.exchange(soci::use(mFlags)); - st.exchange(soci::use(mLastModifieds)); - st.exchange(soci::use(mExtensions)); - st.exchange(soci::use(mLedgerExtensions)); - st.define_and_bind(); + prep.exchange(soci::use(mSellerIDs)); + prep.exchange(soci::use(mOfferIDs)); + prep.exchange(soci::use(mSellingAssets)); + prep.exchange(soci::use(mBuyingAssets)); + prep.exchange(soci::use(mAmounts)); + prep.exchange(soci::use(mPriceNs)); + prep.exchange(soci::use(mPriceDs)); + prep.exchange(soci::use(mPrices)); + prep.exchange(soci::use(mFlags)); + prep.exchange(soci::use(mLastModifieds)); + prep.exchange(soci::use(mExtensions)); + prep.exchange(soci::use(mLedgerExtensions)); + prep.define_and_bind(); { auto timer = mDB.getUpsertTimer("offer"); - st.execute(true); + prep.execute(true); } - if (static_cast(st.get_affected_rows()) != mOfferIDs.size()) + if (static_cast(prep.get_affected_rows()) != mOfferIDs.size()) { throw std::runtime_error("Could not update data in SQL"); } @@ -533,25 +527,24 @@ class BulkUpsertOffersOperation : public DatabaseTypeSpecificOperation "extension = excluded.extension, " "ledgerext = excluded.ledgerext"; auto prep = mDB.getPreparedStatement(sql, mSession); - soci::statement& st = prep.statement(); - st.exchange(soci::use(strSellerIDs)); - st.exchange(soci::use(strOfferIDs)); - st.exchange(soci::use(strSellingAssets)); - st.exchange(soci::use(strBuyingAssets)); - st.exchange(soci::use(strAmounts)); - st.exchange(soci::use(strPriceNs)); - st.exchange(soci::use(strPriceDs)); - st.exchange(soci::use(strPrices)); - st.exchange(soci::use(strFlags)); - st.exchange(soci::use(strLastModifieds)); - st.exchange(soci::use(strExtensions)); - st.exchange(soci::use(strLedgerExtensions)); - st.define_and_bind(); + prep.exchange(soci::use(strSellerIDs)); + prep.exchange(soci::use(strOfferIDs)); + prep.exchange(soci::use(strSellingAssets)); + prep.exchange(soci::use(strBuyingAssets)); + prep.exchange(soci::use(strAmounts)); + prep.exchange(soci::use(strPriceNs)); + prep.exchange(soci::use(strPriceDs)); + prep.exchange(soci::use(strPrices)); + prep.exchange(soci::use(strFlags)); + prep.exchange(soci::use(strLastModifieds)); + prep.exchange(soci::use(strExtensions)); + prep.exchange(soci::use(strLedgerExtensions)); + prep.define_and_bind(); { auto timer = mDB.getUpsertTimer("offer"); - st.execute(true); + prep.execute(true); } - if (static_cast(st.get_affected_rows()) != mOfferIDs.size()) + if (static_cast(prep.get_affected_rows()) != mOfferIDs.size()) { throw std::runtime_error("Could not update data in SQL"); } @@ -588,14 +581,13 @@ class BulkDeleteOffersOperation : public DatabaseTypeSpecificOperation { std::string sql = "DELETE FROM offers WHERE offerid = :id"; auto prep = mDB.getPreparedStatement(sql, mSession); - soci::statement& st = prep.statement(); - st.exchange(soci::use(mOfferIDs)); - st.define_and_bind(); + prep.exchange(soci::use(mOfferIDs)); + prep.define_and_bind(); { auto timer = mDB.getDeleteTimer("offer"); - st.execute(true); + prep.execute(true); } - if (static_cast(st.get_affected_rows()) != mOfferIDs.size() && + if (static_cast(prep.get_affected_rows()) != mOfferIDs.size() && mCons == LedgerTxnConsistency::EXACT) { throw std::runtime_error("Could not update data in SQL"); @@ -621,14 +613,13 @@ class BulkDeleteOffersOperation : public DatabaseTypeSpecificOperation "DELETE FROM offers WHERE " "offerid IN (SELECT * FROM r)"; auto prep = mDB.getPreparedStatement(sql, mSession); - soci::statement& st = prep.statement(); - st.exchange(soci::use(strOfferIDs)); - st.define_and_bind(); + prep.exchange(soci::use(strOfferIDs)); + prep.define_and_bind(); { auto timer = mDB.getDeleteTimer("offer"); - st.execute(true); + prep.execute(true); } - if (static_cast(st.get_affected_rows()) != mOfferIDs.size() && + if (static_cast(prep.get_affected_rows()) != mOfferIDs.size() && mCons == LedgerTxnConsistency::EXACT) { throw std::runtime_error("Could not update data in SQL"); @@ -808,7 +799,7 @@ class BulkLoadOffersOperation sqlite3_reset(st); sqlite3_bind_pointer(st, 1, (void*)mOfferIDs.data(), "carray", 0); sqlite3_bind_int(st, 2, static_cast(mOfferIDs.size())); - return executeAndFetch(prep.statement()); + return executeAndFetch(prep); } #ifdef USE_POSTGRES @@ -825,9 +816,8 @@ class BulkLoadOffersOperation "ledgerext " "FROM offers WHERE offerid IN (SELECT * FROM r)"; auto prep = mDb.getPreparedStatement(sql, mSession); - auto& st = prep.statement(); - st.exchange(soci::use(strOfferIDs)); - return executeAndFetch(st); + prep.exchange(soci::use(strOfferIDs)); + return executeAndFetch(prep); } #endif }; diff --git a/src/main/PersistentState.cpp b/src/main/PersistentState.cpp index 02d24c5be7..fc6602f5b8 100644 --- a/src/main/PersistentState.cpp +++ b/src/main/PersistentState.cpp @@ -62,10 +62,9 @@ PersistentState::deleteTxSets(std::unordered_set hashesToDelete) fmt::format("DELETE FROM {} WHERE statename = :n;", kSlotTableName), mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::use(name)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::use(name)); + prep.define_and_bind(); + prep.execute(true); } tx.commit(); } @@ -138,11 +137,10 @@ PersistentState::hasTxSet(Hash const& txSetHash) auto prep = db.getPreparedStatement( "SELECT COUNT(*) FROM slotstate WHERE statename = :n;", db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(res)); - st.exchange(soci::use(entry)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(res)); + prep.exchange(soci::use(entry)); + prep.define_and_bind(); + prep.execute(true); return res > 0; } @@ -289,16 +287,15 @@ PersistentState::updateDb(std::string const& entry, std::string const& value, tableName), sess); - auto& st = prep.statement(); - st.exchange(soci::use(value)); - st.exchange(soci::use(entry)); - st.define_and_bind(); + prep.exchange(soci::use(value)); + prep.exchange(soci::use(entry)); + prep.define_and_bind(); { ZoneNamedN(updateStoreStateZone, "update storestate", true); - st.execute(true); + prep.execute(true); } - if (st.get_affected_rows() != 1 && + if (prep.get_affected_rows() != 1 && getFromDb(entry, sess, tableName).empty()) { ZoneNamedN(insertStoreStateZone, "insert storestate", true); @@ -306,12 +303,11 @@ PersistentState::updateDb(std::string const& entry, std::string const& value, fmt::format("INSERT INTO {} (statename, state) VALUES (:n, :v);", tableName), sess); - auto& st2 = prep2.statement(); - st2.exchange(soci::use(entry)); - st2.exchange(soci::use(value)); - st2.define_and_bind(); - st2.execute(true); - if (st2.get_affected_rows() != 1) + prep2.exchange(soci::use(entry)); + prep2.exchange(soci::use(value)); + prep2.define_and_bind(); + prep2.execute(true); + if (prep2.get_affected_rows() != 1) { throw std::runtime_error("Could not insert data in SQL"); } @@ -334,26 +330,25 @@ PersistentState::getTxSetsForAllSlots() kSlotTableName); auto& db = mApp.getDatabase(); auto prep = db.getPreparedStatement(statementStr, db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(key)); - st.exchange(soci::into(val)); - st.exchange(soci::use(pattern)); - st.define_and_bind(); + prep.exchange(soci::into(key)); + prep.exchange(soci::into(val)); + prep.exchange(soci::use(pattern)); + prep.define_and_bind(); { ZoneNamedN(selectStoreStateZone, "select storestate", true); - st.execute(true); + prep.execute(true); } Hash hash; size_t len = binToHex(hash).size(); - while (st.got_data()) + while (prep.got_data()) { result.emplace( hexToBin256(key.substr( miscMapping[kTxSet - kLastEntryMain - 1].size(), len)), val); - st.fetch(); + prep.fetch(); } return result; @@ -373,23 +368,22 @@ PersistentState::getTxSetHashesForAllSlots() "SELECT statename FROM slotstate WHERE statename LIKE :n;"; auto& db = mApp.getDatabase(); auto prep = db.getPreparedStatement(statementStr, db.getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(val)); - st.exchange(soci::use(pattern)); - st.define_and_bind(); + prep.exchange(soci::into(val)); + prep.exchange(soci::use(pattern)); + prep.define_and_bind(); { ZoneNamedN(selectSlotStateZone, "select slotstate", true); - st.execute(true); + prep.execute(true); } size_t offset = miscMapping[kTxSet - kLastEntryMain - 1].size(); Hash hash; size_t len = binToHex(hash).size(); - while (st.got_data()) + while (prep.got_data()) { result.insert(hexToBin256(val.substr(offset, len))); - st.fetch(); + prep.fetch(); } return result; @@ -408,16 +402,15 @@ PersistentState::getFromDb(std::string const& entry, SessionWrapper& sess, auto prep = db.getPreparedStatement( fmt::format("SELECT state FROM {} WHERE statename = :n;", tableName), sess); - auto& st = prep.statement(); - st.exchange(soci::into(res)); - st.exchange(soci::use(entry)); - st.define_and_bind(); + prep.exchange(soci::into(res)); + prep.exchange(soci::use(entry)); + prep.define_and_bind(); { ZoneNamedN(selectStoreStateZone, "select storestate", true); - st.execute(true); + prep.execute(true); } - if (!st.got_data()) + if (!prep.got_data()) { res.clear(); } diff --git a/src/overlay/BanManagerImpl.cpp b/src/overlay/BanManagerImpl.cpp index 3e49555a41..ba6b6a99ce 100644 --- a/src/overlay/BanManagerImpl.cpp +++ b/src/overlay/BanManagerImpl.cpp @@ -46,10 +46,9 @@ BanManagerImpl::banNode(NodeID nodeID) auto prep = mApp.getDatabase().getPreparedStatement( "INSERT INTO ban (nodeid) VALUES(:n)", mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::use(nodeIDString)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::use(nodeIDString)); + prep.define_and_bind(); + prep.execute(true); } } @@ -64,10 +63,9 @@ BanManagerImpl::unbanNode(NodeID nodeID) auto prep = mApp.getDatabase().getPreparedStatement( "DELETE FROM ban WHERE nodeid = :n;", mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::use(nodeIDString)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::use(nodeIDString)); + prep.define_and_bind(); + prep.execute(true); } } @@ -82,11 +80,10 @@ BanManagerImpl::isBanned(NodeID nodeID) "SELECT count(*) FROM ban WHERE nodeid = :n", mApp.getDatabase().getMiscSession()); uint32_t count; - auto& st = prep.statement(); - st.exchange(soci::into(count)); - st.exchange(soci::use(nodeIDString)); - st.define_and_bind(); - st.execute(true); + prep.exchange(soci::into(count)); + prep.exchange(soci::use(nodeIDString)); + prep.define_and_bind(); + prep.execute(true); return count == 1; } } @@ -101,14 +98,13 @@ BanManagerImpl::getBans() ZoneNamedN(selectBanZone, "select ban", true); auto prep = mApp.getDatabase().getPreparedStatement( "SELECT nodeid FROM ban", mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(soci::into(nodeIDString)); - st.define_and_bind(); - st.execute(true); - while (st.got_data()) + prep.exchange(soci::into(nodeIDString)); + prep.define_and_bind(); + prep.execute(true); + while (prep.got_data()) { result.push_back(nodeIDString); - st.fetch(); + prep.fetch(); } } return result; diff --git a/src/overlay/PeerManager.cpp b/src/overlay/PeerManager.cpp index f204a5beb8..bf50bfcada 100644 --- a/src/overlay/PeerManager.cpp +++ b/src/overlay/PeerManager.cpp @@ -182,21 +182,20 @@ PeerManager::removePeersWithManyFailures(size_t minNumFailures, auto prep = db.getPreparedStatement(sql, mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(use(minNumFailures)); + prep.exchange(use(minNumFailures)); std::string ip; if (address) { ip = address->getIP(); - st.exchange(use(ip)); + prep.exchange(use(ip)); } - st.define_and_bind(); + prep.define_and_bind(); { auto timer = db.getDeleteTimer("peer"); - st.execute(true); + prep.execute(true); } } catch (soci_error& err) @@ -240,19 +239,18 @@ PeerManager::load(PeerBareAddress const& address) "SELECT numfailures, nextattempt, type FROM peers " "WHERE ip = :v1 AND port = :v2", mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(into(result.mNumFailures)); - st.exchange(into(result.mNextAttempt)); - st.exchange(into(result.mType)); + prep.exchange(into(result.mNumFailures)); + prep.exchange(into(result.mNextAttempt)); + prep.exchange(into(result.mType)); std::string ip = address.getIP(); - st.exchange(use(ip)); + prep.exchange(use(ip)); int port = address.getPort(); - st.exchange(use(port)); - st.define_and_bind(); + prep.exchange(use(port)); + prep.define_and_bind(); { auto timer = mApp.getDatabase().getSelectTimer("peer"); - st.execute(true); - inDatabase = st.got_data(); + prep.execute(true); + inDatabase = prep.got_data(); if (!inDatabase) { @@ -298,19 +296,18 @@ PeerManager::store(PeerBareAddress const& address, PeerRecord const& peerRecord, { auto prep = mApp.getDatabase().getPreparedStatement( query, mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(use(peerRecord.mNextAttempt)); - st.exchange(use(peerRecord.mNumFailures)); - st.exchange(use(peerRecord.mType)); + prep.exchange(use(peerRecord.mNextAttempt)); + prep.exchange(use(peerRecord.mNumFailures)); + prep.exchange(use(peerRecord.mType)); std::string ip = address.getIP(); - st.exchange(use(ip)); + prep.exchange(use(ip)); int port = address.getPort(); - st.exchange(use(port)); - st.define_and_bind(); + prep.exchange(use(port)); + prep.define_and_bind(); { auto timer = mApp.getDatabase().getUpdateTimer("peer"); - st.execute(true); - if (st.get_affected_rows() != 1) + prep.execute(true); + if (prep.get_affected_rows() != 1) { CLOG_ERROR(Overlay, "PeerManager::store failed on {}", address.toString()); @@ -514,13 +511,12 @@ PeerManager::countPeers(std::string const& where, auto prep = mApp.getDatabase().getPreparedStatement( sql, mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - bind(st); - st.exchange(into(count)); + bind(prep); + prep.exchange(into(count)); - st.define_and_bind(); - st.execute(true); + prep.define_and_bind(); + prep.execute(true); } catch (soci_error& err) { @@ -545,29 +541,28 @@ PeerManager::loadPeers(size_t limit, size_t offset, std::string const& where, auto prep = mApp.getDatabase().getPreparedStatement( sql, mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - bind(st); - st.exchange(use(limit)); - st.exchange(use(offset)); + bind(prep); + prep.exchange(use(limit)); + prep.exchange(use(offset)); std::string ip; int lport; - st.exchange(into(ip)); - st.exchange(into(lport)); + prep.exchange(into(ip)); + prep.exchange(into(lport)); - st.define_and_bind(); + prep.define_and_bind(); { auto timer = mApp.getDatabase().getSelectTimer("peer"); - st.execute(true); + prep.execute(true); } - while (st.got_data()) + while (prep.got_data()) { if (!ip.empty() && lport > 0) { result.emplace_back(ip, static_cast(lport)); } - st.fetch(); + prep.fetch(); } } catch (soci_error& err) @@ -601,24 +596,23 @@ PeerManager::loadAllPeers() auto prep = mApp.getDatabase().getPreparedStatement( sql, mApp.getDatabase().getMiscSession()); - auto& st = prep.statement(); - st.exchange(into(ip)); - st.exchange(into(port)); - st.exchange(into(record.mNextAttempt)); - st.exchange(into(record.mNumFailures)); - st.exchange(into(record.mType)); + prep.exchange(into(ip)); + prep.exchange(into(port)); + prep.exchange(into(record.mNextAttempt)); + prep.exchange(into(record.mNumFailures)); + prep.exchange(into(record.mType)); - st.define_and_bind(); + prep.define_and_bind(); { auto timer = mApp.getDatabase().getSelectTimer("peer"); - st.execute(true); + prep.execute(true); } - while (st.got_data()) + while (prep.got_data()) { PeerBareAddress pba{ip, static_cast(port)}; result.emplace_back(std::make_pair(pba, record)); - st.fetch(); + prep.fetch(); } } catch (soci_error& err) From b0fa8c02f6d7a6100d670e894d623b5fed4bf174 Mon Sep 17 00:00:00 2001 From: "nasihudeen04@gmail.com" Date: Sat, 14 Mar 2026 01:54:50 +0100 Subject: [PATCH 2/2] Refactor: remove redundant StatementContext and use soci::statement directly --- src/ledger/LedgerTxnOfferSQL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ledger/LedgerTxnOfferSQL.cpp b/src/ledger/LedgerTxnOfferSQL.cpp index 517843f69f..872ceea4ce 100644 --- a/src/ledger/LedgerTxnOfferSQL.cpp +++ b/src/ledger/LedgerTxnOfferSQL.cpp @@ -786,7 +786,7 @@ class BulkLoadOffersOperation "FROM offers WHERE offerid IN carray(?, ?, 'int64')"; auto prep = mDb.getPreparedStatement(sql, mSession); - auto be = prep.statement().get_backend(); + auto be = prep.get_backend(); if (be == nullptr) { throw std::runtime_error("no sql backend");