mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
@@ -494,41 +494,39 @@ public:
|
||||
if (nftIDs.size() == limit)
|
||||
ret.cursor = nftIDs.back();
|
||||
|
||||
auto const nftQueryStatement = schema_->selectNFTBulk.bind(nftIDs);
|
||||
nftQueryStatement.bindAt(1, ledgerSequence);
|
||||
std::vector<Statement> selectNFTStatements;
|
||||
selectNFTStatements.reserve(nftIDs.size());
|
||||
|
||||
// Fetch all the NFT data, meanwhile filtering out the NFTs that are not within the ledger range
|
||||
auto const nftRes = executor_.read(yield, nftQueryStatement);
|
||||
auto const& nftQueryResults = nftRes.value();
|
||||
std::transform(
|
||||
std::cbegin(nftIDs),
|
||||
std::cend(nftIDs),
|
||||
std::back_inserter(selectNFTStatements),
|
||||
[&](auto const& nftID) { return schema_->selectNFT.bind(nftID, ledgerSequence); }
|
||||
);
|
||||
|
||||
if (not nftQueryResults.hasRows()) {
|
||||
LOG(log_.debug()) << "No rows returned";
|
||||
return {};
|
||||
auto const nftInfos = executor_.readEach(yield, selectNFTStatements);
|
||||
|
||||
std::vector<Statement> selectNFTURIStatements;
|
||||
selectNFTURIStatements.reserve(nftIDs.size());
|
||||
|
||||
std::transform(
|
||||
std::cbegin(nftIDs),
|
||||
std::cend(nftIDs),
|
||||
std::back_inserter(selectNFTURIStatements),
|
||||
[&](auto const& nftID) { return schema_->selectNFTURI.bind(nftID, ledgerSequence); }
|
||||
);
|
||||
|
||||
auto const nftUris = executor_.readEach(yield, selectNFTURIStatements);
|
||||
|
||||
for (auto i = 0u; i < nftIDs.size(); i++) {
|
||||
if (auto const maybeRow = nftInfos[i].template get<uint32_t, ripple::AccountID, bool>(); maybeRow) {
|
||||
auto [seq, owner, isBurned] = *maybeRow;
|
||||
NFT nft(nftIDs[i], seq, owner, isBurned);
|
||||
if (auto const maybeUri = nftUris[i].template get<ripple::Blob>(); maybeUri)
|
||||
nft.uri = *maybeUri;
|
||||
ret.nfts.push_back(nft);
|
||||
}
|
||||
}
|
||||
|
||||
auto const nftURIQueryStatement = schema_->selectNFTURIBulk.bind(nftIDs);
|
||||
nftURIQueryStatement.bindAt(1, ledgerSequence);
|
||||
|
||||
// Get the URI for each NFT, but it's possible that URI doesn't exist
|
||||
auto const uriRes = executor_.read(yield, nftURIQueryStatement);
|
||||
auto const& nftURIQueryResults = uriRes.value();
|
||||
|
||||
std::unordered_map<std::string, Blob> nftURIMap;
|
||||
for (auto const [nftID, uri] : extract<ripple::uint256, Blob>(nftURIQueryResults))
|
||||
nftURIMap.insert({ripple::strHex(nftID), uri});
|
||||
|
||||
for (auto const [nftID, seq, owner, isBurned] :
|
||||
extract<ripple::uint256, std::uint32_t, ripple::AccountID, bool>(nftQueryResults)) {
|
||||
NFT nft;
|
||||
nft.tokenID = nftID;
|
||||
nft.ledgerSequence = seq;
|
||||
nft.owner = owner;
|
||||
nft.isBurned = isBurned;
|
||||
if (nftURIMap.contains(ripple::strHex(nft.tokenID)))
|
||||
nft.uri = nftURIMap.at(ripple::strHex(nft.tokenID));
|
||||
ret.nfts.push_back(nft);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -592,20 +592,6 @@ public:
|
||||
));
|
||||
}();
|
||||
|
||||
PreparedStatement selectNFTBulk = [this]() {
|
||||
return handle_.get().prepare(fmt::format(
|
||||
R"(
|
||||
SELECT token_id, sequence, owner, is_burned
|
||||
FROM {}
|
||||
WHERE token_id IN ?
|
||||
AND sequence <= ?
|
||||
ORDER BY sequence DESC
|
||||
PER PARTITION LIMIT 1
|
||||
)",
|
||||
qualifiedTableName(settingsProvider_.get(), "nf_tokens")
|
||||
));
|
||||
}();
|
||||
|
||||
PreparedStatement selectNFTURI = [this]() {
|
||||
return handle_.get().prepare(fmt::format(
|
||||
R"(
|
||||
@@ -620,20 +606,6 @@ public:
|
||||
));
|
||||
}();
|
||||
|
||||
PreparedStatement selectNFTURIBulk = [this]() {
|
||||
return handle_.get().prepare(fmt::format(
|
||||
R"(
|
||||
SELECT token_id, uri
|
||||
FROM {}
|
||||
WHERE token_id IN ?
|
||||
AND sequence <= ?
|
||||
ORDER BY sequence DESC
|
||||
PER PARTITION LIMIT 1
|
||||
)",
|
||||
qualifiedTableName(settingsProvider_.get(), "nf_token_uris")
|
||||
));
|
||||
}();
|
||||
|
||||
PreparedStatement selectNFTTx = [this]() {
|
||||
return handle_.get().prepare(fmt::format(
|
||||
R"(
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <data/BackendInterface.h>
|
||||
#include <rpc/RPCHelpers.h>
|
||||
#include <rpc/JS.h>
|
||||
#include <rpc/common/Modifiers.h>
|
||||
#include <rpc/common/Types.h>
|
||||
#include <rpc/common/Validators.h>
|
||||
|
||||
@@ -321,16 +321,6 @@ TEST_F(RPCNFTsByIssuerHandlerTest, NonExistLedgerViaLedgerIndex2)
|
||||
// normal case when issuer does not exist or has no NFTs
|
||||
TEST_F(RPCNFTsByIssuerHandlerTest, AccountNotFound)
|
||||
{
|
||||
auto const currentOutput = fmt::format(
|
||||
R"({{
|
||||
"issuer": "{}",
|
||||
"limit":50,
|
||||
"ledger_index": 30,
|
||||
"nfts": [],
|
||||
"validated": true
|
||||
}})",
|
||||
ACCOUNT
|
||||
);
|
||||
MockBackend* rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
|
||||
ASSERT_NE(rawBackendPtr, nullptr);
|
||||
mockBackendPtr->updateRange(10); // min
|
||||
@@ -667,4 +657,4 @@ TEST_F(RPCNFTsByIssuerHandlerTest, LimitMoreThanMAx)
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_EQ(json::parse(currentOutput), *output);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user