Browse Source

StringBuilder, and other, optimizations for repository-related classes.

Add optional "excludeZero" to API call GET /assets/balances

Added tests to call most API calls to check no exceptions are thrown.
pull/67/head
catbref 5 years ago
parent
commit
e47b4dceb2
  1. 2
      src/main/java/org/qora/api/resource/AdminResource.java
  2. 3
      src/main/java/org/qora/api/resource/AssetsResource.java
  3. 2
      src/main/java/org/qora/repository/AccountRepository.java
  4. 149
      src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java
  5. 217
      src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java
  6. 52
      src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java
  7. 121
      src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java
  8. 35
      src/main/java/org/qora/repository/hsqldb/HSQLDBNameRepository.java
  9. 61
      src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java
  10. 34
      src/main/java/org/qora/repository/hsqldb/HSQLDBSaver.java
  11. 24
      src/main/java/org/qora/repository/hsqldb/HSQLDBVotingRepository.java
  12. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java
  13. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java
  14. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java
  15. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java
  16. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java
  17. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java
  18. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java
  19. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java
  20. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java
  21. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java
  22. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java
  23. 4
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java
  24. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java
  25. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java
  26. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java
  27. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java
  28. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java
  29. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java
  30. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java
  31. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java
  32. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java
  33. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java
  34. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java
  35. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java
  36. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java
  37. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java
  38. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java
  39. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java
  40. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java
  41. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java
  42. 238
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java
  43. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java
  44. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java
  45. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java
  46. 2
      src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java
  47. 36
      src/test/java/org/qora/test/api/AddressesApiTests.java
  48. 29
      src/test/java/org/qora/test/api/AdminApiTests.java
  49. 154
      src/test/java/org/qora/test/api/AssetsApiTests.java
  50. 44
      src/test/java/org/qora/test/api/BlockApiTests.java
  51. 73
      src/test/java/org/qora/test/api/GroupApiTests.java
  52. 63
      src/test/java/org/qora/test/api/TransactionsApiTests.java
  53. 49
      src/test/java/org/qora/test/common/ApiCommon.java
  54. 4
      src/test/java/org/qora/test/common/Common.java

2
src/main/java/org/qora/api/resource/AdminResource.java

@ -419,7 +419,7 @@ public class AdminResource {
content = @Content(
mediaType = MediaType.TEXT_PLAIN,
schema = @Schema(
type = "string", example = "node7.mcfamily.io"
type = "string", example = "node2.qora.org"
)
)
),

3
src/main/java/org/qora/api/resource/AssetsResource.java

@ -168,6 +168,7 @@ public class AssetsResource {
})
public List<AccountBalanceData> getAssetBalances(@QueryParam("address") List<String> addresses, @QueryParam("assetid") List<Long> assetIds,
@DefaultValue(value = "ASSET_BALANCE_ACCOUNT") @QueryParam("ordering") BalanceOrdering balanceOrdering,
@QueryParam("excludeZero") Boolean excludeZero,
@Parameter( ref = "limit" ) @QueryParam("limit") Integer limit,
@Parameter( ref = "offset" ) @QueryParam("offset") Integer offset,
@Parameter( ref = "reverse" ) @QueryParam("reverse") Boolean reverse) {
@ -186,7 +187,7 @@ public class AssetsResource {
if (!repository.getAssetRepository().assetExists(assetId))
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID);
return repository.getAccountRepository().getAssetBalances(addresses, assetIds, balanceOrdering, limit, offset, reverse);
return repository.getAccountRepository().getAssetBalances(addresses, assetIds, balanceOrdering, excludeZero, limit, offset, reverse);
} catch (ApiException e) {
throw e;
} catch (DataException e) {

2
src/main/java/org/qora/repository/AccountRepository.java

@ -77,7 +77,7 @@ public interface AccountRepository {
ASSET_ACCOUNT
}
public List<AccountBalanceData> getAssetBalances(List<String> addresses, List<Long> assetIds, BalanceOrdering balanceOrdering, Integer limit, Integer offset, Boolean reverse) throws DataException;
public List<AccountBalanceData> getAssetBalances(List<String> addresses, List<Long> assetIds, BalanceOrdering balanceOrdering, Boolean excludeZero, Integer limit, Integer offset, Boolean reverse) throws DataException;
public void save(AccountBalanceData accountBalanceData) throws DataException;

149
src/main/java/org/qora/repository/hsqldb/HSQLDBAccountRepository.java

@ -5,9 +5,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.qora.data.account.AccountBalanceData;
import org.qora.data.account.AccountData;
@ -16,8 +14,6 @@ import org.qora.data.account.ProxyForgerData;
import org.qora.repository.AccountRepository;
import org.qora.repository.DataException;
import static org.qora.repository.hsqldb.HSQLDBRepository.nValuesPlaceholders;
public class HSQLDBAccountRepository implements AccountRepository {
protected HSQLDBRepository repository;
@ -30,8 +26,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public AccountData getAccount(String address) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT reference, public_key, default_group_id, flags, forging_enabler FROM Accounts WHERE account = ?", address)) {
String sql = "SELECT reference, public_key, default_group_id, flags, forging_enabler FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
if (resultSet == null)
return null;
@ -49,7 +46,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public byte[] getLastReference(String address) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT reference FROM Accounts WHERE account = ?", address)) {
String sql = "SELECT reference FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
if (resultSet == null)
return null;
@ -61,7 +60,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public Integer getDefaultGroupId(String address) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT default_group_id FROM Accounts WHERE account = ?", address)) {
String sql = "SELECT default_group_id FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
if (resultSet == null)
return null;
@ -74,7 +75,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public Integer getFlags(String address) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT flags FROM Accounts WHERE account = ?", address)) {
String sql = "SELECT flags FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
if (resultSet == null)
return null;
@ -105,8 +108,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public void ensureAccount(AccountData accountData) throws DataException {
byte[] publicKey = accountData.getPublicKey();
String sql = "SELECT public_key FROM Accounts WHERE account = ?";
try (ResultSet resultSet = this.repository.checkedExecute("SELECT public_key FROM Accounts WHERE account = ?", accountData.getAddress())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql, accountData.getAddress())) {
if (resultSet != null) {
// We know account record exists at this point.
// If accountData has no public key then we're done.
@ -212,7 +216,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public AccountBalanceData getBalance(String address, long assetId) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT balance FROM AccountBalances WHERE account = ? AND asset_id = ?", address, assetId)) {
String sql = "SELECT balance FROM AccountBalances WHERE account = ? AND asset_id = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, address, assetId)) {
if (resultSet == null)
return null;
@ -225,26 +231,48 @@ public class HSQLDBAccountRepository implements AccountRepository {
}
@Override
public List<AccountBalanceData> getAssetBalances(List<String> addresses, List<Long> assetIds, BalanceOrdering balanceOrdering, Integer limit, Integer offset, Boolean reverse)
throws DataException {
String sql = "SELECT account, asset_id, IFNULL(balance, 0), asset_name FROM ";
public List<AccountBalanceData> getAssetBalances(List<String> addresses, List<Long> assetIds, BalanceOrdering balanceOrdering, Boolean excludeZero,
Integer limit, Integer offset, Boolean reverse) throws DataException {
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT account, asset_id, IFNULL(balance, 0), asset_name FROM ");
if (!addresses.isEmpty()) {
sql += "(VALUES " + String.join(", ", Collections.nCopies(addresses.size(), "(?)")) + ") AS Accounts (account) ";
sql += "CROSS JOIN Assets LEFT OUTER JOIN AccountBalances USING (asset_id, account) ";
sql.append("(VALUES ");
final int addressesSize = addresses.size();
for (int ai = 0; ai < addressesSize; ++ai) {
if (ai != 0)
sql.append(", ");
sql.append("(?)");
}
sql.append(") AS Accounts (account) ");
sql.append("CROSS JOIN Assets LEFT OUTER JOIN AccountBalances USING (asset_id, account) ");
} else {
// Simplier, no-address query
sql += "AccountBalances NATURAL JOIN Assets ";
sql.append("AccountBalances NATURAL JOIN Assets ");
}
if (!assetIds.isEmpty())
if (!assetIds.isEmpty()) {
// longs are safe enough to use literally
sql += "WHERE asset_id IN (" + String.join(", ", assetIds.stream().map(assetId -> assetId.toString()).collect(Collectors.toList())) + ") ";
sql.append("WHERE asset_id IN (");
final int assetIdsSize = assetIds.size();
for (int ai = 0; ai < assetIdsSize; ++ai) {
if (ai != 0)
sql.append(", ");
sql.append(assetIds.get(ai));
}
sql.append(") ");
}
// For no-address queries, only return accounts with non-zero balance
if (addresses.isEmpty()) {
sql += assetIds.isEmpty() ? " WHERE " : " AND ";
sql += "balance != 0 ";
// For no-address queries, or unless specifically requested, only return accounts with non-zero balance
if (addresses.isEmpty() || (excludeZero != null && excludeZero == true)) {
sql.append(assetIds.isEmpty() ? " WHERE " : " AND ");
sql.append("balance != 0 ");
}
String[] orderingColumns;
@ -265,17 +293,22 @@ public class HSQLDBAccountRepository implements AccountRepository {
throw new DataException(String.format("Unsupported asset balance result ordering: %s", balanceOrdering.name()));
}
if (reverse != null && reverse)
orderingColumns = Arrays.stream(orderingColumns).map(column -> column + " DESC").toArray(size -> new String[size]);
sql.append("ORDER BY ");
for (int oi = 0; oi < orderingColumns.length; ++oi) {
if (oi != 0)
sql.append(", ");
sql += "ORDER BY " + String.join(", ", orderingColumns);
sql.append(orderingColumns[oi]);
if (reverse != null && reverse)
sql.append(" DESC");
}
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
String[] addressesArray = addresses.toArray(new String[addresses.size()]);
List<AccountBalanceData> accountBalances = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, (Object[]) addressesArray)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), (Object[]) addressesArray)) {
if (resultSet == null)
return accountBalances;
@ -321,8 +354,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public ProxyForgerData getProxyForgeData(byte[] forgerPublicKey, String recipient) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT proxy_public_key, share FROM ProxyForgers WHERE forger = ? AND recipient = ?",
forgerPublicKey, recipient)) {
String sql = "SELECT proxy_public_key, share FROM ProxyForgers WHERE forger = ? AND recipient = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, forgerPublicKey, recipient)) {
if (resultSet == null)
return null;
@ -337,8 +371,9 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public ProxyForgerData getProxyForgeData(byte[] proxyPublicKey) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT forger, recipient, share FROM ProxyForgers WHERE proxy_public_key = ?",
proxyPublicKey)) {
String sql = "SELECT forger, recipient, share FROM ProxyForgers WHERE proxy_public_key = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, proxyPublicKey)) {
if (resultSet == null)
return null;
@ -400,7 +435,8 @@ public class HSQLDBAccountRepository implements AccountRepository {
@Override
public List<ProxyForgerData> findProxyAccounts(List<String> recipients, List<String> forgers, List<String> involvedAddresses,
Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT DISTINCT forger, recipient, share, proxy_public_key FROM ProxyForgers ";
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT DISTINCT forger, recipient, share, proxy_public_key FROM ProxyForgers ");
List<Object> args = new ArrayList<>();
@ -409,32 +445,63 @@ public class HSQLDBAccountRepository implements AccountRepository {
final boolean hasInvolved = involvedAddresses != null && !involvedAddresses.isEmpty();
if (hasForgers || hasInvolved)
sql += "JOIN Accounts ON Accounts.public_key = ProxyForgers.forger ";
sql.append("JOIN Accounts ON Accounts.public_key = ProxyForgers.forger ");
if (hasRecipients) {
sql += "JOIN (VALUES " + nValuesPlaceholders(recipients.size()) + ") AS Recipients (address) ON ProxyForgers.recipient = Recipients.address ";
sql.append("JOIN (VALUES ");
final int recipientsSize = recipients.size();
for (int ri = 0; ri < recipientsSize; ++ri) {
if (ri != 0)
sql.append(", ");
sql.append("(?)");
}
sql.append(") AS Recipients (address) ON ProxyForgers.recipient = Recipients.address ");
args.addAll(recipients);
}
if (hasForgers) {
sql += "JOIN (VALUES " + nValuesPlaceholders(forgers.size()) + ") AS Forgers (address) ON Accounts.account = Forgers.address ";
sql.append("JOIN (VALUES ");
final int forgersSize = forgers.size();
for (int fi = 0; fi < forgersSize; ++fi) {
if (fi != 0)
sql.append(", ");
sql.append("(?)");
}
sql.append(") AS Forgers (address) ON Accounts.account = Forgers.address ");
args.addAll(forgers);
}
if (hasInvolved) {
sql += "JOIN (VALUES " + nValuesPlaceholders(involvedAddresses.size()) + ") AS Involved (address) ON Involved.address IN (ProxyForgers.recipient, Accounts.account) ";
sql.append("JOIN (VALUES ");
final int involvedAddressesSize = involvedAddresses.size();
for (int iai = 0; iai < involvedAddressesSize; ++iai) {
if (iai != 0)
sql.append(", ");
sql.append("(?)");
}
sql.append(") AS Involved (address) ON Involved.address IN (ProxyForgers.recipient, Accounts.account) ");
args.addAll(involvedAddresses);
}
sql += "ORDER BY recipient, share";
sql.append("ORDER BY recipient, share");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<ProxyForgerData> proxyAccounts = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, args.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), args.toArray())) {
if (resultSet == null)
return proxyAccounts;

217
src/main/java/org/qora/repository/hsqldb/HSQLDBAssetRepository.java

@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.qora.data.asset.AssetData;
import org.qora.data.asset.OrderData;
@ -29,9 +28,9 @@ public class HSQLDBAssetRepository implements AssetRepository {
@Override
public AssetData fromAssetId(long assetId) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_id = ?",
assetId)) {
String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_id = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, assetId)) {
if (resultSet == null)
return null;
@ -53,9 +52,9 @@ public class HSQLDBAssetRepository implements AssetRepository {
@Override
public AssetData fromAssetName(String assetName) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute(
"SELECT owner, asset_id, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_name = ?",
assetName)) {
String sql = "SELECT owner, asset_id, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets WHERE asset_name = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, assetName)) {
if (resultSet == null)
return null;
@ -95,14 +94,16 @@ public class HSQLDBAssetRepository implements AssetRepository {
@Override
public List<AssetData> getAllAssets(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT asset_id, owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets ORDER BY asset_id";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT asset_id, owner, asset_name, description, quantity, is_divisible, data, creation_group_id, reference FROM Assets ORDER BY asset_id");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<AssetData> assets = new ArrayList<AssetData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return assets;
@ -234,21 +235,21 @@ public class HSQLDBAssetRepository implements AssetRepository {
if (wantAssetData == null)
return orders;
String sql = "SELECT creator, asset_order_id, amount, fulfilled, price, ordered "
+ "FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled ";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT creator, asset_order_id, amount, fulfilled, price, ordered " + "FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled ");
sql += "ORDER BY price";
sql.append("ORDER BY price");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += ", ordered";
sql.append(", ordered");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), haveAssetId, wantAssetId)) {
if (resultSet == null)
return orders;
@ -277,9 +278,9 @@ public class HSQLDBAssetRepository implements AssetRepository {
public List<OrderData> getOpenOrdersForTrading(long haveAssetId, long wantAssetId, BigDecimal minimumPrice) throws DataException {
List<Object> bindParams = new ArrayList<>(3);
String sql = "SELECT creator, asset_order_id, amount, fulfilled, price, ordered "
+ "FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled ";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT creator, asset_order_id, amount, fulfilled, price, ordered " + "FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled ");
Collections.addAll(bindParams, haveAssetId, wantAssetId);
@ -287,22 +288,22 @@ public class HSQLDBAssetRepository implements AssetRepository {
// 'new' pricing scheme implied
// NOTE: haveAssetId and wantAssetId are for TARGET orders, so different from Order.process() caller
if (haveAssetId < wantAssetId)
sql += "AND price >= ? ";
sql.append("AND price >= ? ");
else
sql += "AND price <= ? ";
sql.append("AND price <= ? ");
bindParams.add(minimumPrice);
}
sql += "ORDER BY price";
sql.append("ORDER BY price");
if (minimumPrice == null || haveAssetId < wantAssetId)
sql += " DESC";
sql.append(" DESC");
sql += ", ordered";
sql.append(", ordered");
List<OrderData> orders = new ArrayList<OrderData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
if (resultSet == null)
return orders;
@ -342,18 +343,18 @@ public class HSQLDBAssetRepository implements AssetRepository {
if (wantAssetData == null)
return orders;
String sql = "SELECT price, SUM(amount - fulfilled), MAX(ordered) "
+ "FROM AssetOrders "
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT price, SUM(amount - fulfilled), MAX(ordered) " + "FROM AssetOrders "
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled "
+ "GROUP BY price ";
+ "GROUP BY price ");
sql += "ORDER BY price";
sql.append("ORDER BY price");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), haveAssetId, wantAssetId)) {
if (resultSet == null)
return orders;
@ -376,28 +377,32 @@ public class HSQLDBAssetRepository implements AssetRepository {
@Override
public List<OrderData> getAccountsOrders(byte[] publicKey, Boolean optIsClosed, Boolean optIsFulfilled,
Integer limit, Integer offset, Boolean reverse) throws DataException {
// We have to join for have/want asset data as it might vary
String sql = "SELECT asset_order_id, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled, HaveAsset.asset_name, WantAsset.asset_name "
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT asset_order_id, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled, HaveAsset.asset_name, WantAsset.asset_name "
+ "FROM AssetOrders "
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
+ "JOIN Assets AS WantAsset ON WantAsset.asset_id = want_asset_id "
+ "WHERE creator = ?";
+ "WHERE creator = ?");
if (optIsClosed != null)
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
if (optIsClosed != null) {
sql.append(" AND is_closed = ");
sql.append(optIsClosed ? "TRUE" : "FALSE");
}
if (optIsFulfilled != null)
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
if (optIsFulfilled != null) {
sql.append(" AND is_fulfilled = ");
sql.append(optIsFulfilled ? "TRUE" : "FALSE");
}
sql += " ORDER BY ordered";
sql.append(" ORDER BY ordered");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<OrderData> orders = new ArrayList<OrderData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, publicKey)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), publicKey)) {
if (resultSet == null)
return orders;
@ -439,23 +444,28 @@ public class HSQLDBAssetRepository implements AssetRepository {
if (wantAssetData == null)
return orders;
String sql = "SELECT asset_order_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT asset_order_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
+ "FROM AssetOrders "
+ "WHERE creator = ? AND have_asset_id = ? AND want_asset_id = ?";
+ "WHERE creator = ? AND have_asset_id = ? AND want_asset_id = ?");
if (optIsClosed != null)
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
if (optIsClosed != null) {
sql.append(" AND is_closed = ");
sql.append(optIsClosed ? "TRUE" : "FALSE");
}
if (optIsFulfilled != null)
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
if (optIsFulfilled != null) {
sql.append(" AND is_fulfilled = ");
sql.append(optIsFulfilled ? "TRUE" : "FALSE");
}
sql += " ORDER BY ordered";
sql.append(" ORDER BY ordered");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
try (ResultSet resultSet = this.repository.checkedExecute(sql, publicKey, haveAssetId, wantAssetId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), publicKey, haveAssetId, wantAssetId)) {
if (resultSet == null)
return orders;
@ -521,17 +531,18 @@ public class HSQLDBAssetRepository implements AssetRepository {
if (wantAssetData == null)
return trades;
String sql = "SELECT initiating_order_id, target_order_id, target_amount, initiator_amount, initiator_saving, traded "
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT initiating_order_id, target_order_id, target_amount, initiator_amount, initiator_saving, traded "
+ "FROM AssetOrders JOIN AssetTrades ON initiating_order_id = asset_order_id "
+ "WHERE have_asset_id = ? AND want_asset_id = ? ";
+ "WHERE have_asset_id = ? AND want_asset_id = ? ");
sql += "ORDER BY traded";
sql.append("ORDER BY traded");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), haveAssetId, wantAssetId)) {
if (resultSet == null)
return trades;
@ -558,25 +569,44 @@ public class HSQLDBAssetRepository implements AssetRepository {
public List<RecentTradeData> getRecentTrades(List<Long> assetIds, List<Long> otherAssetIds, Integer limit,
Integer offset, Boolean reverse) throws DataException {
// Find assetID pairs that have actually been traded
String tradedAssetsSubquery = "SELECT have_asset_id, want_asset_id "
+ "FROM AssetTrades JOIN AssetOrders ON asset_order_id = initiating_order_id ";
StringBuilder tradedAssetsSubquery = new StringBuilder(1024);
tradedAssetsSubquery.append("SELECT have_asset_id, want_asset_id "
+ "FROM AssetTrades JOIN AssetOrders ON asset_order_id = initiating_order_id ");
// Optionally limit traded assetID pairs
if (!assetIds.isEmpty())
if (!assetIds.isEmpty()) {
// longs are safe enough to use literally
tradedAssetsSubquery += "WHERE have_asset_id IN (" + String.join(", ",
assetIds.stream().map(assetId -> assetId.toString()).collect(Collectors.toList())) + ")";
tradedAssetsSubquery.append("WHERE have_asset_id IN (");
final int assetIdsSize = assetIds.size();
for (int ai = 0; ai < assetIdsSize; ++ai) {
if (ai != 0)
tradedAssetsSubquery.append(", ");
tradedAssetsSubquery.append(assetIds.get(ai));
}
tradedAssetsSubquery.append(")");
}
if (!otherAssetIds.isEmpty()) {
tradedAssetsSubquery += assetIds.isEmpty() ? " WHERE " : " AND ";
tradedAssetsSubquery.append(assetIds.isEmpty() ? " WHERE " : " AND ");
// longs are safe enough to use literally
tradedAssetsSubquery += "want_asset_id IN ("
+ String.join(", ",
otherAssetIds.stream().map(assetId -> assetId.toString()).collect(Collectors.toList()))
+ ")";
tradedAssetsSubquery.append("want_asset_id IN (");
final int otherAssetIdsSize = otherAssetIds.size();
for (int oai = 0; oai < otherAssetIdsSize; ++oai) {
if (oai != 0)
tradedAssetsSubquery.append(", ");
tradedAssetsSubquery.append(otherAssetIds.get(oai));
}
tradedAssetsSubquery.append(")");
}
tradedAssetsSubquery += " GROUP BY have_asset_id, want_asset_id";
tradedAssetsSubquery.append(" GROUP BY have_asset_id, want_asset_id");
// Find recent trades using "TradedAssets" assetID pairs
String recentTradesSubquery = "SELECT AssetTrades.target_amount, AssetTrades.initiator_amount, AssetTrades.traded "
@ -585,23 +615,26 @@ public class HSQLDBAssetRepository implements AssetRepository {
+ "ORDER BY traded DESC LIMIT 2";
// Put it all together
String sql = "SELECT have_asset_id, want_asset_id, RecentTrades.target_amount, RecentTrades.initiator_amount, RecentTrades.traded "
+ "FROM (" + tradedAssetsSubquery + ") AS TradedAssets " + ", LATERAL (" + recentTradesSubquery
+ ") AS RecentTrades (target_amount, initiator_amount, traded) " + "ORDER BY have_asset_id";
StringBuilder sql = new StringBuilder(4096);
sql.append("SELECT have_asset_id, want_asset_id, RecentTrades.target_amount, RecentTrades.initiator_amount, RecentTrades.traded FROM (");
sql.append(tradedAssetsSubquery);
sql.append(") AS TradedAssets, LATERAL (");
sql.append(recentTradesSubquery);
sql.append(") AS RecentTrades (target_amount, initiator_amount, traded) ORDER BY have_asset_id");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += ", want_asset_id";
sql.append(", want_asset_id");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += ", RecentTrades.traded DESC ";
sql.append(", RecentTrades.traded DESC ");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<RecentTradeData> recentTrades = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return recentTrades;
@ -624,25 +657,25 @@ public class HSQLDBAssetRepository implements AssetRepository {
}
@Override
public List<TradeData> getOrdersTrades(byte[] orderId, Integer limit, Integer offset, Boolean reverse)
throws DataException {
String sql = "SELECT initiating_order_id, target_order_id, target_amount, initiator_amount, initiator_saving, traded, "
+ "have_asset_id, HaveAsset.asset_name, want_asset_id, WantAsset.asset_name "
public List<TradeData> getOrdersTrades(byte[] orderId, Integer limit, Integer offset, Boolean reverse) throws DataException {
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT initiating_order_id, target_order_id, target_amount, initiator_amount, initiator_saving, traded, "
+ "have_asset_id, HaveAsset.asset_name, want_asset_id, WantAsset.asset_name "
+ "FROM AssetTrades "
+ "JOIN AssetOrders ON asset_order_id = initiating_order_id "
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
+ "JOIN Assets AS WantAsset ON WantAsset.asset_id = want_asset_id "
+ "WHERE ? IN (initiating_order_id, target_order_id)";
+ "WHERE ? IN (initiating_order_id, target_order_id) ");
sql += "ORDER BY traded";
sql.append("ORDER BY traded");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TradeData> trades = new ArrayList<TradeData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, orderId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), orderId)) {
if (resultSet == null)
return trades;

52
src/main/java/org/qora/repository/hsqldb/HSQLDBBlockRepository.java

@ -131,14 +131,17 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override
public List<TransactionData> getTransactionsFromSignature(byte[] signature, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT transaction_signature FROM BlockTransactions WHERE block_signature = ? ORDER BY sequence";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT transaction_signature FROM BlockTransactions WHERE block_signature = ? ORDER BY sequence");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), signature)) {
if (resultSet == null)
return transactions; // No transactions in this block
@ -183,27 +186,39 @@ public class HSQLDBBlockRepository implements BlockRepository {
public List<BlockForgerSummary> getBlockForgers(List<String> addresses, Integer limit, Integer offset, Boolean reverse) throws DataException {
String subquerySql = "SELECT generator, COUNT(signature) FROM Blocks GROUP BY generator";
String sql = "SELECT DISTINCT generator, n_blocks, forger, recipient FROM (" + subquerySql + ") AS Forgers (generator, n_blocks) "
+ " LEFT OUTER JOIN ProxyForgers ON proxy_public_key = generator ";
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT DISTINCT generator, n_blocks, forger, recipient FROM (");
sql.append(subquerySql);
sql.append(") AS Forgers (generator, n_blocks) LEFT OUTER JOIN ProxyForgers ON proxy_public_key = generator ");
if (addresses != null && !addresses.isEmpty()) {
sql += " LEFT OUTER JOIN Accounts AS GeneratorAccounts ON GeneratorAccounts.public_key = generator "
+ " LEFT OUTER JOIN Accounts AS ForgerAccounts ON ForgerAccounts.public_key = forger "
+ " JOIN (VALUES " + String.join(", ", Collections.nCopies(addresses.size(), "(?)")) + ") AS FilterAccounts (account) "
+ " ON FilterAccounts.account IN (recipient, GeneratorAccounts.account, ForgerAccounts.account) ";
sql.append(" LEFT OUTER JOIN Accounts AS GeneratorAccounts ON GeneratorAccounts.public_key = generator ");
sql.append(" LEFT OUTER JOIN Accounts AS ForgerAccounts ON ForgerAccounts.public_key = forger ");
sql.append(" JOIN (VALUES ");
final int addressesSize = addresses.size();
for (int ai = 0; ai < addressesSize; ++ai) {
if (ai != 0)
sql.append(", ");
sql.append("(?)");
}
sql.append(") AS FilterAccounts (account) ");
sql.append(" ON FilterAccounts.account IN (recipient, GeneratorAccounts.account, ForgerAccounts.account) ");
} else {
addresses = Collections.emptyList();
}
sql += "ORDER BY n_blocks ";
sql.append("ORDER BY n_blocks ");
if (reverse != null && reverse)
sql += "DESC ";
sql.append("DESC ");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<BlockForgerSummary> summaries = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, addresses.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), addresses.toArray())) {
if (resultSet == null)
return summaries;
@ -224,15 +239,16 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override
public List<BlockData> getBlocksWithGenerator(byte[] generatorPublicKey, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT " + BLOCK_DB_COLUMNS + " FROM Blocks WHERE generator = ? ORDER BY height ";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT " + BLOCK_DB_COLUMNS + " FROM Blocks WHERE generator = ? ORDER BY height ");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<BlockData> blockData = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, generatorPublicKey)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), generatorPublicKey)) {
if (resultSet == null)
return blockData;

121
src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java

@ -29,7 +29,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupData fromGroupId(int groupId) throws DataException {
final String sql = "SELECT group_name, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_id = ?";
String sql = "SELECT group_name, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_id = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
if (resultSet == null)
@ -62,8 +62,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupData fromGroupName(String groupName) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT group_id, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_name = ?", groupName)) {
String sql = "SELECT group_id, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_name = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupName)) {
if (resultSet == null)
return null;
@ -112,14 +113,17 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupData> getAllGroups(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups ORDER BY group_name";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT group_id, owner, group_name, description, created, updated, reference, is_open, "
+ "approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups ORDER BY group_name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupData> groups = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return groups;
@ -155,14 +159,17 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupData> getGroupsByOwner(String owner, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT group_id, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE owner = ? ORDER BY group_name";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT group_id, group_name, description, created, updated, reference, is_open, "
+ "approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE owner = ? ORDER BY group_name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupData> groups = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, owner)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), owner)) {
if (resultSet == null)
return groups;
@ -197,15 +204,18 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupData> getGroupsWithMember(String member, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups "
+ "JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT group_id, owner, group_name, description, created, updated, reference, is_open, "
+ "approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups "
+ "JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupData> groups = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, member)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), member)) {
if (resultSet == null)
return groups;
@ -334,14 +344,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupAdminData> getGroupAdmins(int groupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT admin, reference FROM GroupAdmins WHERE group_id = ? ORDER BY admin";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT admin, reference FROM GroupAdmins WHERE group_id = ? ORDER BY admin");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupAdminData> admins = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), groupId)) {
if (resultSet == null)
return admins;
@ -399,7 +411,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupMemberData getMember(int groupId, String address) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT address, joined, reference FROM GroupMembers WHERE group_id = ?", groupId)) {
String sql = "SELECT address, joined, reference FROM GroupMembers WHERE group_id = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
if (resultSet == null)
return null;
@ -424,14 +438,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupMemberData> getGroupMembers(int groupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT address, joined, reference FROM GroupMembers WHERE group_id = ? ORDER BY address";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT address, joined, reference FROM GroupMembers WHERE group_id = ? ORDER BY address");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupMemberData> members = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), groupId)) {
if (resultSet == null)
return members;
@ -491,8 +507,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupInviteData getInvite(int groupId, String invitee) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT inviter, expiry, reference FROM GroupInvites WHERE group_id = ? AND invitee = ?",
groupId, invitee)) {
String sql = "SELECT inviter, expiry, reference FROM GroupInvites WHERE group_id = ? AND invitee = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId, invitee)) {
if (resultSet == null)
return null;
@ -519,14 +536,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupInviteData> getInvitesByGroupId(int groupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT inviter, invitee, expiry, reference FROM GroupInvites WHERE group_id = ? ORDER BY invitee";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT inviter, invitee, expiry, reference FROM GroupInvites WHERE group_id = ? ORDER BY invitee");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupInviteData> invites = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), groupId)) {
if (resultSet == null)
return invites;
@ -550,14 +569,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupInviteData> getInvitesByInvitee(String invitee, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT group_id, inviter, expiry, reference FROM GroupInvites WHERE invitee = ? ORDER BY group_id";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT group_id, inviter, expiry, reference FROM GroupInvites WHERE invitee = ? ORDER BY group_id");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupInviteData> invites = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, invitee)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), invitee)) {
if (resultSet == null)
return invites;
@ -610,8 +631,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupJoinRequestData getJoinRequest(Integer groupId, String joiner) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT reference FROM GroupJoinRequests WHERE group_id = ? AND joiner = ?", groupId,
joiner)) {
String sql = "SELECT reference FROM GroupJoinRequests WHERE group_id = ? AND joiner = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId, joiner)) {
if (resultSet == null)
return null;
@ -634,14 +656,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupJoinRequestData> getGroupJoinRequests(int groupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT joiner, reference FROM GroupJoinRequests WHERE group_id = ? ORDER BY joiner";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT joiner, reference FROM GroupJoinRequests WHERE group_id = ? ORDER BY joiner");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupJoinRequestData> joinRequests = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), groupId)) {
if (resultSet == null)
return joinRequests;
@ -685,8 +709,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public GroupBanData getBan(int groupId, String offender) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT admin, banned, reason, expiry, reference FROM GroupBans WHERE group_id = ? AND offender = ?", groupId, offender)) {
String sql = "SELECT admin, banned, reason, expiry, reference FROM GroupBans WHERE group_id = ? AND offender = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId, offender)) {
String admin = resultSet.getString(1);
long banned = resultSet.getTimestamp(2, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
String reason = resultSet.getString(3);
@ -713,14 +738,16 @@ public class HSQLDBGroupRepository implements GroupRepository {
@Override
public List<GroupBanData> getGroupBans(int groupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT offender, admin, banned, reason, expiry, reference FROM GroupBans WHERE group_id = ? ORDER BY offender";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT offender, admin, banned, reason, expiry, reference FROM GroupBans WHERE group_id = ? ORDER BY offender");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<GroupBanData> bans = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, groupId)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), groupId)) {
if (resultSet == null)
return bans;

35
src/main/java/org/qora/repository/hsqldb/HSQLDBNameRepository.java

@ -22,8 +22,9 @@ public class HSQLDBNameRepository implements NameRepository {
@Override
public NameData fromName(String name) throws DataException {
try (ResultSet resultSet = this.repository
.checkedExecute("SELECT owner, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE name = ?", name)) {
String sql = "SELECT owner, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE name = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, name)) {
if (resultSet == null)
return null;
@ -57,14 +58,16 @@ public class HSQLDBNameRepository implements NameRepository {
@Override
public List<NameData> getAllNames(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT name, data, owner, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names ORDER BY name";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT name, data, owner, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names ORDER BY name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<NameData> names = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return names;
@ -94,14 +97,16 @@ public class HSQLDBNameRepository implements NameRepository {
@Override
public List<NameData> getNamesForSale(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT name, data, owner, registered, updated, reference, sale_price, creation_group_id FROM Names WHERE is_for_sale = TRUE ORDER BY name";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT name, data, owner, registered, updated, reference, sale_price, creation_group_id FROM Names WHERE is_for_sale = TRUE ORDER BY name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<NameData> names = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return names;
@ -131,14 +136,16 @@ public class HSQLDBNameRepository implements NameRepository {
@Override
public List<NameData> getNamesByOwner(String owner, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT name, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE owner = ? ORDER BY name";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT name, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE owner = ? ORDER BY name");
if (reverse != null && reverse)
sql += " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<NameData> names = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, owner)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), owner)) {
if (resultSet == null)
return names;

61
src/main/java/org/qora/repository/hsqldb/HSQLDBRepository.java

@ -12,7 +12,6 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.TimeZone;
@ -391,9 +390,14 @@ public class HSQLDBRepository implements Repository {
* @throws SQLException
*/
public boolean exists(String tableName, String whereClause, Object... objects) throws SQLException {
String sql = "SELECT TRUE FROM " + tableName + " WHERE " + whereClause + " LIMIT 1";
try (PreparedStatement preparedStatement = this.prepareStatement(sql);
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT TRUE FROM ");
sql.append(tableName);
sql.append(" WHERE ");
sql.append(whereClause);
sql.append(" LIMIT 1");
try (PreparedStatement preparedStatement = this.prepareStatement(sql.toString());
ResultSet resultSet = this.checkedExecuteResultSet(preparedStatement, objects)) {
if (resultSet == null)
return false;
@ -411,9 +415,13 @@ public class HSQLDBRepository implements Repository {
* @throws SQLException
*/
public int delete(String tableName, String whereClause, Object... objects) throws SQLException {
String sql = "DELETE FROM " + tableName + " WHERE " + whereClause;
StringBuilder sql = new StringBuilder(256);
sql.append("DELETE FROM ");
sql.append(tableName);
sql.append(" WHERE ");
sql.append(whereClause);
try (PreparedStatement preparedStatement = this.prepareStatement(sql)) {
try (PreparedStatement preparedStatement = this.prepareStatement(sql.toString())) {
return this.checkedExecuteUpdateCount(preparedStatement, objects);
}
}
@ -425,32 +433,33 @@ public class HSQLDBRepository implements Repository {
* @throws SQLException
*/
public int delete(String tableName) throws SQLException {
String sql = "DELETE FROM " + tableName;
StringBuilder sql = new StringBuilder(256);
sql.append("DELETE FROM ");
sql.append(tableName);
try (PreparedStatement preparedStatement = this.prepareStatement(sql)) {
try (PreparedStatement preparedStatement = this.prepareStatement(sql.toString())) {
return this.checkedExecuteUpdateCount(preparedStatement);
}
}
/**
* Returns additional SQL "LIMIT" and "OFFSET" clauses.
* Appends additional SQL "LIMIT" and "OFFSET" clauses.
* <p>
* (Convenience method for HSQLDB repository subclasses).
*
* @param limit
* @param offset
* @return SQL string, potentially empty but never null
*/
public static String limitOffsetSql(Integer limit, Integer offset) {
String sql = "";
if (limit != null && limit > 0)
sql += " LIMIT " + limit;
if (offset != null)
sql += " OFFSET " + offset;
public static void limitOffsetSql(StringBuilder stringBuilder, Integer limit, Integer offset) {
if (limit != null && limit > 0) {
stringBuilder.append(" LIMIT ");
stringBuilder.append(limit);
}
return sql;
if (offset != null) {
stringBuilder.append(" OFFSET ");
stringBuilder.append(offset);
}
}
/** Logs other HSQLDB sessions then re-throws passed exception */
@ -460,8 +469,8 @@ public class HSQLDBRepository implements Repository {
logStatements();
// Serialization failure / potential deadlock - so list other sessions
try (ResultSet resultSet = this.checkedExecute(
"SELECT session_id, transaction, transaction_size, waiting_for_this, this_waiting_for, current_statement FROM Information_schema.system_sessions")) {
String sql = "SELECT session_id, transaction, transaction_size, waiting_for_this, this_waiting_for, current_statement FROM Information_schema.system_sessions";
try (ResultSet resultSet = this.checkedExecute(sql)) {
if (resultSet == null)
return e;
@ -529,14 +538,4 @@ public class HSQLDBRepository implements Repository {
return offsetDateTime.toInstant().toEpochMilli();
}
/** Convenience method to return n comma-separated, placeholders as a string. */
public static String nPlaceholders(int n) {
return String.join(", ", Collections.nCopies(n, "?"));
}
/** Convenience method to return n comma-separated, bracketed, placeholders as a string. */
public static String nValuesPlaceholders(int n) {
return String.join(", ", Collections.nCopies(n, "(?)"));
}
}

34
src/main/java/org/qora/repository/hsqldb/HSQLDBSaver.java

@ -6,7 +6,6 @@ import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
/**
@ -79,18 +78,39 @@ public class HSQLDBSaver {
* @return String
*/
private String formatInsertWithPlaceholders() {
List<String> placeholders = Collections.nCopies(this.columns.size(), "?");
final int columnsSize = this.columns.size();
StringBuilder output = new StringBuilder();
StringBuilder output = new StringBuilder(1024);
output.append("INSERT INTO ");
output.append(this.table);
output.append(" (");
output.append(String.join(", ", this.columns));
for (int ci = 0; ci < columnsSize; ++ci) {
if (ci != 0)
output.append(", ");
output.append(this.columns.get(ci));
}
output.append(") VALUES (");
output.append(String.join(", ", placeholders));
for (int ci = 0; ci < columnsSize; ++ci) {
if (ci != 0)
output.append(", ");
output.append("?");
}
output.append(") ON DUPLICATE KEY UPDATE ");
output.append(String.join("=?, ", this.columns));
output.append("=?");
for (int ci = 0; ci < columnsSize; ++ci) {
if (ci != 0)
output.append(", ");
output.append(this.columns.get(ci));
output.append("=?");
}
return output.toString();
}

24
src/main/java/org/qora/repository/hsqldb/HSQLDBVotingRepository.java

@ -25,7 +25,9 @@ public class HSQLDBVotingRepository implements VotingRepository {
@Override
public PollData fromPollName(String pollName) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT description, creator, owner, published FROM Polls WHERE poll_name = ?", pollName)) {
String sql = "SELECT description, creator, owner, published FROM Polls WHERE poll_name = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, pollName)) {
if (resultSet == null)
return null;
@ -34,8 +36,8 @@ public class HSQLDBVotingRepository implements VotingRepository {
String owner = resultSet.getString(3);
long published = resultSet.getTimestamp(4, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
try (ResultSet optionsResultSet = this.repository
.checkedExecute("SELECT option_name FROM PollOptions WHERE poll_name = ? ORDER BY option_index ASC", pollName)) {
String optionsSql = "SELECT option_name FROM PollOptions WHERE poll_name = ? ORDER BY option_index ASC";
try (ResultSet optionsResultSet = this.repository.checkedExecute(optionsSql, pollName)) {
if (optionsResultSet == null)
return null;
@ -96,8 +98,8 @@ public class HSQLDBVotingRepository implements VotingRepository {
@Override
public void delete(String pollName) throws DataException {
// NOTE: The corresponding rows in PollOptions are deleted automatically by the database thanks to "ON DELETE CASCADE" in the PollOptions' FOREIGN KEY
// definition.
// NOTE: The corresponding rows in PollOptions are deleted automatically by the database
// thanks to "ON DELETE CASCADE" in the PollOptions' FOREIGN KEY definition.
try {
this.repository.delete("Polls", "poll_name = ?", pollName);
} catch (SQLException e) {
@ -109,9 +111,10 @@ public class HSQLDBVotingRepository implements VotingRepository {
@Override
public List<VoteOnPollData> getVotes(String pollName) throws DataException {
String sql = "SELECT voter, option_index FROM PollVotes WHERE poll_name = ?";
List<VoteOnPollData> votes = new ArrayList<VoteOnPollData>();
try (ResultSet resultSet = this.repository.checkedExecute("SELECT voter, option_index FROM PollVotes WHERE poll_name = ?", pollName)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql, pollName)) {
if (resultSet == null)
return votes;
@ -131,8 +134,9 @@ public class HSQLDBVotingRepository implements VotingRepository {
@Override
public VoteOnPollData getVote(String pollName, byte[] voterPublicKey) throws DataException {
try (ResultSet resultSet = this.repository.checkedExecute("SELECT option_index FROM PollVotes WHERE poll_name = ? AND voter = ?", pollName,
voterPublicKey)) {
String sql = "SELECT option_index FROM PollVotes WHERE poll_name = ? AND voter = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, pollName, voterPublicKey)) {
if (resultSet == null)
return null;
@ -148,8 +152,8 @@ public class HSQLDBVotingRepository implements VotingRepository {
public void save(VoteOnPollData voteOnPollData) throws DataException {
HSQLDBSaver saveHelper = new HSQLDBSaver("PollVotes");
saveHelper.bind("poll_name", voteOnPollData.getPollName()).bind("voter", voteOnPollData.getVoterPublicKey()).bind("option_index",
voteOnPollData.getOptionIndex());
saveHelper.bind("poll_name", voteOnPollData.getPollName()).bind("voter", voteOnPollData.getVoterPublicKey())
.bind("option_index", voteOnPollData.getOptionIndex());
try {
saveHelper.execute(this.repository);

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAccountFlagsTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBAccountFlagsTransactionRepository extends HSQLDBTransactionRe
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT target, and_mask, or_mask, xor_mask, previous_flags FROM AccountFlagsTransactions WHERE signature = ?";
String sql = "SELECT target, and_mask, or_mask, xor_mask, previous_flags FROM AccountFlagsTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAddGroupAdminTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBAddGroupAdminTransactionRepository extends HSQLDBTransactionR
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, address FROM AddGroupAdminTransactions WHERE signature = ?";
String sql = "SELECT group_id, address FROM AddGroupAdminTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java

@ -20,7 +20,7 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT version, service, is_data_raw, data from ArbitraryTransactions WHERE signature = ?";
String sql = "SELECT version, service, is_data_raw, data from ArbitraryTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBAtTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBAtTransactionRepository extends HSQLDBTransactionRepository {
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT AT_address, recipient, amount, asset_id, message FROM ATTransactions WHERE signature = ?";
String sql = "SELECT AT_address, recipient, amount, asset_id, message FROM ATTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBBuyNameTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBBuyNameTransactionRepository extends HSQLDBTransactionReposit
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT name, amount, seller, name_reference FROM BuyNameTransactions WHERE signature = ?";
String sql = "SELECT name, amount, seller, name_reference FROM BuyNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelAssetOrderTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBCancelAssetOrderTransactionRepository extends HSQLDBTransacti
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT asset_order_id FROM CancelAssetOrderTransactions WHERE signature = ?";
String sql = "SELECT asset_order_id FROM CancelAssetOrderTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupBanTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBCancelGroupBanTransactionRepository extends HSQLDBTransaction
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, address, ban_reference FROM CancelGroupBanTransactions WHERE signature = ?";
String sql = "SELECT group_id, address, ban_reference FROM CancelGroupBanTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelGroupInviteTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBCancelGroupInviteTransactionRepository extends HSQLDBTransact
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, invitee, invite_reference FROM CancelGroupInviteTransactions WHERE signature = ?";
String sql = "SELECT group_id, invitee, invite_reference FROM CancelGroupInviteTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCancelSellNameTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransaction
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT name FROM CancelSellNameTransactions WHERE signature = ?";
String sql = "SELECT name FROM CancelSellNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateAssetOrderTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT have_asset_id, amount, want_asset_id, price, HaveAsset.asset_name, WantAsset.asset_name "
String sql = "SELECT have_asset_id, amount, want_asset_id, price, HaveAsset.asset_name, WantAsset.asset_name "
+ "FROM CreateAssetOrderTransactions "
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
+ "JOIN Assets AS WantAsset ON WantAsset.asset_id = want_asset_id "

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreateGroupTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBCreateGroupTransactionRepository extends HSQLDBTransactionRep
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT owner, group_name, description, is_open, approval_threshold, min_block_delay, max_block_delay, group_id FROM CreateGroupTransactions WHERE signature = ?";
String sql = "SELECT owner, group_name, description, is_open, approval_threshold, min_block_delay, max_block_delay, group_id FROM CreateGroupTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

4
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBCreatePollTransactionRepository.java

@ -20,7 +20,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT owner, poll_name, description FROM CreatePollTransactions WHERE signature = ?";
String sql = "SELECT owner, poll_name, description FROM CreatePollTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)
@ -30,7 +30,7 @@ public class HSQLDBCreatePollTransactionRepository extends HSQLDBTransactionRepo
String pollName = resultSet.getString(2);
String description = resultSet.getString(3);
final String optionsSql = "SELECT option_name FROM CreatePollTransactionOptions WHERE signature = ? ORDER BY option_index ASC";
String optionsSql = "SELECT option_name FROM CreatePollTransactionOptions WHERE signature = ? ORDER BY option_index ASC";
try (ResultSet optionsResultSet = this.repository.checkedExecute(optionsSql, baseTransactionData.getSignature())) {
if (optionsResultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBDeployAtTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBDeployAtTransactionRepository extends HSQLDBTransactionReposi
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT AT_name, description, AT_type, AT_tags, creation_bytes, amount, asset_id, AT_address FROM DeployATTransactions WHERE signature = ?";
String sql = "SELECT AT_name, description, AT_type, AT_tags, creation_bytes, amount, asset_id, AT_address FROM DeployATTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBEnableForgingTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBEnableForgingTransactionRepository extends HSQLDBTransactionR
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT target FROM EnableForgingTransactions WHERE signature = ?";
String sql = "SELECT target FROM EnableForgingTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGenesisTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBGenesisTransactionRepository extends HSQLDBTransactionReposit
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT recipient, amount, asset_id FROM GenesisTransactions WHERE signature = ?";
String sql = "SELECT recipient, amount, asset_id FROM GenesisTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupApprovalTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBGroupApprovalTransactionRepository extends HSQLDBTransactionR
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT pending_signature, approval, prior_reference FROM GroupApprovalTransactions WHERE signature = ?";
String sql = "SELECT pending_signature, approval, prior_reference FROM GroupApprovalTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, address, reason, time_to_live, member_reference, admin_reference, join_invite_reference, previous_group_id FROM GroupBanTransactions WHERE signature = ?";
String sql = "SELECT group_id, address, reason, time_to_live, member_reference, admin_reference, join_invite_reference, previous_group_id FROM GroupBanTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, invitee, time_to_live, join_reference, previous_group_id FROM GroupInviteTransactions WHERE signature = ?";
String sql = "SELECT group_id, invitee, time_to_live, join_reference, previous_group_id FROM GroupInviteTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, address, reason, member_reference, admin_reference, join_reference, previous_group_id FROM GroupKickTransactions WHERE signature = ?";
String sql = "SELECT group_id, address, reason, member_reference, admin_reference, join_reference, previous_group_id FROM GroupKickTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBIssueAssetTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBIssueAssetTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, asset_id FROM IssueAssetTransactions WHERE signature = ?";
String sql = "SELECT owner, asset_name, description, quantity, is_divisible, data, asset_id FROM IssueAssetTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, invite_reference, previous_group_id FROM JoinGroupTransactions WHERE signature = ?";
String sql = "SELECT group_id, invite_reference, previous_group_id FROM JoinGroupTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, member_reference, admin_reference, previous_group_id FROM LeaveGroupTransactions WHERE signature = ?";
String sql = "SELECT group_id, member_reference, admin_reference, previous_group_id FROM LeaveGroupTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMessageTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT version, recipient, is_text, is_encrypted, amount, asset_id, data FROM MessageTransactions WHERE signature = ?";
String sql = "SELECT version, recipient, is_text, is_encrypted, amount, asset_id, data FROM MessageTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBMultiPaymentTransactionRepository.java

@ -19,7 +19,7 @@ public class HSQLDBMultiPaymentTransactionRepository extends HSQLDBTransactionRe
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT TRUE from MultiPaymentTransactions WHERE signature = ?";
String sql = "SELECT TRUE from MultiPaymentTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBPaymentTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBPaymentTransactionRepository extends HSQLDBTransactionReposit
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT recipient, amount FROM PaymentTransactions WHERE signature = ?";
String sql = "SELECT recipient, amount FROM PaymentTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBProxyForgingTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBProxyForgingTransactionRepository extends HSQLDBTransactionRe
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT recipient, proxy_public_key, share, previous_share FROM ProxyForgingTransactions WHERE signature = ?";
String sql = "SELECT recipient, proxy_public_key, share, previous_share FROM ProxyForgingTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRegisterNameTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT owner, name, data FROM RegisterNameTransactions WHERE signature = ?";
String sql = "SELECT owner, name, data FROM RegisterNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBRemoveGroupAdminTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBRemoveGroupAdminTransactionRepository extends HSQLDBTransacti
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, admin, admin_reference FROM RemoveGroupAdminTransactions WHERE signature = ?";
String sql = "SELECT group_id, admin, admin_reference FROM RemoveGroupAdminTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSellNameTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBSellNameTransactionRepository extends HSQLDBTransactionReposi
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT name, amount FROM SellNameTransactions WHERE signature = ?";
String sql = "SELECT name, amount FROM SellNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBSetGroupTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBSetGroupTransactionRepository extends HSQLDBTransactionReposi
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT default_group_id, previous_default_group_id FROM SetGroupTransactions WHERE signature = ?";
String sql = "SELECT default_group_id, previous_default_group_id FROM SetGroupTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

238
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBTransactionRepository.java

@ -8,12 +8,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -128,7 +126,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public TransactionData fromSignature(byte[] signature) throws DataException {
final String sql = "SELECT type, reference, creator, creation, fee, tx_group_id, block_height, approval_status, approval_height FROM Transactions WHERE signature = ?";
String sql = "SELECT type, reference, creator, creation, fee, tx_group_id, block_height, approval_status, approval_height "
+ "FROM Transactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
if (resultSet == null)
@ -162,7 +161,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public TransactionData fromReference(byte[] reference) throws DataException {
final String sql = "SELECT type, signature, creator, creation, fee, tx_group_id, block_height, approval_status, approval_height FROM Transactions WHERE reference = ?";
String sql = "SELECT type, signature, creator, creation, fee, tx_group_id, block_height, approval_status, approval_height "
+ "FROM Transactions WHERE reference = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, reference)) {
if (resultSet == null)
@ -196,7 +196,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public TransactionData fromHeightAndSequence(int height, int sequence) throws DataException {
final String sql = "SELECT transaction_signature FROM BlockTransactions JOIN Blocks ON signature = block_signature WHERE height = ? AND sequence = ?";
String sql = "SELECT transaction_signature FROM BlockTransactions JOIN Blocks ON signature = block_signature "
+ "WHERE height = ? AND sequence = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, height, sequence)) {
if (resultSet == null)
@ -238,7 +239,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
* @throws DataException
*/
protected List<PaymentData> getPaymentsFromSignature(byte[] signature) throws DataException {
final String sql = "SELECT recipient, amount, asset_id FROM SharedTransactionPayments WHERE signature = ?";
String sql = "SELECT recipient, amount, asset_id FROM SharedTransactionPayments WHERE signature = ?";
List<PaymentData> payments = new ArrayList<PaymentData>();
@ -265,8 +266,8 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
for (PaymentData paymentData : payments) {
HSQLDBSaver saver = new HSQLDBSaver("SharedTransactionPayments");
saver.bind("signature", signature).bind("recipient", paymentData.getRecipient()).bind("amount", paymentData.getAmount()).bind("asset_id",
paymentData.getAssetId());
saver.bind("signature", signature).bind("recipient", paymentData.getRecipient())
.bind("amount", paymentData.getAmount()).bind("asset_id", paymentData.getAssetId());
try {
saver.execute(this.repository);
@ -281,7 +282,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
if (signature == null)
return 0;
final String sql = "SELECT block_height from Transactions WHERE signature = ? LIMIT 1";
String sql = "SELECT block_height from Transactions WHERE signature = ? LIMIT 1";
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
if (resultSet == null)
@ -310,7 +311,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<byte[]> getSignaturesInvolvingAddress(String address) throws DataException {
final String sql = "SELECT signature FROM TransactionRecipients WHERE participant = ?";
String sql = "SELECT signature FROM TransactionRecipients WHERE participant = ?";
List<byte[]> signatures = new ArrayList<byte[]>();
@ -398,21 +399,22 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
String signatureColumn = "Transactions.signature";
List<String> whereClauses = new ArrayList<String>();
String groupBy = "";
String groupBy = null;
List<Object> bindParams = new ArrayList<Object>();
// Tables, starting with Transactions
String tables = "Transactions";
StringBuilder tables = new StringBuilder(256);
tables.append("Transactions");
if (hasAddress) {
tables += " JOIN TransactionParticipants ON TransactionParticipants.signature = Transactions.signature";
tables.append(" JOIN TransactionParticipants ON TransactionParticipants.signature = Transactions.signature");
groupBy = " GROUP BY TransactionParticipants.signature, Transactions.creation";
signatureColumn = "TransactionParticipants.signature";
}
if (service != null) {
// This is for ARBITRARY transactions
tables += " LEFT OUTER JOIN ArbitraryTransactions ON ArbitraryTransactions.signature = Transactions.signature";
tables.append(" LEFT OUTER JOIN ArbitraryTransactions ON ArbitraryTransactions.signature = Transactions.signature");
}
// WHERE clauses next
@ -445,8 +447,21 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
}
if (hasTxTypes) {
whereClauses.add("Transactions.type IN (" + HSQLDBRepository.nPlaceholders(txTypes.size()) + ")");
bindParams.addAll(txTypes.stream().map(txType -> txType.value).collect(Collectors.toList()));
StringBuilder txTypesIn = new StringBuilder(256);
txTypesIn.append("Transactions.type IN (");
// ints are safe enough to use literally
final int txTypesSize = txTypes.size();
for (int tti = 0; tti < txTypesSize; ++tti) {
if (tti != 0)
txTypesIn.append(", ");
txTypesIn.append(txTypes.get(tti).value);
}
txTypesIn.append(")");
whereClauses.add(txTypesIn.toString());
}
if (service != null) {
@ -459,22 +474,35 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
bindParams.add(address);
}
String sql = "SELECT " + signatureColumn + " FROM " + tables;
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT ");
sql.append(signatureColumn);
sql.append(" FROM ");
sql.append(tables);
if (!whereClauses.isEmpty())
sql += " WHERE " + String.join(" AND ", whereClauses);
if (!whereClauses.isEmpty()) {
sql.append(" WHERE ");
if (!groupBy.isEmpty())
sql += groupBy;
final int whereClausesSize = whereClauses.size();
for (int wci = 0; wci < whereClausesSize; ++wci) {
if (wci != 0)
sql.append(" AND ");
sql += " ORDER BY Transactions.creation";
sql += (reverse == null || !reverse) ? " ASC" : " DESC";
sql.append(whereClauses.get(wci));
}
}
if (groupBy != null)
sql.append(groupBy);
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(" ORDER BY Transactions.creation");
sql.append((reverse == null || !reverse) ? " ASC" : " DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
LOGGER.trace(String.format("Transaction search SQL: %s", sql));
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
if (resultSet == null)
return signatures;
@ -497,17 +525,26 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
ISSUE_ASSET, TRANSFER_ASSET, CREATE_ASSET_ORDER, CANCEL_ASSET_ORDER
};
List<String> typeValueStrings = Arrays.asList(transactionTypes).stream().map(type -> String.valueOf(type.value)).collect(Collectors.toList());
String sql = "SELECT Transactions.signature FROM Transactions";
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT Transactions.signature FROM Transactions");
for (TransactionType type : transactionTypes)
sql += " LEFT OUTER JOIN " + type.className + "Transactions USING (signature)";
for (int ti = 0; ti < transactionTypes.length; ++ti) {
sql.append(" LEFT OUTER JOIN ");
sql.append(transactionTypes[ti].className);
sql.append("Transactions USING (signature)");
}
// assetID isn't in Cancel Asset Order so we need to join to the order
sql += " LEFT OUTER JOIN AssetOrders ON AssetOrders.asset_order_id = CancelAssetOrderTransactions.asset_order_id";
sql.append(" LEFT OUTER JOIN AssetOrders ON AssetOrders.asset_order_id = CancelAssetOrderTransactions.asset_order_id");
sql.append(" WHERE Transactions.type IN (");
for (int ti = 0; ti < transactionTypes.length; ++ti) {
if (ti != 0)
sql.append(", ");
sql += " WHERE Transactions.type IN (" + String.join(", ", typeValueStrings) + ")";
sql.append(transactionTypes[ti].value);
}
sql.append(")");
// Confirmation status
switch (confirmationStatus) {
@ -515,34 +552,35 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
break;
case CONFIRMED:
sql += " AND Transactions.block_height IS NOT NULL";
sql.append(" AND Transactions.block_height IS NOT NULL");
break;
case UNCONFIRMED:
sql += " AND Transactions.block_height IS NULL";
sql.append(" AND Transactions.block_height IS NULL");
break;
}
sql += " AND (";
sql += "IssueAssetTransactions.asset_id = " + assetId;
sql += " OR ";
sql += "TransferAssetTransactions.asset_id = " + assetId;
sql += " OR ";
sql += "CreateAssetOrderTransactions.have_asset_id = " + assetId;
sql += " OR ";
sql += "CreateAssetOrderTransactions.want_asset_id = " + assetId;
sql += " OR ";
sql += "AssetOrders.have_asset_id = " + assetId;
sql += " OR ";
sql += "AssetOrders.want_asset_id = " + assetId;
sql += ") GROUP BY Transactions.signature, Transactions.creation ORDER BY Transactions.creation";
sql.append(" AND (IssueAssetTransactions.asset_id = ");
sql.append(assetId);
sql.append(" OR TransferAssetTransactions.asset_id = ");
sql.append(assetId);
sql.append(" OR CreateAssetOrderTransactions.have_asset_id = ");
sql.append(assetId);
sql.append(" OR CreateAssetOrderTransactions.want_asset_id = ");
sql.append(assetId);
sql.append(" OR AssetOrders.have_asset_id = ");
sql.append(assetId);
sql.append(" OR AssetOrders.want_asset_id = ");
sql.append(assetId);
sql += (reverse == null || !reverse) ? " ASC" : " DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
sql.append(") GROUP BY Transactions.signature, Transactions.creation ORDER BY Transactions.creation");
sql.append((reverse == null || !reverse) ? " ASC" : " DESC");
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return transactions;
@ -569,28 +607,29 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
throws DataException {
List<Object> bindParams = new ArrayList<>(3);
String sql = "SELECT creation, tx_group_id, reference, fee, signature, sender, block_height, approval_status, approval_height, recipient, amount, asset_name "
+ "FROM TransferAssetTransactions JOIN Transactions USING (signature) ";
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT creation, tx_group_id, reference, fee, signature, sender, block_height, approval_status, approval_height, recipient, amount, asset_name "
+ "FROM TransferAssetTransactions JOIN Transactions USING (signature) ");
if (address != null)
sql += "JOIN Accounts ON public_key = sender ";
sql.append("JOIN Accounts ON public_key = sender ");
sql += "JOIN Assets USING (asset_id) WHERE asset_id = ? ";
sql.append("JOIN Assets USING (asset_id) WHERE asset_id = ?");
bindParams.add(assetId);
if (address != null) {
sql += "AND ? IN (account, recipient) ";
sql.append(" AND ? IN (account, recipient) ");
bindParams.add(address);
}
sql += "ORDER by creation ";
sql.append(" ORDER by creation ");
sql.append((reverse == null || !reverse) ? "ASC" : "DESC");
sql += (reverse == null || !reverse) ? "ASC" : "DESC";
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TransferAssetTransactionData> assetTransfers = new ArrayList<>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
if (resultSet == null)
return assetTransfers;
@ -629,30 +668,34 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getApprovalPendingTransactions(Integer txGroupId, Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT signature FROM Transactions WHERE Transactions.approval_status = ? ";
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT signature FROM Transactions WHERE Transactions.approval_status = ");
// Enum int value safe to use literally
sql.append(ApprovalStatus.PENDING.value);
List<Object> bindParams = new ArrayList<>();
bindParams.add(ApprovalStatus.PENDING.value);
Object[] bindParams;
if (txGroupId != null) {
sql += "AND Transactions.tx_group_id = ? ";
bindParams.add(txGroupId);
sql.append(" AND Transactions.tx_group_id = ?");
bindParams = new Object[] { txGroupId };
} else {
bindParams = new Object[0];
}
sql += "ORDER BY creation";
sql.append(" ORDER BY creation");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += ", signature";
sql.append(", signature");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
// Find transactions with no corresponding row in BlockTransactions
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams)) {
if (resultSet == null)
return transactions;
@ -676,14 +719,18 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getApprovalPendingTransactions(int blockHeight) throws DataException {
String sql = "SELECT signature FROM Transactions "
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT signature FROM Transactions "
+ "JOIN Groups on Groups.group_id = Transactions.tx_group_id "
+ "WHERE Transactions.approval_status = ? "
+ "AND Transactions.block_height < ? - Groups.min_block_delay";
+ "WHERE Transactions.approval_status = ");
// Enum int value safe to use literally
sql.append(ApprovalStatus.PENDING.value);
sql.append(" AND Transactions.block_height < ? - Groups.min_block_delay");
List<TransactionData> transactions = new ArrayList<TransactionData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, ApprovalStatus.PENDING.value, blockHeight)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), blockHeight)) {
if (resultSet == null)
return transactions;
@ -707,14 +754,18 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getApprovalExpiringTransactions(int blockHeight) throws DataException {
String sql = "SELECT signature FROM Transactions "
StringBuilder sql = new StringBuilder(512);
sql.append("SELECT signature FROM Transactions "
+ "JOIN Groups on Groups.group_id = Transactions.tx_group_id "
+ "WHERE Transactions.approval_status = ? "
+ "AND Transactions.block_height < ? - Groups.max_block_delay";
+ "WHERE Transactions.approval_status = ");
// Enum int value safe to use literally
sql.append(ApprovalStatus.PENDING.value);
sql.append(" AND Transactions.block_height < ? - Groups.max_block_delay");
List<TransactionData> transactions = new ArrayList<TransactionData>();
try (ResultSet resultSet = this.repository.checkedExecute(sql, ApprovalStatus.PENDING.value, blockHeight)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), blockHeight)) {
if (resultSet == null)
return transactions;
@ -738,7 +789,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getApprovalTransactionDecidedAtHeight(int approvalHeight) throws DataException {
final String sql = "SELECT signature from Transactions WHERE approval_height = ?";
String sql = "SELECT signature from Transactions WHERE approval_height = ?";
List<TransactionData> transactions = new ArrayList<>();
@ -793,18 +844,20 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
String latestApprovalSql = "SELECT pending_signature, admin, approval, creation, signature FROM GroupApprovalTransactions "
+ "NATURAL JOIN Transactions WHERE pending_signature = ? AND block_height IS NOT NULL";
String sql = "SELECT GAT.admin, GAT.approval FROM "
+ "(" + latestApprovalSql + ") AS GAT "
+ "LEFT OUTER JOIN (" + latestApprovalSql + ") AS NewerGAT "
+ "ON NewerGAT.admin = GAT.admin AND (NewerGAT.creation > GAT.creation OR (NewerGAT.creation = GAT.creation AND NewerGat.signature > GAT.signature)) "
StringBuilder sql = new StringBuilder(1024);
sql.append("SELECT GAT.admin, GAT.approval FROM (");
sql.append(latestApprovalSql);
sql.append(") AS GAT LEFT OUTER JOIN (");
sql.append(latestApprovalSql);
sql.append(") AS NewerGAT ON NewerGAT.admin = GAT.admin AND (NewerGAT.creation > GAT.creation OR (NewerGAT.creation = GAT.creation AND NewerGat.signature > GAT.signature)) "
+ "JOIN Transactions AS PendingTransactions ON PendingTransactions.signature = GAT.pending_signature "
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = GAT.admin "
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account AND GroupAdmins.group_id = PendingTransactions.tx_group_id "
+ "WHERE NewerGAT.admin IS NULL";
+ "WHERE NewerGAT.admin IS NULL");
GroupApprovalData groupApprovalData = new GroupApprovalData();
try (ResultSet resultSet = this.repository.checkedExecute(sql, pendingSignature, pendingSignature)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), pendingSignature, pendingSignature)) {
if (resultSet == null)
return groupApprovalData;
@ -858,22 +911,23 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
@Override
public List<TransactionData> getUnconfirmedTransactions(Integer limit, Integer offset, Boolean reverse) throws DataException {
String sql = "SELECT signature FROM UnconfirmedTransactions ";
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT signature FROM UnconfirmedTransactions ");
sql += "ORDER BY creation";
sql.append("ORDER BY creation");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += ", signature";
sql.append(", signature");
if (reverse != null && reverse)
sql += " DESC";
sql.append(" DESC");
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
List<TransactionData> transactions = new ArrayList<TransactionData>();
// Find transactions with no corresponding row in BlockTransactions
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) {
if (resultSet == null)
return transactions;

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateAssetTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBUpdateAssetTransactionRepository extends HSQLDBTransactionRep
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT asset_id, new_owner, new_description, new_data, orphan_reference FROM UpdateAssetTransactions WHERE signature = ?";
String sql = "SELECT asset_id, new_owner, new_description, new_data, orphan_reference FROM UpdateAssetTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateGroupTransactionRepository.java

@ -18,7 +18,7 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT group_id, new_owner, new_description, new_is_open, new_approval_threshold, new_min_block_delay, new_max_block_delay, group_reference FROM UpdateGroupTransactions WHERE signature = ?";
String sql = "SELECT group_id, new_owner, new_description, new_is_open, new_approval_threshold, new_min_block_delay, new_max_block_delay, group_reference FROM UpdateGroupTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBUpdateNameTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT new_owner, name, new_data, name_reference FROM UpdateNameTransactions WHERE signature = ?";
String sql = "SELECT new_owner, name, new_data, name_reference FROM UpdateNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

2
src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBVoteOnPollTransactionRepository.java

@ -17,7 +17,7 @@ public class HSQLDBVoteOnPollTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
final String sql = "SELECT poll_name, option_index, previous_option_index FROM VoteOnPollTransactions WHERE signature = ?";
String sql = "SELECT poll_name, option_index, previous_option_index FROM VoteOnPollTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)

36
src/test/java/org/qora/test/api/AddressesApiTests.java

@ -0,0 +1,36 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.resource.AddressesResource;
import org.qora.test.common.ApiCommon;
public class AddressesApiTests extends ApiCommon {
private AddressesResource addressesResource;
@Before
public void buildResource() {
this.addressesResource = (AddressesResource) ApiCommon.buildResource(AddressesResource.class);
}
@Test
public void testGetAccountInfo() {
assertNotNull(this.addressesResource.getAccountInfo(aliceAddress));
}
@Test
public void testGetProxying() {
assertNotNull(this.addressesResource.getProxying(Collections.singletonList(aliceAddress), null, null, null, null, null));
assertNotNull(this.addressesResource.getProxying(null, Collections.singletonList(aliceAddress), null, null, null, null));
assertNotNull(this.addressesResource.getProxying(Collections.singletonList(aliceAddress), Collections.singletonList(aliceAddress), null, null, null, null));
assertNotNull(this.addressesResource.getProxying(null, null, Collections.singletonList(aliceAddress), null, null, null));
assertNotNull(this.addressesResource.getProxying(Collections.singletonList(aliceAddress), Collections.singletonList(aliceAddress), Collections.singletonList(aliceAddress), null, null, null));
assertNotNull(this.addressesResource.getProxying(Collections.singletonList(aliceAddress), Collections.singletonList(aliceAddress), Collections.singletonList(aliceAddress), 1, 1, true));
}
}

29
src/test/java/org/qora/test/api/AdminApiTests.java

@ -0,0 +1,29 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.resource.AdminResource;
import org.qora.test.common.ApiCommon;
public class AdminApiTests extends ApiCommon {
private AdminResource adminResource;
@Before
public void buildResource() {
this.adminResource = (AdminResource) ApiCommon.buildResource(AdminResource.class);
}
@Test
public void testInfo() {
assertNotNull(this.adminResource.info());
}
@Test
public void testSummary() {
assertNotNull(this.adminResource.summary());
}
}

154
src/test/java/org/qora/test/api/AssetsApiTests.java

@ -0,0 +1,154 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.ApiError;
import org.qora.api.ApiException;
import org.qora.api.resource.AssetsResource;
import org.qora.api.resource.TransactionsResource.ConfirmationStatus;
import org.qora.repository.AccountRepository.BalanceOrdering;
import org.qora.test.common.ApiCommon;
public class AssetsApiTests extends ApiCommon {
private static final String FAKE_ORDER_ID_BASE58 = "C3CPq7c8PY";
private AssetsResource assetsResource;
@Before
public void buildResource() {
this.assetsResource = (AssetsResource) ApiCommon.buildResource(AssetsResource.class);
}
@Test
public void testGet() {
assertNotNull(this.assetsResource);
}
@Test
public void testGetAccountAssetPairOrders() {
String address = aliceAddress;
final int assetId = 0;
final int otherAssetId = 1;
for (Boolean includeClosed : ALL_BOOLEAN_VALUES) {
for (Boolean includeFulfilled : ALL_BOOLEAN_VALUES) {
assertNotNull(this.assetsResource.getAccountAssetPairOrders(address, assetId, otherAssetId, includeClosed, includeFulfilled, null, null, null));
assertNotNull(this.assetsResource.getAccountAssetPairOrders(address, assetId, otherAssetId, includeClosed, includeFulfilled, 1, 1, true));
}
}
}
@Test
public void testGetAccountOrders() {
for (Boolean includeClosed : TF_BOOLEAN_VALUES) {
for (Boolean includeFulfilled : TF_BOOLEAN_VALUES) {
assertNotNull(this.assetsResource.getAccountOrders(aliceAddress, includeClosed, includeFulfilled, null, null, null));
assertNotNull(this.assetsResource.getAccountOrders(aliceAddress, includeClosed, includeFulfilled, 1, 1, true));
}
}
}
@Test
public void testGetAggregatedOpenOrders() {
assertNotNull(this.assetsResource.getAggregatedOpenOrders(0, 1, null, null, null));
assertNotNull(this.assetsResource.getAggregatedOpenOrders(0, 1, 1, 1, true));
}
@Test
public void testGetAllAssets() {
assertNotNull(this.assetsResource.getAllAssets(null, null, null, null));
assertNotNull(this.assetsResource.getAllAssets(false, null, null, null));
assertNotNull(this.assetsResource.getAllAssets(false, 1, 1, true));
}
@Test
public void testGetAssetBalances() {
List<String> addresses = Arrays.asList(aliceAddress, aliceAddress);
List<Long> assetIds = Arrays.asList(1L, 2L, 3L);
for (BalanceOrdering balanceOrdering : BalanceOrdering.values()) {
for (Boolean excludeZero : ALL_BOOLEAN_VALUES) {
assertNotNull(this.assetsResource.getAssetBalances(Collections.emptyList(), assetIds, balanceOrdering, excludeZero, null, null, null));
assertNotNull(this.assetsResource.getAssetBalances(addresses, Collections.emptyList(), balanceOrdering, excludeZero, null, null, null));
assertNotNull(this.assetsResource.getAssetBalances(addresses, assetIds, balanceOrdering, excludeZero, null, null, null));
assertNotNull(this.assetsResource.getAssetBalances(addresses, assetIds, balanceOrdering, excludeZero, 1, 1, true));
}
}
}
@Test
public void testGetAssetInfo() {
assertNotNull(this.assetsResource.getAssetInfo((int) 0L, null));
assertNotNull(this.assetsResource.getAssetInfo(null, "QORA"));
}
@Test
public void testGetAssetOrder() {
try {
assertNotNull(this.assetsResource.getAssetOrder(FAKE_ORDER_ID_BASE58));
} catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode());
}
}
@Test
public void testGetAssetOrderTrades() {
try {
assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, null, null, null));
} catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode());
}
try {
assertNotNull(this.assetsResource.getAssetOrderTrades(FAKE_ORDER_ID_BASE58, 1, 1, true));
} catch (ApiException e) {
assertTrue(e.error == ApiError.ORDER_NO_EXISTS.getCode());
}
}
@Test
public void testGetAssetTrades() {
assertNotNull(this.assetsResource.getAssetTrades(0, 1, null, null, null));
assertNotNull(this.assetsResource.getAssetTrades(0, 1, 1, 1, true));
}
@Test
public void testGetAssetTransactions() {
for (ConfirmationStatus confirmationStatus : ConfirmationStatus.values()) {
assertNotNull(this.assetsResource.getAssetTransactions(0, confirmationStatus, null, null, null));
assertNotNull(this.assetsResource.getAssetTransactions(0, confirmationStatus, 1, 1, true));
}
}
@Test
public void testGetAssetTransfers() {
assertNotNull(this.assetsResource.getAssetTransfers(0, null, null, null, null));
assertNotNull(this.assetsResource.getAssetTransfers(0, null, 1, 1, true));
assertNotNull(this.assetsResource.getAssetTransfers(0, aliceAddress, null, null, null));
assertNotNull(this.assetsResource.getAssetTransfers(0, aliceAddress, 1, 1, true));
}
@Test
public void testGetOpenOrders() {
assertNotNull(this.assetsResource.getOpenOrders(0, 1, null, null, null));
assertNotNull(this.assetsResource.getOpenOrders(0, 1, 1, 1, true));
}
@Test
public void testGetRecentTrades() {
List<Long> assetIds = Arrays.asList(1L, 2L, 3L);
assertNotNull(this.assetsResource.getRecentTrades(assetIds, Collections.emptyList(), null, null, null));
assertNotNull(this.assetsResource.getRecentTrades(assetIds, Collections.emptyList(), 1, 1, true));
assertNotNull(this.assetsResource.getRecentTrades(assetIds, assetIds, null, null, null));
assertNotNull(this.assetsResource.getRecentTrades(assetIds, assetIds, 1, 1, true));
}
}

44
src/test/java/org/qora/test/api/BlockApiTests.java

@ -0,0 +1,44 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.resource.BlocksResource;
import org.qora.test.common.ApiCommon;
public class BlockApiTests extends ApiCommon {
private BlocksResource blocksResource;
@Before
public void buildResource() {
this.blocksResource = (BlocksResource) ApiCommon.buildResource(BlocksResource.class);
}
@Test
public void test() {
assertNotNull(this.blocksResource);
}
@Test
public void testGetBlockForgers() {
List<String> addresses = Arrays.asList(aliceAddress, aliceAddress);
assertNotNull(this.blocksResource.getBlockForgers(Collections.emptyList(), null, null, null));
assertNotNull(this.blocksResource.getBlockForgers(addresses, null, null, null));
assertNotNull(this.blocksResource.getBlockForgers(Collections.emptyList(), 1, 1, true));
assertNotNull(this.blocksResource.getBlockForgers(addresses, 1, 1, true));
}
@Test
public void testGetBlocksByForger() {
assertNotNull(this.blocksResource.getBlocksByForger(aliceAddress, null, null, null));
assertNotNull(this.blocksResource.getBlocksByForger(aliceAddress, 1, 1, true));
}
}

73
src/test/java/org/qora/test/api/GroupApiTests.java

@ -0,0 +1,73 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.resource.GroupsResource;
import org.qora.test.common.ApiCommon;
public class GroupApiTests extends ApiCommon {
private GroupsResource groupsResource;
@Before
public void buildResource() {
this.groupsResource = (GroupsResource) ApiCommon.buildResource(GroupsResource.class);
}
@Test
public void test() {
assertNotNull(this.groupsResource);
}
@Test
public void testGetAllGroups() {
assertNotNull(this.groupsResource.getAllGroups(null, null, null));
assertNotNull(this.groupsResource.getAllGroups(1, 1, true));
}
@Test
public void testGetBans() {
assertNotNull(this.groupsResource.getBans(1));
}
@Test
public void testGetGroup() {
for (Boolean onlyAdmins : ALL_BOOLEAN_VALUES) {
assertNotNull(this.groupsResource.getGroup(1, onlyAdmins, null, null, null));
assertNotNull(this.groupsResource.getGroup(1, onlyAdmins, 1, 1, true));
}
}
@Test
public void testGetGroupData() {
assertNotNull(this.groupsResource.getGroupData(1));
}
@Test
public void testGetGroupsByOwner() {
assertNotNull(this.groupsResource.getGroupsByOwner(aliceAddress));
}
@Test
public void testGetGroupsWithMember() {
assertNotNull(this.groupsResource.getGroupsWithMember(aliceAddress));
}
@Test
public void testGetInvitesByGroupId() {
assertNotNull(this.groupsResource.getInvitesByGroupId(1));
}
@Test
public void testGetInvitesByInvitee() {
assertNotNull(this.groupsResource.getInvitesByInvitee(aliceAddress));
}
@Test
public void testGetJoinRequests() {
assertNotNull(this.groupsResource.getJoinRequests(1));
}
}

63
src/test/java/org/qora/test/api/TransactionsApiTests.java

@ -0,0 +1,63 @@
package org.qora.test.api;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.qora.api.resource.TransactionsResource;
import org.qora.api.resource.TransactionsResource.ConfirmationStatus;
import org.qora.test.common.ApiCommon;
import org.qora.transaction.Transaction.TransactionType;
public class TransactionsApiTests extends ApiCommon {
private TransactionsResource transactionsResource;
@Before
public void buildResource() {
this.transactionsResource = (TransactionsResource) ApiCommon.buildResource(TransactionsResource.class);
}
@Test
public void test() {
assertNotNull(this.transactionsResource);
}
@Test
public void testGetPendingTransactions() {
for (Integer txGroupId : Arrays.asList(null, 0, 1)) {
assertNotNull(this.transactionsResource.getPendingTransactions(txGroupId, null, null, null));
assertNotNull(this.transactionsResource.getPendingTransactions(txGroupId, 1, 1, true));
}
}
@Test
public void testGetUnconfirmedTransactions() {
assertNotNull(this.transactionsResource.getUnconfirmedTransactions(null, null, null));
assertNotNull(this.transactionsResource.getUnconfirmedTransactions(1, 1, true));
}
@Test
public void testSearchTransactions() {
List<TransactionType> txTypes = Arrays.asList(TransactionType.PAYMENT, TransactionType.ISSUE_ASSET);
for (Integer startBlock : Arrays.asList(null, 1))
for (Integer blockLimit : Arrays.asList(null, 1))
for (Integer txGroupId : Arrays.asList(null, 1))
for (String address : Arrays.asList(null, aliceAddress))
for (ConfirmationStatus confirmationStatus : ConfirmationStatus.values()) {
if (confirmationStatus != ConfirmationStatus.CONFIRMED) {
startBlock = null;
blockLimit = null;
}
assertNotNull(this.transactionsResource.searchTransactions(startBlock, blockLimit, txGroupId, txTypes, address, confirmationStatus, null, null, null));
assertNotNull(this.transactionsResource.searchTransactions(startBlock, blockLimit, txGroupId, txTypes, address, confirmationStatus, 1, 1, true));
assertNotNull(this.transactionsResource.searchTransactions(startBlock, blockLimit, txGroupId, null, address, confirmationStatus, 1, 1, true));
}
}
}

49
src/test/java/org/qora/test/common/ApiCommon.java

@ -0,0 +1,49 @@
package org.qora.test.common;
import java.lang.reflect.Field;
import org.eclipse.jetty.server.Request;
import org.junit.Before;
import org.qora.repository.DataException;
public class ApiCommon extends Common {
public static final Boolean[] ALL_BOOLEAN_VALUES = new Boolean[] { null, true, false };
public static final Boolean[] TF_BOOLEAN_VALUES = new Boolean[] { true, false };
public static class FakeRequest extends Request {
public FakeRequest() {
super(null, null);
}
@Override
public String getRemoteAddr() {
return "127.0.0.1";
}
}
private static final FakeRequest FAKE_REQUEST = new FakeRequest();
public String aliceAddress;
@Before
public void beforeTests() throws DataException {
Common.useDefaultSettings();
this.aliceAddress = Common.getTestAccount(null, "alice").getAddress();
}
public static Object buildResource(Class<?> resourceClass) {
try {
Object resource = resourceClass.newInstance();
Field requestField = resourceClass.getDeclaredField("request");
requestField.setAccessible(true);
requestField.set(resource, FAKE_REQUEST);
return resource;
} catch (Exception e) {
throw new RuntimeException("Failed to build API resource " + resourceClass.getName() + ": " + e.getMessage(), e);
}
}
}

4
src/test/java/org/qora/test/common/Common.java

@ -110,7 +110,7 @@ public class Common {
// Build snapshot of initial state in case we want to compare with post-test orphaning
initialAssets = repository.getAssetRepository().getAllAssets();
initialGroups = repository.getGroupRepository().getAllGroups();
initialBalances = repository.getAccountRepository().getAssetBalances(Collections.emptyList(), Collections.emptyList(), BalanceOrdering.ASSET_ACCOUNT, null, null, null);
initialBalances = repository.getAccountRepository().getAssetBalances(Collections.emptyList(), Collections.emptyList(), BalanceOrdering.ASSET_ACCOUNT, false, null, null, null);
// Check that each test account can fetch their last reference
for (TestAccount testAccount : getTestAccounts(repository))
@ -137,7 +137,7 @@ public class Common {
List<GroupData> remainingGroups = repository.getGroupRepository().getAllGroups();
checkOrphanedLists("group", initialGroups, remainingGroups, GroupData::getGroupId);
List<AccountBalanceData> remainingBalances = repository.getAccountRepository().getAssetBalances(Collections.emptyList(), Collections.emptyList(), BalanceOrdering.ASSET_ACCOUNT, null, null, null);
List<AccountBalanceData> remainingBalances = repository.getAccountRepository().getAssetBalances(Collections.emptyList(), Collections.emptyList(), BalanceOrdering.ASSET_ACCOUNT, false, null, null, null);
checkOrphanedLists("account balance", initialBalances, remainingBalances, entry -> entry.getAssetName() + "-" + entry.getAddress());
assertEquals("remainingBalances is different size", initialBalances.size(), remainingBalances.size());

Loading…
Cancel
Save