void TrustFrame::storeAdd(LedgerDelta& delta, Database& db) { if (!isValid()) { throw std::runtime_error("Invalid TrustEntry"); } auto key = getKey(); flushCachedEntry(key, db); if (mIsIssuer) return; touch(delta); std::string actIDStrKey, issuerStrKey, assetCode; unsigned int assetType = getKey().trustLine().asset.type(); getKeyFields(getKey(), actIDStrKey, issuerStrKey, assetCode); auto prep = db.getPreparedStatement( "INSERT INTO trustlines " "(accountid, assettype, issuer, assetcode, balance, tlimit, flags, " "lastmodified) " "VALUES (:v1, :v2, :v3, :v4, :v5, :v6, :v7, :v8)"); auto& st = prep.statement(); st.exchange(use(actIDStrKey)); st.exchange(use(assetType)); st.exchange(use(issuerStrKey)); st.exchange(use(assetCode)); st.exchange(use(mTrustLine.balance)); st.exchange(use(mTrustLine.limit)); st.exchange(use(mTrustLine.flags)); st.exchange(use(getLastModified())); st.define_and_bind(); { auto timer = db.getInsertTimer("trust"); st.execute(true); } if (st.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } delta.addEntry(*this); }
void AccountFrame::storeUpdate(LedgerDelta& delta, Database& db, bool insert) { assert(isValid()); touch(delta); flushCachedEntry(db); std::string actIDStrKey = PubKeyUtils::toStrKey(mAccountEntry.accountID); std::string sql; if (insert) { sql = std::string( "INSERT INTO accounts ( accountid, balance, seqnum, " "numsubentries, inflationdest, homedomain, thresholds, flags, " "lastmodified ) " "VALUES ( :id, :v1, :v2, :v3, :v4, :v5, :v6, :v7, :v8 )"); } else { sql = std::string( "UPDATE accounts SET balance = :v1, seqnum = :v2, " "numsubentries = :v3, " "inflationdest = :v4, homedomain = :v5, thresholds = :v6, " "flags = :v7, lastmodified = :v8 WHERE accountid = :id"); } auto prep = db.getPreparedStatement(sql); soci::indicator inflation_ind = soci::i_null; string inflationDestStrKey; if (mAccountEntry.inflationDest) { inflationDestStrKey = PubKeyUtils::toStrKey(*mAccountEntry.inflationDest); inflation_ind = soci::i_ok; } string thresholds(bn::encode_b64(mAccountEntry.thresholds)); { soci::statement& st = prep.statement(); st.exchange(use(actIDStrKey, "id")); st.exchange(use(mAccountEntry.balance, "v1")); st.exchange(use(mAccountEntry.seqNum, "v2")); st.exchange(use(mAccountEntry.numSubEntries, "v3")); st.exchange(use(inflationDestStrKey, inflation_ind, "v4")); string homeDomain(mAccountEntry.homeDomain); st.exchange(use(homeDomain, "v5")); st.exchange(use(thresholds, "v6")); st.exchange(use(mAccountEntry.flags, "v7")); st.exchange(use(getLastModified(), "v8")); st.define_and_bind(); { auto timer = insert ? db.getInsertTimer("account") : db.getUpdateTimer("account"); st.execute(true); } if (st.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } if (insert) { delta.addEntry(*this); } else { delta.modEntry(*this); } } if (mUpdateSigners) { applySigners(db); } }
void OfferFrame::storeUpdateHelper(LedgerDelta& delta, Database& db, bool insert) { touch(delta); if (!isValid()) { throw std::runtime_error("Invalid asset"); } std::string actIDStrKey = PubKeyUtils::toStrKey(mOffer.sellerID); unsigned int sellingType = mOffer.selling.type(); unsigned int buyingType = mOffer.buying.type(); std::string sellingIssuerStrKey, buyingIssuerStrKey; std::string sellingAssetCode, buyingAssetCode; soci::indicator selling_ind = soci::i_null, buying_ind = soci::i_null; if (sellingType == ASSET_TYPE_CREDIT_ALPHANUM4) { sellingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.selling.alphaNum4().issuer); assetCodeToStr(mOffer.selling.alphaNum4().assetCode, sellingAssetCode); selling_ind = soci::i_ok; } else if (sellingType == ASSET_TYPE_CREDIT_ALPHANUM12) { sellingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.selling.alphaNum12().issuer); assetCodeToStr(mOffer.selling.alphaNum12().assetCode, sellingAssetCode); selling_ind = soci::i_ok; } if (buyingType == ASSET_TYPE_CREDIT_ALPHANUM4) { buyingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.buying.alphaNum4().issuer); assetCodeToStr(mOffer.buying.alphaNum4().assetCode, buyingAssetCode); buying_ind = soci::i_ok; } else if (buyingType == ASSET_TYPE_CREDIT_ALPHANUM12) { buyingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.buying.alphaNum12().issuer); assetCodeToStr(mOffer.buying.alphaNum12().assetCode, buyingAssetCode); buying_ind = soci::i_ok; } string sql; if (insert) { sql = "INSERT INTO offers (sellerid,offerid," "sellingassettype,sellingassetcode,sellingissuer," "buyingassettype,buyingassetcode,buyingissuer," "amount,pricen,priced,price,flags,lastmodified) VALUES " "(:sid,:oid,:sat,:sac,:si,:bat,:bac,:bi,:a,:pn,:pd,:p,:f,:l)"; } else { sql = "UPDATE offers SET sellingassettype=:sat " ",sellingassetcode=:sac,sellingissuer=:si," "buyingassettype=:bat,buyingassetcode=:bac,buyingissuer=:bi," "amount=:a,pricen=:pn,priced=:pd,price=:p,flags=:f," "lastmodified=:l WHERE offerid=:oid"; } auto prep = db.getPreparedStatement(sql); auto& st = prep.statement(); if (insert) { st.exchange(use(actIDStrKey, "sid")); } st.exchange(use(mOffer.offerID, "oid")); st.exchange(use(sellingType, "sat")); st.exchange(use(sellingAssetCode, selling_ind, "sac")); st.exchange(use(sellingIssuerStrKey, selling_ind, "si")); st.exchange(use(buyingType, "bat")); st.exchange(use(buyingAssetCode, buying_ind, "bac")); st.exchange(use(buyingIssuerStrKey, buying_ind, "bi")); st.exchange(use(mOffer.amount, "a")); st.exchange(use(mOffer.price.n, "pn")); st.exchange(use(mOffer.price.d, "pd")); auto price = computePrice(); st.exchange(use(price, "p")); st.exchange(use(mOffer.flags, "f")); st.exchange(use(getLastModified(), "l")); st.define_and_bind(); auto timer = insert ? db.getInsertTimer("offer") : db.getUpdateTimer("offer"); st.execute(true); if (st.get_affected_rows() != 1) { throw std::runtime_error("could not update SQL"); } if (insert) { delta.addEntry(*this); } else { delta.modEntry(*this); } }
void AccountFrame::storeUpdate(LedgerDelta& delta, Database& db, bool insert) const { flushCachedEntry(db); std::string actIDStrKey = PubKeyUtils::toStrKey(mAccountEntry.accountID); std::string sql; if (insert) { sql = std::string( "INSERT INTO accounts ( accountid, balance, seqnum, " "numsubentries, inflationdest, homedomain, thresholds, flags) " "VALUES ( :id, :v1, :v2, :v3, :v4, :v5, :v6, :v7 )"); } else { sql = std::string( "UPDATE accounts SET balance = :v1, seqnum = :v2, " "numsubentries = :v3, " "inflationdest = :v4, homedomain = :v5, thresholds = :v6, " "flags = :v7 WHERE accountid = :id"); } auto prep = db.getPreparedStatement(sql); soci::indicator inflation_ind = soci::i_null; string inflationDestStrKey; if (mAccountEntry.inflationDest) { inflationDestStrKey = PubKeyUtils::toStrKey(*mAccountEntry.inflationDest); inflation_ind = soci::i_ok; } string thresholds(bn::encode_b64(mAccountEntry.thresholds)); { soci::statement& st = prep.statement(); st.exchange(use(actIDStrKey, "id")); st.exchange(use(mAccountEntry.balance, "v1")); st.exchange(use(mAccountEntry.seqNum, "v2")); st.exchange(use(mAccountEntry.numSubEntries, "v3")); st.exchange(use(inflationDestStrKey, inflation_ind, "v4")); st.exchange(use(string(mAccountEntry.homeDomain), "v5")); st.exchange(use(thresholds, "v6")); st.exchange(use(mAccountEntry.flags, "v7")); st.define_and_bind(); { auto timer = insert ? db.getInsertTimer("account") : db.getUpdateTimer("account"); st.execute(true); } if (st.get_affected_rows() != 1) { throw std::runtime_error("Could not update data in SQL"); } if (insert) { delta.addEntry(*this); } else { delta.modEntry(*this); } } if (mUpdateSigners) { // instead separate signatures from account, just like offers are // separate entities AccountFrame::pointer startAccountFrame; startAccountFrame = loadAccount(getID(), db); if (!startAccountFrame) { throw runtime_error("could not load account!"); } AccountEntry& startAccount = startAccountFrame->mAccountEntry; // deal with changes to Signers if (mAccountEntry.signers.size() < startAccount.signers.size()) { // some signers were removed for (auto const& startSigner : startAccount.signers) { bool found = false; for (auto const& finalSigner : mAccountEntry.signers) { if (finalSigner.pubKey == startSigner.pubKey) { if (finalSigner.weight != startSigner.weight) { std::string signerStrKey = PubKeyUtils::toStrKey(finalSigner.pubKey); { auto timer = db.getUpdateTimer("signer"); db.getSession() << "UPDATE signers set weight=:v1 where " "accountid=:v2 and publickey=:v3", use(finalSigner.weight), use(actIDStrKey), use(signerStrKey); } } found = true; break; } } if (!found) { // delete signer std::string signerStrKey = PubKeyUtils::toStrKey(startSigner.pubKey); soci::statement st = (db.getSession().prepare << "DELETE from signers where " "accountid=:v2 and " "publickey=:v3", use(actIDStrKey), use(signerStrKey)); { auto timer = db.getDeleteTimer("signer"); st.execute(true); } if (st.get_affected_rows() != 1) { throw std::runtime_error( "Could not update data in SQL"); } } } } else { // signers added or the same for (auto const& finalSigner : mAccountEntry.signers) { bool found = false; for (auto const& startSigner : startAccount.signers) { if (finalSigner.pubKey == startSigner.pubKey) { if (finalSigner.weight != startSigner.weight) { std::string signerStrKey = PubKeyUtils::toStrKey(finalSigner.pubKey); soci::statement st = (db.getSession().prepare << "UPDATE signers set weight=:v1 where " "accountid=:v2 and publickey=:v3", use(finalSigner.weight), use(actIDStrKey), use(signerStrKey)); st.execute(true); if (st.get_affected_rows() != 1) { throw std::runtime_error( "Could not update data in SQL"); } } found = true; break; } } if (!found) { // new signer std::string signerStrKey = PubKeyUtils::toStrKey(finalSigner.pubKey); soci::statement st = (db.getSession().prepare << "INSERT INTO signers " "(accountid,publickey,weight) " "VALUES (:v1,:v2,:v3)", use(actIDStrKey), use(signerStrKey), use(finalSigner.weight)); st.execute(true); if (st.get_affected_rows() != 1) { throw std::runtime_error( "Could not update data in SQL"); } } } } // Flush again to ensure changed signers are reloaded. flushCachedEntry(db); } }
void OfferFrame::storeAdd(LedgerDelta& delta, Database& db) const { std::string actIDStrKey = PubKeyUtils::toStrKey(mOffer.sellerID); soci::statement st(db.getSession().prepare << "select 1"); auto timer = db.getInsertTimer("offer"); unsigned int sellingType = mOffer.selling.type(); unsigned int buyingType = mOffer.buying.type(); std::string sellingIssuerStrKey, buyingIssuerStrKey; std::string sellingAssetCode, buyingAssetCode; if(sellingType == ASSET_TYPE_CREDIT_ALPHANUM4) { sellingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.selling.alphaNum4().issuer); assetCodeToStr(mOffer.selling.alphaNum4().assetCode, sellingAssetCode); } else if(sellingType == ASSET_TYPE_CREDIT_ALPHANUM12) { sellingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.selling.alphaNum12().issuer); assetCodeToStr(mOffer.selling.alphaNum12().assetCode, sellingAssetCode); } if(buyingType == ASSET_TYPE_CREDIT_ALPHANUM4) { buyingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.buying.alphaNum4().issuer); assetCodeToStr(mOffer.buying.alphaNum4().assetCode, buyingAssetCode); } else if(buyingType == ASSET_TYPE_CREDIT_ALPHANUM12) { buyingIssuerStrKey = PubKeyUtils::toStrKey(mOffer.buying.alphaNum12().issuer); assetCodeToStr(mOffer.buying.alphaNum12().assetCode, buyingAssetCode); } st = (db.getSession().prepare << "INSERT INTO offers (sellerid,offerid," "sellingassettype,sellingassetcode,sellingissuer," "buyingassettype,buyingassetcode,buyingissuer," "amount,pricen,priced,price,flags) VALUES " "(:v1,:v2,:v3,:v4,:v5,:v6,:v7,:v8,:v9,:v10,:v11,:v12,:v13)", use(actIDStrKey), use(mOffer.offerID), use(sellingType), use(sellingAssetCode), use(sellingIssuerStrKey), use(buyingType), use(buyingAssetCode), use(buyingIssuerStrKey), use(mOffer.amount), use(mOffer.price.n), use(mOffer.price.d), use(computePrice()), use(mOffer.flags)); st.execute(true); if (st.get_affected_rows() != 1) { throw std::runtime_error("could not update SQL"); } delta.addEntry(*this); }