forked from Qortal/qortal
Rewrite of fetchAllTransactionsInvolvingName() to avoid having to load all name transactions into memory.
This commit is contained in:
parent
4e59eb8958
commit
6dec65c5d9
@ -320,46 +320,7 @@ public class NamesDatabaseIntegrityCheck {
|
||||
}
|
||||
|
||||
public List<TransactionData> fetchAllTransactionsInvolvingName(String name, Repository repository) throws DataException {
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
String reducedName = Unicode.sanitize(name);
|
||||
|
||||
// Fetch all the confirmed name-modification transactions
|
||||
if (this.nameTransactions.isEmpty()) {
|
||||
this.fetchAllNameTransactions(repository);
|
||||
}
|
||||
|
||||
for (TransactionData transactionData : this.nameTransactions) {
|
||||
|
||||
if ((transactionData instanceof RegisterNameTransactionData)) {
|
||||
RegisterNameTransactionData registerNameTransactionData = (RegisterNameTransactionData) transactionData;
|
||||
if (Objects.equals(registerNameTransactionData.getName(), name) ||
|
||||
Objects.equals(registerNameTransactionData.getReducedName(), reducedName)) {
|
||||
transactions.add(transactionData);
|
||||
}
|
||||
}
|
||||
if ((transactionData instanceof UpdateNameTransactionData)) {
|
||||
UpdateNameTransactionData updateNameTransactionData = (UpdateNameTransactionData) transactionData;
|
||||
boolean hasReducedNewName = updateNameTransactionData.getReducedNewName() == null && !updateNameTransactionData.getReducedNewName().isEmpty();
|
||||
if (Objects.equals(updateNameTransactionData.getName(), name) ||
|
||||
(hasReducedNewName && Objects.equals(updateNameTransactionData.getReducedNewName(), reducedName)) ||
|
||||
Objects.equals(updateNameTransactionData.getNewName(), name)) {
|
||||
transactions.add(transactionData);
|
||||
}
|
||||
}
|
||||
if ((transactionData instanceof BuyNameTransactionData)) {
|
||||
BuyNameTransactionData buyNameTransactionData = (BuyNameTransactionData) transactionData;
|
||||
if (Objects.equals(buyNameTransactionData.getName(), name)) {
|
||||
transactions.add(transactionData);
|
||||
}
|
||||
}
|
||||
if ((transactionData instanceof SellNameTransactionData)) {
|
||||
SellNameTransactionData sellNameTransactionData = (SellNameTransactionData) transactionData;
|
||||
if (Objects.equals(sellNameTransactionData.getName(), name)) {
|
||||
transactions.add(transactionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
return transactions;
|
||||
return repository.getTransactionRepository().getTransactionsInvolvingName(name, ConfirmationStatus.CONFIRMED);
|
||||
}
|
||||
|
||||
private TransactionData fetchLatestModificationTransactionInvolvingName(String registeredName, Repository repository) throws DataException {
|
||||
|
@ -125,6 +125,17 @@ public interface TransactionRepository {
|
||||
*/
|
||||
public byte[] getLatestAutoUpdateTransaction(TransactionType txType, int txGroupId, Integer service) throws DataException;
|
||||
|
||||
/**
|
||||
* Returns signatures for all name-registration related transactions relating to supplied name.
|
||||
* Note: this does not currently include ARBITRARY data relating to the name.
|
||||
*
|
||||
* @param name
|
||||
* @param confirmationStatus
|
||||
* @return
|
||||
* @throws DataException
|
||||
*/
|
||||
public List<TransactionData> getTransactionsInvolvingName(String name, ConfirmationStatus confirmationStatus) throws DataException;
|
||||
|
||||
/**
|
||||
* Returns list of transactions relating to specific asset ID.
|
||||
*
|
||||
|
@ -30,6 +30,7 @@ import org.qortal.repository.hsqldb.HSQLDBSaver;
|
||||
import org.qortal.transaction.Transaction.ApprovalStatus;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
import org.qortal.utils.Base58;
|
||||
import org.qortal.utils.Unicode;
|
||||
|
||||
public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
|
||||
@ -700,6 +701,88 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TransactionData> getTransactionsInvolvingName(String name, ConfirmationStatus confirmationStatus) throws DataException {
|
||||
TransactionType[] transactionTypes = new TransactionType[] {
|
||||
REGISTER_NAME, UPDATE_NAME, BUY_NAME, SELL_NAME
|
||||
}; // TODO: CancelSellNameTransaction?
|
||||
|
||||
String reducedName = Unicode.sanitize(name);
|
||||
|
||||
StringBuilder sql = new StringBuilder(1024);
|
||||
List<Object> bindParams = new ArrayList<>();
|
||||
sql.append("SELECT Transactions.signature FROM Transactions");
|
||||
|
||||
for (int ti = 0; ti < transactionTypes.length; ++ti) {
|
||||
sql.append(" LEFT OUTER JOIN ");
|
||||
sql.append(transactionTypes[ti].className);
|
||||
sql.append("Transactions USING (signature)");
|
||||
}
|
||||
|
||||
sql.append(" WHERE Transactions.type IN (");
|
||||
for (int ti = 0; ti < transactionTypes.length; ++ti) {
|
||||
if (ti != 0)
|
||||
sql.append(", ");
|
||||
|
||||
sql.append(transactionTypes[ti].value);
|
||||
}
|
||||
sql.append(")");
|
||||
|
||||
// Confirmation status
|
||||
switch (confirmationStatus) {
|
||||
case BOTH:
|
||||
break;
|
||||
|
||||
case CONFIRMED:
|
||||
sql.append(" AND Transactions.block_height IS NOT NULL");
|
||||
break;
|
||||
|
||||
case UNCONFIRMED:
|
||||
sql.append(" AND Transactions.block_height IS NULL");
|
||||
break;
|
||||
}
|
||||
|
||||
sql.append(" AND (RegisterNameTransactions.name = ?");
|
||||
bindParams.add(name);
|
||||
sql.append(" OR RegisterNameTransactions.reduced_name = ?");
|
||||
bindParams.add(reducedName);
|
||||
sql.append(" OR UpdateNameTransactions.name = ?");
|
||||
bindParams.add(name);
|
||||
sql.append(" OR (UpdateNameTransactions.reduced_new_name != '' AND UpdateNameTransactions.reduced_new_name = ?)");
|
||||
bindParams.add(reducedName);
|
||||
sql.append(" OR UpdateNameTransactions.new_name = ?");
|
||||
bindParams.add(name);
|
||||
sql.append(" OR SellNameTransactions.name = ?");
|
||||
bindParams.add(name);
|
||||
sql.append(" OR BuyNameTransactions.name = ?");
|
||||
bindParams.add(name);
|
||||
|
||||
sql.append(") GROUP BY Transactions.signature, Transactions.created_when ORDER BY Transactions.created_when");
|
||||
|
||||
List<TransactionData> transactions = new ArrayList<>();
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
|
||||
if (resultSet == null)
|
||||
return transactions;
|
||||
|
||||
do {
|
||||
byte[] signature = resultSet.getBytes(1);
|
||||
|
||||
TransactionData transactionData = this.fromSignature(signature);
|
||||
|
||||
if (transactionData == null)
|
||||
// Something inconsistent with the repository
|
||||
throw new DataException("Unable to fetch name-related transaction from repository?");
|
||||
|
||||
transactions.add(transactionData);
|
||||
} while (resultSet.next());
|
||||
|
||||
return transactions;
|
||||
} catch (SQLException | DataException e) {
|
||||
throw new DataException("Unable to fetch name-related transactions from repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TransactionData> getAssetTransactions(long assetId, ConfirmationStatus confirmationStatus, Integer limit, Integer offset, Boolean reverse)
|
||||
throws DataException {
|
||||
|
@ -125,7 +125,6 @@ public class IntegrityTests extends Common {
|
||||
TransactionUtils.signAndMint(repository, updateTransactionData, alice);
|
||||
|
||||
// Register emoji name
|
||||
PrivateKeyAccount bob = Common.getTestAccount(repository, "bob");
|
||||
String emojiName = "\uD83E\uDD73"; // Translates to a reducedName of ""
|
||||
|
||||
// Ensure that the initial_name isn't associated with the emoji name
|
||||
|
Loading…
x
Reference in New Issue
Block a user