119 ripple::AccountID
const& issuer,
120 std::optional<std::uint32_t>
const& taxon,
121 std::uint32_t
const ledgerSequence,
122 std::uint32_t
const limit,
123 std::optional<ripple::uint256>
const& cursorIn,
124 boost::asio::yield_context yield
129 Statement
const idQueryStatement = [&taxon, &issuer, &cursorIn, &limit,
this]() {
130 if (taxon.has_value()) {
131 auto r = schema_->selectNFTIDsByIssuerTaxon.bind(issuer);
133 r.bindAt(2, cursorIn.value_or(ripple::uint256(0)));
134 r.bindAt(3,
Limit{limit});
138 auto r = schema_->selectNFTIDsByIssuer.bind(issuer);
142 cursorIn.has_value() ? ripple::nft::toUInt32(ripple::nft::getTaxon(*cursorIn)) : 0,
143 cursorIn.value_or(ripple::uint256(0))
146 r.bindAt(2,
Limit{limit});
151 auto const res = executor_.read(yield, idQueryStatement);
153 auto const& idQueryResults = res.value();
154 if (not idQueryResults.hasRows()) {
155 LOG(log_.debug()) <<
"No rows returned";
159 std::vector<ripple::uint256> nftIDs;
161 nftIDs.push_back(nftID);
166 if (nftIDs.size() == limit)
167 ret.cursor = nftIDs.back();
169 std::vector<Statement> selectNFTStatements;
170 selectNFTStatements.reserve(nftIDs.size());
173 std::cbegin(nftIDs), std::cend(nftIDs), std::back_inserter(selectNFTStatements), [&](
auto const& nftID) {
174 return schema_->selectNFT.bind(nftID, ledgerSequence);
178 auto const nftInfos = executor_.readEach(yield, selectNFTStatements);
180 std::vector<Statement> selectNFTURIStatements;
181 selectNFTURIStatements.reserve(nftIDs.size());
184 std::cbegin(nftIDs), std::cend(nftIDs), std::back_inserter(selectNFTURIStatements), [&](
auto const& nftID) {
185 return schema_->selectNFTURI.bind(nftID, ledgerSequence);
189 auto const nftUris = executor_.readEach(yield, selectNFTURIStatements);
191 for (
auto i = 0u; i < nftIDs.size(); i++) {
192 if (
auto const maybeRow = nftInfos[i].
template get<uint32_t, ripple::AccountID, bool>();
193 maybeRow.has_value()) {
194 auto [seq, owner, isBurned] = *maybeRow;
195 NFT nft(nftIDs[i], seq, owner, isBurned);
196 if (
auto const maybeUri = nftUris[i].
template get<ripple::Blob>(); maybeUri.has_value())
198 ret.nfts.push_back(nft);
206 std::uint32_t number,
207 std::uint32_t pageSize,
209 boost::asio::yield_context yield
212 std::vector<ripple::uint256> liveAccounts;
213 std::optional<ripple::AccountID> lastItem;
215 while (liveAccounts.size() < number) {
216 Statement
const statement = lastItem ? schema_->selectAccountFromToken.bind(*lastItem,
Limit{pageSize})
217 : schema_->selectAccountFromBeginning.bind(
Limit{pageSize});
219 auto const res = executor_.read(yield, statement);
221 auto const& results = res.value();
222 if (not results.hasRows()) {
223 LOG(log_.debug()) <<
"No rows returned";
227 std::vector<ripple::uint256> fullAccounts;
229 fullAccounts.push_back(ripple::keylet::account(account).key);
234 for (
auto i = 0u; i < fullAccounts.size(); i++) {
235 if (not objs[i].empty()) {
236 if (liveAccounts.size() < number) {
237 liveAccounts.push_back(fullAccounts[i]);
244 LOG(log_.error()) <<
"Could not fetch account from account_tx: " << res.error();