forked from Qortal/qortal
Added new GET /arbitrary/resources/names endpoint to fetch resources grouped by name.
This commit is contained in:
parent
b762eff4eb
commit
2850bd0b46
@ -40,6 +40,7 @@ import org.qortal.arbitrary.misc.Service;
|
|||||||
import org.qortal.controller.Controller;
|
import org.qortal.controller.Controller;
|
||||||
import org.qortal.data.account.AccountData;
|
import org.qortal.data.account.AccountData;
|
||||||
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
||||||
|
import org.qortal.data.arbitrary.ArbitraryResourceNameInfo;
|
||||||
import org.qortal.data.naming.NameData;
|
import org.qortal.data.naming.NameData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
@ -101,28 +102,73 @@ public class ArbitraryResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository()
|
List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository()
|
||||||
.getArbitraryResources(service, identifier, defaultRes, limit, offset, reverse);
|
.getArbitraryResources(service, identifier, null, defaultRes, limit, offset, reverse);
|
||||||
|
|
||||||
if (resources == null) {
|
if (resources == null) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeStatus == null || includeStatus == false) {
|
if (includeStatus != null && includeStatus == true) {
|
||||||
return resources;
|
resources = this.addStatusToResources(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine and add the status of each resource
|
return resources;
|
||||||
List<ArbitraryResourceInfo> updatedResources = new ArrayList<>();
|
|
||||||
for (ArbitraryResourceInfo resourceInfo : resources) {
|
} catch (DataException e) {
|
||||||
ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ResourceIdType.NAME,
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
resourceInfo.service, resourceInfo.identifier);
|
|
||||||
ArbitraryResourceSummary summary = resource.getSummary();
|
|
||||||
if (summary != null) {
|
|
||||||
resourceInfo.status = summary.status;
|
|
||||||
}
|
}
|
||||||
updatedResources.add(resourceInfo);
|
|
||||||
}
|
}
|
||||||
return updatedResources;
|
|
||||||
|
@GET
|
||||||
|
@Path("/resources/names")
|
||||||
|
@Operation(
|
||||||
|
summary = "List arbitrary resources available on chain, grouped by creator's name",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiErrors({ApiError.REPOSITORY_ISSUE})
|
||||||
|
public List<ArbitraryResourceNameInfo> getResourcesGroupedByName(
|
||||||
|
@QueryParam("service") Service service,
|
||||||
|
@QueryParam("identifier") String identifier,
|
||||||
|
@Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource,
|
||||||
|
@Parameter(ref = "limit") @QueryParam("limit") Integer limit,
|
||||||
|
@Parameter(ref = "offset") @QueryParam("offset") Integer offset,
|
||||||
|
@Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse,
|
||||||
|
@Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus) {
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
// Treat empty identifier as null
|
||||||
|
if (identifier != null && identifier.isEmpty()) {
|
||||||
|
identifier = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that "default" and "identifier" parameters cannot coexist
|
||||||
|
boolean defaultRes = Boolean.TRUE.equals(defaultResource);
|
||||||
|
if (defaultRes == true && identifier != null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "identifier cannot be specified when requesting a default resource");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ArbitraryResourceNameInfo> creatorNames = repository.getArbitraryRepository()
|
||||||
|
.getArbitraryResourceCreatorNames(service, identifier, defaultRes, limit, offset, reverse);
|
||||||
|
|
||||||
|
for (ArbitraryResourceNameInfo creatorName : creatorNames) {
|
||||||
|
String name = creatorName.name;
|
||||||
|
if (name != null) {
|
||||||
|
List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository()
|
||||||
|
.getArbitraryResources(service, identifier, name, defaultRes, null, null, reverse);
|
||||||
|
|
||||||
|
if (includeStatus != null && includeStatus == true) {
|
||||||
|
resources = this.addStatusToResources(resources);
|
||||||
|
}
|
||||||
|
creatorName.resources = resources;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return creatorNames;
|
||||||
|
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
@ -665,4 +711,19 @@ public class ArbitraryResource {
|
|||||||
ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier);
|
ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier);
|
||||||
return resource.getSummary();
|
return resource.getSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ArbitraryResourceInfo> addStatusToResources(List<ArbitraryResourceInfo> resources) {
|
||||||
|
// Determine and add the status of each resource
|
||||||
|
List<ArbitraryResourceInfo> updatedResources = new ArrayList<>();
|
||||||
|
for (ArbitraryResourceInfo resourceInfo : resources) {
|
||||||
|
ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ResourceIdType.NAME,
|
||||||
|
resourceInfo.service, resourceInfo.identifier);
|
||||||
|
ArbitraryResourceSummary summary = resource.getSummary();
|
||||||
|
if (summary != null) {
|
||||||
|
resourceInfo.status = summary.status;
|
||||||
|
}
|
||||||
|
updatedResources.add(resourceInfo);
|
||||||
|
}
|
||||||
|
return updatedResources;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package org.qortal.data.arbitrary;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class ArbitraryResourceNameInfo {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public List<ArbitraryResourceInfo> resources = new ArrayList<>();
|
||||||
|
|
||||||
|
public ArbitraryResourceNameInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package org.qortal.repository;
|
|||||||
|
|
||||||
import org.qortal.arbitrary.misc.Service;
|
import org.qortal.arbitrary.misc.Service;
|
||||||
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
||||||
|
import org.qortal.data.arbitrary.ArbitraryResourceNameInfo;
|
||||||
import org.qortal.data.network.ArbitraryPeerData;
|
import org.qortal.data.network.ArbitraryPeerData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
||||||
@ -23,7 +24,9 @@ public interface ArbitraryRepository {
|
|||||||
public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException;
|
public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method, String identifier) throws DataException;
|
||||||
|
|
||||||
|
|
||||||
public List<ArbitraryResourceInfo> getArbitraryResources(Service service, String identifier, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException;
|
public List<ArbitraryResourceInfo> getArbitraryResources(Service service, String identifier, String name, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException;
|
||||||
|
|
||||||
|
public List<ArbitraryResourceNameInfo> getArbitraryResourceCreatorNames(Service service, String identifier, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException;
|
||||||
|
|
||||||
|
|
||||||
public List<ArbitraryPeerData> getArbitraryPeerDataForSignature(byte[] signature) throws DataException;
|
public List<ArbitraryPeerData> getArbitraryPeerDataForSignature(byte[] signature) throws DataException;
|
||||||
|
@ -3,6 +3,7 @@ package org.qortal.repository.hsqldb;
|
|||||||
import org.qortal.arbitrary.misc.Service;
|
import org.qortal.arbitrary.misc.Service;
|
||||||
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
import org.qortal.data.arbitrary.ArbitraryResourceInfo;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
|
import org.qortal.data.arbitrary.ArbitraryResourceNameInfo;
|
||||||
import org.qortal.data.network.ArbitraryPeerData;
|
import org.qortal.data.network.ArbitraryPeerData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
||||||
@ -279,11 +280,79 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ArbitraryResourceInfo> getArbitraryResources(Service service, String identifier,
|
public List<ArbitraryResourceInfo> getArbitraryResources(Service service, String identifier, String name,
|
||||||
|
boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||||
|
StringBuilder sql = new StringBuilder(512);
|
||||||
|
List<Object> bindParams = new ArrayList<>();
|
||||||
|
|
||||||
|
sql.append("SELECT name, service, identifier FROM ArbitraryTransactions WHERE 1=1");
|
||||||
|
|
||||||
|
if (service != null) {
|
||||||
|
sql.append(" AND service = ");
|
||||||
|
sql.append(service.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultResource) {
|
||||||
|
// Default resource requested - use NULL identifier
|
||||||
|
sql.append(" AND identifier IS NULL");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Non-default resource requested
|
||||||
|
// Use an exact match identifier, or list all if supplied identifier is null
|
||||||
|
sql.append(" AND (identifier = ? OR (? IS NULL))");
|
||||||
|
bindParams.add(identifier);
|
||||||
|
bindParams.add(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
sql.append(" AND name = ?");
|
||||||
|
bindParams.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql.append(" GROUP BY name, service, identifier ORDER BY name");
|
||||||
|
|
||||||
|
if (reverse != null && reverse) {
|
||||||
|
sql.append(" DESC");
|
||||||
|
}
|
||||||
|
|
||||||
|
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||||
|
|
||||||
|
List<ArbitraryResourceInfo> arbitraryResources = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), bindParams.toArray())) {
|
||||||
|
if (resultSet == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
do {
|
||||||
|
String nameResult = resultSet.getString(1);
|
||||||
|
Service serviceResult = Service.valueOf(resultSet.getInt(2));
|
||||||
|
String identifierResult = resultSet.getString(3);
|
||||||
|
|
||||||
|
// We should filter out resources without names
|
||||||
|
if (name == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo();
|
||||||
|
arbitraryResourceInfo.name = nameResult;
|
||||||
|
arbitraryResourceInfo.service = serviceResult;
|
||||||
|
arbitraryResourceInfo.identifier = identifierResult;
|
||||||
|
|
||||||
|
arbitraryResources.add(arbitraryResourceInfo);
|
||||||
|
} while (resultSet.next());
|
||||||
|
|
||||||
|
return arbitraryResources;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to fetch arbitrary transactions from repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ArbitraryResourceNameInfo> getArbitraryResourceCreatorNames(Service service, String identifier,
|
||||||
boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||||
StringBuilder sql = new StringBuilder(512);
|
StringBuilder sql = new StringBuilder(512);
|
||||||
|
|
||||||
sql.append("SELECT name, service, identifier FROM ArbitraryTransactions WHERE 1=1");
|
sql.append("SELECT name FROM ArbitraryTransactions WHERE 1=1");
|
||||||
|
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
sql.append(" AND service = ");
|
sql.append(" AND service = ");
|
||||||
@ -302,7 +371,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
|||||||
sql.append(" AND (identifier = ? OR (? IS NULL))");
|
sql.append(" AND (identifier = ? OR (? IS NULL))");
|
||||||
}
|
}
|
||||||
|
|
||||||
sql.append(" GROUP BY name, service, identifier ORDER BY name");
|
sql.append(" GROUP BY name ORDER BY name");
|
||||||
|
|
||||||
if (reverse != null && reverse) {
|
if (reverse != null && reverse) {
|
||||||
sql.append(" DESC");
|
sql.append(" DESC");
|
||||||
@ -310,7 +379,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
|||||||
|
|
||||||
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
HSQLDBRepository.limitOffsetSql(sql, limit, offset);
|
||||||
|
|
||||||
List<ArbitraryResourceInfo> arbitraryResources = new ArrayList<>();
|
List<ArbitraryResourceNameInfo> arbitraryResources = new ArrayList<>();
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), identifier, identifier)) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql.toString(), identifier, identifier)) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
@ -318,20 +387,16 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
String name = resultSet.getString(1);
|
String name = resultSet.getString(1);
|
||||||
Service serviceResult = Service.valueOf(resultSet.getInt(2));
|
|
||||||
String identifierResult = resultSet.getString(3);
|
|
||||||
|
|
||||||
// We should filter out resources without names
|
// We should filter out resources without names
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo();
|
ArbitraryResourceNameInfo arbitraryResourceNameInfo = new ArbitraryResourceNameInfo();
|
||||||
arbitraryResourceInfo.name = name;
|
arbitraryResourceNameInfo.name = name;
|
||||||
arbitraryResourceInfo.service = serviceResult;
|
|
||||||
arbitraryResourceInfo.identifier = identifierResult;
|
|
||||||
|
|
||||||
arbitraryResources.add(arbitraryResourceInfo);
|
arbitraryResources.add(arbitraryResourceNameInfo);
|
||||||
} while (resultSet.next());
|
} while (resultSet.next());
|
||||||
|
|
||||||
return arbitraryResources;
|
return arbitraryResources;
|
||||||
|
Loading…
Reference in New Issue
Block a user