mirror of
https://github.com/Qortal/qortal.git
synced 2025-05-03 00:07:52 +00:00
Supply extra information fields to various asset-related API calls.
e.g. supply "assetName" in JSON for TRANSFER_ASSET transactions Also supply have/want asset names, amount asset ID/name, price-pair and creator address in asset orders. Show CREATE_ASSET_ORDER amount ID/name & price-pair in correct format depending on whether transaction was placed before/after 'new' asset pricing took effect. (Orders are always in 'new' form). Change API call /assets/transfers/{assetid}/{address} to /assets/transfers/{assetid} with optional "address" query param.
This commit is contained in:
parent
d5a2e5be19
commit
cfbf5c12bf
@ -2,6 +2,7 @@ package org.qora.api.model;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
@ -11,11 +12,18 @@ import org.qora.data.asset.OrderData;
|
|||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
public class AggregatedOrder {
|
public class AggregatedOrder {
|
||||||
|
|
||||||
|
// Not exposed to API
|
||||||
private OrderData orderData;
|
private OrderData orderData;
|
||||||
|
|
||||||
|
// Needed by JAXB for [un]marshalling
|
||||||
protected AggregatedOrder() {
|
protected AggregatedOrder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void beforeMarshal(Marshaller m) {
|
||||||
|
// OrderData needs to calculate values for us
|
||||||
|
this.orderData.beforeMarshal(m);
|
||||||
|
}
|
||||||
|
|
||||||
public AggregatedOrder(OrderData orderData) {
|
public AggregatedOrder(OrderData orderData) {
|
||||||
this.orderData = orderData;
|
this.orderData = orderData;
|
||||||
}
|
}
|
||||||
@ -30,4 +38,19 @@ public class AggregatedOrder {
|
|||||||
return this.orderData.getAmount();
|
return this.orderData.getAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "unfulfilledAssetId")
|
||||||
|
public long getUnfulfilledAssetId() {
|
||||||
|
return this.orderData.getAmountAssetId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "unfulfilledAssetName")
|
||||||
|
public String getUnfulfilledAssetName() {
|
||||||
|
return this.orderData.getAmountAssetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "pricePair")
|
||||||
|
public String getPricePair() {
|
||||||
|
return this.orderData.getPricePair();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -633,9 +633,9 @@ public class AssetsResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/transfers/{assetid}/{address}")
|
@Path("/transfers/{assetid}")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Asset transfers for specific asset and address combination",
|
summary = "Asset transfers for specific asset, with optional address filter",
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "Asset transactions",
|
description = "Asset transactions",
|
||||||
@ -654,7 +654,7 @@ public class AssetsResource {
|
|||||||
})
|
})
|
||||||
public List<TransferAssetTransactionData> getAssetTransfers(@Parameter(
|
public List<TransferAssetTransactionData> getAssetTransfers(@Parameter(
|
||||||
ref = "assetid"
|
ref = "assetid"
|
||||||
) @PathParam("assetid") int assetId, @PathParam("address") String address, @Parameter(
|
) @PathParam("assetid") int assetId, @QueryParam("address") String address, @Parameter(
|
||||||
ref = "limit"
|
ref = "limit"
|
||||||
) @QueryParam("limit") Integer limit, @Parameter(
|
) @QueryParam("limit") Integer limit, @Parameter(
|
||||||
ref = "offset"
|
ref = "offset"
|
||||||
@ -665,7 +665,7 @@ public class AssetsResource {
|
|||||||
if (!repository.getAssetRepository().assetExists(assetId))
|
if (!repository.getAssetRepository().assetExists(assetId))
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ASSET_ID);
|
||||||
|
|
||||||
if (!Crypto.isValidAddress(address))
|
if (address != null && !Crypto.isValidAddress(address))
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_ADDRESS);
|
||||||
|
|
||||||
return repository.getTransactionRepository().getAssetTransfers(assetId, address, limit, offset, reverse);
|
return repository.getTransactionRepository().getAssetTransfers(assetId, address, limit, offset, reverse);
|
||||||
|
@ -2,12 +2,16 @@ package org.qora.data.asset;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import org.qora.crypto.Crypto;
|
||||||
|
|
||||||
// All properties to be converted to JSON via JAX-RS
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||||
|
|
||||||
|
// All properties to be converted to JSON via JAXB
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class OrderData implements Comparable<OrderData> {
|
public class OrderData implements Comparable<OrderData> {
|
||||||
|
|
||||||
@ -38,13 +42,59 @@ public class OrderData implements Comparable<OrderData> {
|
|||||||
@Schema(description = "has this order been fully traded?")
|
@Schema(description = "has this order been fully traded?")
|
||||||
private boolean isFulfilled;
|
private boolean isFulfilled;
|
||||||
|
|
||||||
|
// Used by API - not always present
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String creator;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String haveAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String wantAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private long amountAssetId;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String amountAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String pricePair;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
// necessary for JAX-RS serialization
|
// Necessary for JAXB serialization
|
||||||
protected OrderData() {
|
protected OrderData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderData(byte[] orderId, byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal fulfilled, BigDecimal price, long timestamp, boolean isClosed, boolean isFulfilled) {
|
// Called before converting to JSON for API
|
||||||
|
public void beforeMarshal(Marshaller m) {
|
||||||
|
if (this.creator == null && this.creatorPublicKey != null)
|
||||||
|
this.creator = Crypto.toAddress(this.creatorPublicKey);
|
||||||
|
|
||||||
|
// If we don't have the extra asset name fields then we can't fill in the others
|
||||||
|
if (this.haveAssetName == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 'old' pricing scheme is simpler so test for that first
|
||||||
|
// XXX TODO
|
||||||
|
|
||||||
|
// 'new' pricing scheme
|
||||||
|
if (this.haveAssetId < this.wantAssetId) {
|
||||||
|
this.amountAssetId = this.wantAssetId;
|
||||||
|
this.amountAssetName = this.wantAssetName;
|
||||||
|
this.pricePair = this.haveAssetName + "/" + this.wantAssetName;
|
||||||
|
} else {
|
||||||
|
this.amountAssetId = this.haveAssetId;
|
||||||
|
this.amountAssetName = this.haveAssetName;
|
||||||
|
this.pricePair = this.wantAssetName + "/" + this.haveAssetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs OrderData using data from repository, including optional API fields. */
|
||||||
|
public OrderData(byte[] orderId, byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal fulfilled, BigDecimal price, long timestamp,
|
||||||
|
boolean isClosed, boolean isFulfilled, String haveAssetName, String wantAssetName) {
|
||||||
this.orderId = orderId;
|
this.orderId = orderId;
|
||||||
this.creatorPublicKey = creatorPublicKey;
|
this.creatorPublicKey = creatorPublicKey;
|
||||||
this.haveAssetId = haveAssetId;
|
this.haveAssetId = haveAssetId;
|
||||||
@ -55,9 +105,17 @@ public class OrderData implements Comparable<OrderData> {
|
|||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.isClosed = isClosed;
|
this.isClosed = isClosed;
|
||||||
this.isFulfilled = isFulfilled;
|
this.isFulfilled = isFulfilled;
|
||||||
|
|
||||||
|
this.haveAssetName = haveAssetName;
|
||||||
|
this.wantAssetName = wantAssetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs OrderData using typical deserialized network data */
|
/** Constructs OrderData using data from repository, excluding optional API fields. */
|
||||||
|
public OrderData(byte[] orderId, byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal fulfilled, BigDecimal price, long timestamp, boolean isClosed, boolean isFulfilled) {
|
||||||
|
this(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled, price, timestamp, isClosed, isFulfilled, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs OrderData using data typically received from network. */
|
||||||
public OrderData(byte[] orderId, byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price, long timestamp) {
|
public OrderData(byte[] orderId, byte[] creatorPublicKey, long haveAssetId, long wantAssetId, BigDecimal amount, BigDecimal price, long timestamp) {
|
||||||
this(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, BigDecimal.ZERO.setScale(8), price, timestamp, false, false);
|
this(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, BigDecimal.ZERO.setScale(8), price, timestamp, false, false);
|
||||||
}
|
}
|
||||||
@ -116,6 +174,28 @@ public class OrderData implements Comparable<OrderData> {
|
|||||||
this.isFulfilled = isFulfilled;
|
this.isFulfilled = isFulfilled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some JAXB/API-related getters
|
||||||
|
|
||||||
|
public String getHaveAssetName() {
|
||||||
|
return this.haveAssetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWantAssetName() {
|
||||||
|
return this.wantAssetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAmountAssetId() {
|
||||||
|
return this.amountAssetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAmountAssetName() {
|
||||||
|
return this.amountAssetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPricePair() {
|
||||||
|
return this.pricePair;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(OrderData orderData) {
|
public int compareTo(OrderData orderData) {
|
||||||
// Compare using prices
|
// Compare using prices
|
||||||
|
@ -2,13 +2,16 @@ package org.qora.data.transaction;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
import org.qora.block.BlockChain;
|
||||||
import org.qora.transaction.Transaction.TransactionType;
|
import org.qora.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||||
|
|
||||||
// All properties to be converted to JSON via JAXB
|
// All properties to be converted to JSON via JAXB
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
@ -25,6 +28,23 @@ public class CreateAssetOrderTransactionData extends TransactionData {
|
|||||||
@Schema(description = "price in lowest-assetID asset / highest-assetID asset")
|
@Schema(description = "price in lowest-assetID asset / highest-assetID asset")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
|
// Used by API - not always present
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String haveAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String wantAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private long amountAssetId;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String amountAssetName;
|
||||||
|
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
private String pricePair;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
// For JAXB
|
// For JAXB
|
||||||
@ -32,16 +52,53 @@ public class CreateAssetOrderTransactionData extends TransactionData {
|
|||||||
super(TransactionType.CREATE_ASSET_ORDER);
|
super(TransactionType.CREATE_ASSET_ORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called before converting to JSON for API
|
||||||
|
public void beforeMarshal(Marshaller m) {
|
||||||
|
final boolean isNewPricing = this.timestamp > BlockChain.getInstance().getNewAssetPricingTimestamp();
|
||||||
|
|
||||||
|
this.amountAssetId = (isNewPricing && this.haveAssetId < this.wantAssetId) ? this.wantAssetId : this.haveAssetId;
|
||||||
|
|
||||||
|
// If we don't have the extra asset name fields then we can't fill in the others
|
||||||
|
if (this.haveAssetName == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isNewPricing) {
|
||||||
|
// 'new' pricing scheme
|
||||||
|
if (this.haveAssetId < this.wantAssetId) {
|
||||||
|
this.amountAssetName = this.wantAssetName;
|
||||||
|
this.pricePair = this.haveAssetName + "/" + this.wantAssetName;
|
||||||
|
} else {
|
||||||
|
this.amountAssetName = this.haveAssetName;
|
||||||
|
this.pricePair = this.wantAssetName + "/" + this.haveAssetName;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 'old' pricing scheme is simpler
|
||||||
|
this.amountAssetName = this.haveAssetName;
|
||||||
|
this.pricePair = this.wantAssetName + "/" + this.haveAssetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs using data from repository, including optional asset names. */
|
||||||
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
||||||
BigDecimal amount, BigDecimal price, BigDecimal fee, byte[] signature) {
|
BigDecimal amount, BigDecimal price, BigDecimal fee, String haveAssetName, String wantAssetName, byte[] signature) {
|
||||||
super(TransactionType.CREATE_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
super(TransactionType.CREATE_ASSET_ORDER, timestamp, txGroupId, reference, creatorPublicKey, fee, signature);
|
||||||
|
|
||||||
this.haveAssetId = haveAssetId;
|
this.haveAssetId = haveAssetId;
|
||||||
this.wantAssetId = wantAssetId;
|
this.wantAssetId = wantAssetId;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.price = price;
|
this.price = price;
|
||||||
|
|
||||||
|
this.haveAssetName = haveAssetName;
|
||||||
|
this.wantAssetName = wantAssetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructs using data from repository, excluding optional asset names. */
|
||||||
|
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
||||||
|
BigDecimal amount, BigDecimal price, BigDecimal fee, byte[] signature) {
|
||||||
|
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null, null, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor typically used with data from network. */
|
||||||
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
public CreateAssetOrderTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, long haveAssetId, long wantAssetId,
|
||||||
BigDecimal amount, BigDecimal price, BigDecimal fee) {
|
BigDecimal amount, BigDecimal price, BigDecimal fee) {
|
||||||
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null);
|
this(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, null);
|
||||||
|
@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||||||
import org.qora.transaction.Transaction.TransactionType;
|
import org.qora.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema.AccessMode;
|
||||||
|
|
||||||
// All properties to be converted to JSON via JAXB
|
// All properties to be converted to JSON via JAXB
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
@ -21,6 +22,10 @@ public class TransferAssetTransactionData extends TransactionData {
|
|||||||
private BigDecimal amount;
|
private BigDecimal amount;
|
||||||
private long assetId;
|
private long assetId;
|
||||||
|
|
||||||
|
// Used by API - not always present
|
||||||
|
@Schema(accessMode = AccessMode.READ_ONLY)
|
||||||
|
protected String assetName;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
// For JAXB
|
// For JAXB
|
||||||
@ -32,16 +37,25 @@ public class TransferAssetTransactionData extends TransactionData {
|
|||||||
this.creatorPublicKey = this.senderPublicKey;
|
this.creatorPublicKey = this.senderPublicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructs using data from repository, including optional assetName. */
|
||||||
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
||||||
long assetId, BigDecimal fee, byte[] signature) {
|
long assetId, BigDecimal fee, String assetName, byte[] signature) {
|
||||||
super(TransactionType.TRANSFER_ASSET, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
super(TransactionType.TRANSFER_ASSET, timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||||
|
|
||||||
this.senderPublicKey = senderPublicKey;
|
this.senderPublicKey = senderPublicKey;
|
||||||
this.recipient = recipient;
|
this.recipient = recipient;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.assetId = assetId;
|
this.assetId = assetId;
|
||||||
|
this.assetName = assetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructs using data from repository, excluding optional assetName. */
|
||||||
|
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
||||||
|
long assetId, BigDecimal fee, byte[] signature) {
|
||||||
|
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs using data typically received over network. */
|
||||||
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
public TransferAssetTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] senderPublicKey, String recipient, BigDecimal amount,
|
||||||
long assetId, BigDecimal fee) {
|
long assetId, BigDecimal fee) {
|
||||||
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null);
|
this(timestamp, txGroupId, reference, senderPublicKey, recipient, amount, assetId, fee, null);
|
||||||
|
@ -63,7 +63,7 @@ public interface TransactionRepository {
|
|||||||
throws DataException;
|
throws DataException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns list of TRANSFER_ASSET transactions relating to specific asset ID/address combination.
|
* Returns list of TRANSFER_ASSET transactions relating to specific asset ID, with optional address filter.
|
||||||
*
|
*
|
||||||
* @param assetId
|
* @param assetId
|
||||||
* @param address
|
* @param address
|
||||||
|
@ -6,6 +6,7 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -191,9 +192,13 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderData fromOrderId(byte[] orderId) throws DataException {
|
public OrderData fromOrderId(byte[] orderId) throws DataException {
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(
|
String sql = "SELECT creator, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled, HaveAsset.asset_name, WantAsset.asset_name "
|
||||||
"SELECT creator, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled FROM AssetOrders WHERE asset_order_id = ?",
|
+ "FROM AssetOrders "
|
||||||
orderId)) {
|
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
|
||||||
|
+ "JOIN Assets AS WantAsset ON WantAsset.asset_id = want_asset_id "
|
||||||
|
+ "WHERE asset_order_id = ?";
|
||||||
|
|
||||||
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, orderId)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -206,8 +211,10 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||||
boolean isClosed = resultSet.getBoolean(8);
|
boolean isClosed = resultSet.getBoolean(8);
|
||||||
boolean isFulfilled = resultSet.getBoolean(9);
|
boolean isFulfilled = resultSet.getBoolean(9);
|
||||||
|
String haveAssetName = resultSet.getString(10);
|
||||||
|
String wantAssetName = resultSet.getString(11);
|
||||||
|
|
||||||
return new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled, price, timestamp, isClosed, isFulfilled);
|
return new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled, price, timestamp, isClosed, isFulfilled, haveAssetName, wantAssetName);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DataException("Unable to fetch asset order from repository", e);
|
throw new DataException("Unable to fetch asset order from repository", e);
|
||||||
}
|
}
|
||||||
@ -216,16 +223,30 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
@Override
|
@Override
|
||||||
public List<OrderData> getOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
public List<OrderData> getOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
||||||
Boolean reverse) throws DataException {
|
Boolean reverse) throws DataException {
|
||||||
String sql = "SELECT creator, asset_order_id, amount, fulfilled, price, ordered FROM AssetOrders "
|
List<OrderData> orders = new ArrayList<OrderData>();
|
||||||
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND is_closed = FALSE AND is_fulfilled = FALSE ORDER BY price";
|
|
||||||
|
// Cache have & want asset names for later use, which also saves a table join
|
||||||
|
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||||
|
if (haveAssetData == null)
|
||||||
|
return orders;
|
||||||
|
|
||||||
|
AssetData wantAssetData = this.fromAssetId(wantAssetId);
|
||||||
|
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 ";
|
||||||
|
|
||||||
|
sql += "ORDER BY price";
|
||||||
if (reverse != null && reverse)
|
if (reverse != null && reverse)
|
||||||
sql += " DESC";
|
sql += " DESC";
|
||||||
|
|
||||||
sql += ", ordered";
|
sql += ", ordered";
|
||||||
if (reverse != null && reverse)
|
if (reverse != null && reverse)
|
||||||
sql += " DESC";
|
sql += " DESC";
|
||||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
|
||||||
|
|
||||||
List<OrderData> orders = new ArrayList<OrderData>();
|
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
@ -242,7 +263,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
boolean isFulfilled = false;
|
boolean isFulfilled = false;
|
||||||
|
|
||||||
OrderData order = new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
OrderData order = new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
||||||
price, timestamp, isClosed, isFulfilled);
|
price, timestamp, isClosed, isFulfilled, haveAssetData.getName(), wantAssetData.getName());
|
||||||
orders.add(order);
|
orders.add(order);
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
@ -254,22 +275,24 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OrderData> getOpenOrdersForTrading(long haveAssetId, long wantAssetId, BigDecimal minimumPrice) throws DataException {
|
public List<OrderData> getOpenOrdersForTrading(long haveAssetId, long wantAssetId, BigDecimal minimumPrice) throws DataException {
|
||||||
Object[] bindParams;
|
List<Object> bindParams = new ArrayList<>(3);
|
||||||
String sql = "SELECT creator, asset_order_id, amount, fulfilled, price, ordered FROM AssetOrders "
|
|
||||||
|
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 ";
|
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND NOT is_closed AND NOT is_fulfilled ";
|
||||||
|
|
||||||
|
Collections.addAll(bindParams, haveAssetId, wantAssetId);
|
||||||
|
|
||||||
if (minimumPrice != null) {
|
if (minimumPrice != null) {
|
||||||
sql += "AND price >= ? ";
|
sql += "AND price >= ? ";
|
||||||
bindParams = new Object[] {haveAssetId, wantAssetId, minimumPrice};
|
bindParams.add(minimumPrice);
|
||||||
} else {
|
|
||||||
bindParams = new Object[] {haveAssetId, wantAssetId};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += "ORDER BY price DESC, ordered";
|
sql += "ORDER BY price DESC, ordered";
|
||||||
|
|
||||||
List<OrderData> orders = new ArrayList<OrderData>();
|
List<OrderData> orders = new ArrayList<OrderData>();
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return orders;
|
return orders;
|
||||||
|
|
||||||
@ -283,6 +306,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
boolean isClosed = false;
|
boolean isClosed = false;
|
||||||
boolean isFulfilled = false;
|
boolean isFulfilled = false;
|
||||||
|
|
||||||
|
// We don't need asset names so we can use simpler constructor
|
||||||
OrderData order = new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
OrderData order = new OrderData(orderId, creatorPublicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
||||||
price, timestamp, isClosed, isFulfilled);
|
price, timestamp, isClosed, isFulfilled);
|
||||||
orders.add(order);
|
orders.add(order);
|
||||||
@ -297,13 +321,27 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
@Override
|
@Override
|
||||||
public List<OrderData> getAggregatedOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
public List<OrderData> getAggregatedOpenOrders(long haveAssetId, long wantAssetId, Integer limit, Integer offset,
|
||||||
Boolean reverse) throws DataException {
|
Boolean reverse) throws DataException {
|
||||||
String sql = "SELECT price, SUM(amount - fulfilled), MAX(ordered) FROM AssetOrders "
|
List<OrderData> orders = new ArrayList<OrderData>();
|
||||||
+ "WHERE have_asset_id = ? AND want_asset_id = ? AND is_closed = FALSE AND is_fulfilled = FALSE GROUP BY price ORDER BY price";
|
|
||||||
|
// Cache have & want asset names for later use, which also saves a table join
|
||||||
|
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||||
|
if (haveAssetData == null)
|
||||||
|
return orders;
|
||||||
|
|
||||||
|
AssetData wantAssetData = this.fromAssetId(wantAssetId);
|
||||||
|
if (wantAssetData == null)
|
||||||
|
return orders;
|
||||||
|
|
||||||
|
String sql = "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 ";
|
||||||
|
|
||||||
|
sql += "ORDER BY price";
|
||||||
if (reverse != null && reverse)
|
if (reverse != null && reverse)
|
||||||
sql += " DESC";
|
sql += " DESC";
|
||||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
|
||||||
|
|
||||||
List<OrderData> orders = new ArrayList<OrderData>();
|
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, haveAssetId, wantAssetId)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
@ -315,7 +353,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
long timestamp = resultSet.getTimestamp(3).getTime();
|
long timestamp = resultSet.getTimestamp(3).getTime();
|
||||||
|
|
||||||
OrderData order = new OrderData(null, null, haveAssetId, wantAssetId, totalUnfulfilled, BigDecimal.ZERO,
|
OrderData order = new OrderData(null, null, haveAssetId, wantAssetId, totalUnfulfilled, BigDecimal.ZERO,
|
||||||
price, timestamp, false, false);
|
price, timestamp, false, false, haveAssetData.getName(), wantAssetData.getName());
|
||||||
orders.add(order);
|
orders.add(order);
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
@ -328,15 +366,23 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
@Override
|
@Override
|
||||||
public List<OrderData> getAccountsOrders(byte[] publicKey, Boolean optIsClosed, Boolean optIsFulfilled,
|
public List<OrderData> getAccountsOrders(byte[] publicKey, Boolean optIsClosed, Boolean optIsFulfilled,
|
||||||
Integer limit, Integer offset, Boolean reverse) throws DataException {
|
Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||||
String sql = "SELECT asset_order_id, have_asset_id, want_asset_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
|
// We have to join for have/want asset data as it might vary
|
||||||
+ "FROM AssetOrders WHERE creator = ?";
|
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 "
|
||||||
|
+ "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 = ?";
|
||||||
|
|
||||||
if (optIsClosed != null)
|
if (optIsClosed != null)
|
||||||
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
|
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
if (optIsFulfilled != null)
|
if (optIsFulfilled != null)
|
||||||
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
|
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
sql += " ORDER BY ordered";
|
sql += " ORDER BY ordered";
|
||||||
if (reverse != null && reverse)
|
if (reverse != null && reverse)
|
||||||
sql += " DESC";
|
sql += " DESC";
|
||||||
|
|
||||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||||
|
|
||||||
List<OrderData> orders = new ArrayList<OrderData>();
|
List<OrderData> orders = new ArrayList<OrderData>();
|
||||||
@ -355,9 +401,11 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
long timestamp = resultSet.getTimestamp(7, Calendar.getInstance(HSQLDBRepository.UTC)).getTime();
|
||||||
boolean isClosed = resultSet.getBoolean(8);
|
boolean isClosed = resultSet.getBoolean(8);
|
||||||
boolean isFulfilled = resultSet.getBoolean(9);
|
boolean isFulfilled = resultSet.getBoolean(9);
|
||||||
|
String haveAssetName = resultSet.getString(10);
|
||||||
|
String wantAssetName = resultSet.getString(11);
|
||||||
|
|
||||||
OrderData order = new OrderData(orderId, publicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
OrderData order = new OrderData(orderId, publicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
||||||
price, timestamp, isClosed, isFulfilled);
|
price, timestamp, isClosed, isFulfilled, haveAssetName, wantAssetName);
|
||||||
orders.add(order);
|
orders.add(order);
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
@ -370,18 +418,32 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
@Override
|
@Override
|
||||||
public List<OrderData> getAccountsOrders(byte[] publicKey, long haveAssetId, long wantAssetId, Boolean optIsClosed,
|
public List<OrderData> getAccountsOrders(byte[] publicKey, long haveAssetId, long wantAssetId, Boolean optIsClosed,
|
||||||
Boolean optIsFulfilled, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
Boolean optIsFulfilled, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||||
|
List<OrderData> orders = new ArrayList<OrderData>();
|
||||||
|
|
||||||
|
// Cache have & want asset names for later use, which also saves a table join
|
||||||
|
AssetData haveAssetData = this.fromAssetId(haveAssetId);
|
||||||
|
if (haveAssetData == null)
|
||||||
|
return orders;
|
||||||
|
|
||||||
|
AssetData wantAssetData = this.fromAssetId(wantAssetId);
|
||||||
|
if (wantAssetData == null)
|
||||||
|
return orders;
|
||||||
|
|
||||||
String sql = "SELECT asset_order_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
|
String sql = "SELECT asset_order_id, amount, fulfilled, price, ordered, is_closed, is_fulfilled "
|
||||||
+ "FROM AssetOrders WHERE creator = ? AND have_asset_id = ? AND want_asset_id = ?";
|
+ "FROM AssetOrders "
|
||||||
|
+ "WHERE creator = ? AND have_asset_id = ? AND want_asset_id = ?";
|
||||||
|
|
||||||
if (optIsClosed != null)
|
if (optIsClosed != null)
|
||||||
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
|
sql += " AND is_closed = " + (optIsClosed ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
if (optIsFulfilled != null)
|
if (optIsFulfilled != null)
|
||||||
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
|
sql += " AND is_fulfilled = " + (optIsFulfilled ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
sql += " ORDER BY ordered";
|
sql += " ORDER BY ordered";
|
||||||
if (reverse != null && reverse)
|
if (reverse != null && reverse)
|
||||||
sql += " DESC";
|
sql += " DESC";
|
||||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
|
||||||
|
|
||||||
List<OrderData> orders = new ArrayList<OrderData>();
|
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, publicKey, haveAssetId, wantAssetId)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, publicKey, haveAssetId, wantAssetId)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
@ -397,7 +459,7 @@ public class HSQLDBAssetRepository implements AssetRepository {
|
|||||||
boolean isFulfilled = resultSet.getBoolean(7);
|
boolean isFulfilled = resultSet.getBoolean(7);
|
||||||
|
|
||||||
OrderData order = new OrderData(orderId, publicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
OrderData order = new OrderData(orderId, publicKey, haveAssetId, wantAssetId, amount, fulfilled,
|
||||||
price, timestamp, isClosed, isFulfilled);
|
price, timestamp, isClosed, isFulfilled, haveAssetData.getName(), wantAssetData.getName());
|
||||||
orders.add(order);
|
orders.add(order);
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
|
@ -17,8 +17,13 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||||
try (ResultSet resultSet = this.repository
|
String sql = "SELECT have_asset_id, amount, want_asset_id, price, HaveAsset.asset_name, WantAsset.asset_name "
|
||||||
.checkedExecute("SELECT have_asset_id, amount, want_asset_id, price FROM CreateAssetOrderTransactions WHERE signature = ?", signature)) {
|
+ "FROM CreateAssetOrderTransactions "
|
||||||
|
+ "JOIN Assets AS HaveAsset ON HaveAsset.asset_id = have_asset_id "
|
||||||
|
+ "JOIN Assets AS WantAsset ON WantAsset.asset_id = want_asset_id "
|
||||||
|
+ "WHERE signature = ?";
|
||||||
|
|
||||||
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -26,8 +31,10 @@ public class HSQLDBCreateAssetOrderTransactionRepository extends HSQLDBTransacti
|
|||||||
BigDecimal amount = resultSet.getBigDecimal(2);
|
BigDecimal amount = resultSet.getBigDecimal(2);
|
||||||
long wantAssetId = resultSet.getLong(3);
|
long wantAssetId = resultSet.getLong(3);
|
||||||
BigDecimal price = resultSet.getBigDecimal(4);
|
BigDecimal price = resultSet.getBigDecimal(4);
|
||||||
|
String haveAssetName = resultSet.getString(5);
|
||||||
|
String wantAssetName = resultSet.getString(6);
|
||||||
|
|
||||||
return new CreateAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, signature);
|
return new CreateAssetOrderTransactionData(timestamp, txGroupId, reference, creatorPublicKey, haveAssetId, wantAssetId, amount, price, fee, haveAssetName, wantAssetName, signature);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DataException("Unable to fetch create order transaction from repository", e);
|
throw new DataException("Unable to fetch create order transaction from repository", e);
|
||||||
}
|
}
|
||||||
|
@ -535,18 +535,30 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
|||||||
@Override
|
@Override
|
||||||
public List<TransferAssetTransactionData> getAssetTransfers(long assetId, String address, Integer limit, Integer offset, Boolean reverse)
|
public List<TransferAssetTransactionData> getAssetTransfers(long assetId, String address, Integer limit, Integer offset, Boolean reverse)
|
||||||
throws DataException {
|
throws DataException {
|
||||||
String sql = "SELECT creation, tx_group_id, reference, fee, signature, sender, recipient, amount FROM TransferAssetTransactions "
|
List<Object> bindParams = new ArrayList<>(3);
|
||||||
+ "JOIN Transactions USING (signature) "
|
|
||||||
+ "JOIN Accounts ON public_key = sender "
|
String sql = "SELECT creation, tx_group_id, reference, fee, signature, sender, recipient, amount, asset_name "
|
||||||
+ "WHERE asset_id = ? AND ? IN (account, recipient) "
|
+ "FROM TransferAssetTransactions JOIN Transactions USING (signature) ";
|
||||||
+ "ORDER by creation ";
|
|
||||||
|
if (address != null)
|
||||||
|
sql += "JOIN Accounts ON public_key = sender ";
|
||||||
|
|
||||||
|
sql += "JOIN Assets USING (asset_id) WHERE asset_id = ? ";
|
||||||
|
bindParams.add(assetId);
|
||||||
|
|
||||||
|
if (address != null) {
|
||||||
|
sql += "AND ? IN (account, recipient) ";
|
||||||
|
bindParams.add(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql += "ORDER by creation ";
|
||||||
|
|
||||||
sql += (reverse == null || !reverse) ? "ASC" : "DESC";
|
sql += (reverse == null || !reverse) ? "ASC" : "DESC";
|
||||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||||
|
|
||||||
List<TransferAssetTransactionData> assetTransfers = new ArrayList<>();
|
List<TransferAssetTransactionData> assetTransfers = new ArrayList<>();
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, assetId, address)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, bindParams.toArray())) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return assetTransfers;
|
return assetTransfers;
|
||||||
|
|
||||||
@ -559,8 +571,9 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
|||||||
byte[] creatorPublicKey = resultSet.getBytes(6);
|
byte[] creatorPublicKey = resultSet.getBytes(6);
|
||||||
String recipient = resultSet.getString(7);
|
String recipient = resultSet.getString(7);
|
||||||
BigDecimal amount = resultSet.getBigDecimal(8);
|
BigDecimal amount = resultSet.getBigDecimal(8);
|
||||||
|
String assetName = resultSet.getString(9);
|
||||||
|
|
||||||
assetTransfers.add(new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, signature));
|
assetTransfers.add(new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, signature));
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
return assetTransfers;
|
return assetTransfers;
|
||||||
|
@ -17,16 +17,18 @@ public class HSQLDBTransferAssetTransactionRepository extends HSQLDBTransactionR
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException {
|
||||||
try (ResultSet resultSet = this.repository
|
String sql = "SELECT recipient, asset_id, amount, asset_name FROM TransferAssetTransactions JOIN Assets USING (asset_id) WHERE signature = ?";
|
||||||
.checkedExecute("SELECT recipient, asset_id, amount FROM TransferAssetTransactions WHERE signature = ?", signature)) {
|
|
||||||
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, signature)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
String recipient = resultSet.getString(1);
|
String recipient = resultSet.getString(1);
|
||||||
long assetId = resultSet.getLong(2);
|
long assetId = resultSet.getLong(2);
|
||||||
BigDecimal amount = resultSet.getBigDecimal(3);
|
BigDecimal amount = resultSet.getBigDecimal(3);
|
||||||
|
String assetName = resultSet.getString(4);
|
||||||
|
|
||||||
return new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, signature);
|
return new TransferAssetTransactionData(timestamp, txGroupId, reference, creatorPublicKey, recipient, amount, assetId, fee, assetName, signature);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DataException("Unable to fetch transfer asset transaction from repository", e);
|
throw new DataException("Unable to fetch transfer asset transaction from repository", e);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user