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 {
|
public List<TransactionData> fetchAllTransactionsInvolvingName(String name, Repository repository) throws DataException {
|
||||||
List<TransactionData> transactions = new ArrayList<>();
|
return repository.getTransactionRepository().getTransactionsInvolvingName(name, ConfirmationStatus.CONFIRMED);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransactionData fetchLatestModificationTransactionInvolvingName(String registeredName, Repository repository) throws DataException {
|
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;
|
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.
|
* 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.ApprovalStatus;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
import org.qortal.utils.Base58;
|
import org.qortal.utils.Base58;
|
||||||
|
import org.qortal.utils.Unicode;
|
||||||
|
|
||||||
public class HSQLDBTransactionRepository implements TransactionRepository {
|
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
|
@Override
|
||||||
public List<TransactionData> getAssetTransactions(long assetId, ConfirmationStatus confirmationStatus, Integer limit, Integer offset, Boolean reverse)
|
public List<TransactionData> getAssetTransactions(long assetId, ConfirmationStatus confirmationStatus, Integer limit, Integer offset, Boolean reverse)
|
||||||
throws DataException {
|
throws DataException {
|
||||||
|
@ -125,7 +125,6 @@ public class IntegrityTests extends Common {
|
|||||||
TransactionUtils.signAndMint(repository, updateTransactionData, alice);
|
TransactionUtils.signAndMint(repository, updateTransactionData, alice);
|
||||||
|
|
||||||
// Register emoji name
|
// Register emoji name
|
||||||
PrivateKeyAccount bob = Common.getTestAccount(repository, "bob");
|
|
||||||
String emojiName = "\uD83E\uDD73"; // Translates to a reducedName of ""
|
String emojiName = "\uD83E\uDD73"; // Translates to a reducedName of ""
|
||||||
|
|
||||||
// Ensure that the initial_name isn't associated with the emoji name
|
// Ensure that the initial_name isn't associated with the emoji name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user