diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index ba2ce3a1..efdc57ef 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -33,6 +33,7 @@ import org.qortal.arbitrary.ArbitraryDataTransactionBuilder; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.controller.Controller; import org.qortal.data.account.AccountData; +import org.qortal.data.arbitrary.ArbitraryResourceInfo; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; @@ -67,7 +68,42 @@ public class ArbitraryResource { @Context HttpServletRequest request; @Context HttpServletResponse response; @Context ServletContext context; - + + @GET + @Path("/resources") + @Operation( + summary = "List arbitrary resources available on chain, optionally filtered by service", + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class)) + ) + } + ) + @ApiErrors({ApiError.REPOSITORY_ISSUE}) + public List getResources( + @QueryParam("service") Service service, @Parameter( + ref = "limit" + ) @QueryParam("limit") Integer limit, @Parameter( + ref = "offset" + ) @QueryParam("offset") Integer offset, @Parameter( + ref = "reverse" + ) @QueryParam("reverse") Boolean reverse) { + try (final Repository repository = RepositoryManager.getRepository()) { + + List resources = repository.getArbitraryRepository() + .getArbitraryResources(service, limit, offset, reverse); + + if (resources == null) { + return new ArrayList<>(); + } + return resources; + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } + } + + @GET @Path("/search") @Operation( diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java new file mode 100644 index 00000000..fc949e41 --- /dev/null +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceInfo.java @@ -0,0 +1,17 @@ +package org.qortal.data.arbitrary; + +import org.qortal.data.transaction.ArbitraryTransactionData; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class ArbitraryResourceInfo { + + public String name; + public ArbitraryTransactionData.Service service; + + public ArbitraryResourceInfo() { + } + +} diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 549f2c5d..108bca59 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -1,5 +1,6 @@ package org.qortal.repository; +import org.qortal.data.arbitrary.ArbitraryResourceInfo; import org.qortal.data.network.ArbitraryPeerData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; @@ -21,6 +22,9 @@ public interface ArbitraryRepository { public ArbitraryTransactionData getLatestTransaction(String name, Service service, Method method) throws DataException; + public List getArbitraryResources(Service service, Integer limit, Integer offset, Boolean reverse) throws DataException; + + public List getArbitraryPeerDataForSignature(byte[] signature) throws DataException; public ArbitraryPeerData getArbitraryPeerDataForSignatureAndPeer(byte[] signature, String peerAddress) throws DataException; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index c608813d..07a7ed05 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -1,5 +1,6 @@ package org.qortal.repository.hsqldb; +import org.qortal.data.arbitrary.ArbitraryResourceInfo; import org.qortal.crypto.Crypto; import org.qortal.data.PaymentData; import org.qortal.data.network.ArbitraryPeerData; @@ -288,6 +289,53 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } + @Override + public List getArbitraryResources(Service service, Integer limit, Integer offset, Boolean reverse) throws DataException { + StringBuilder sql = new StringBuilder(512); + + sql.append("SELECT name, service FROM ArbitraryTransactions"); + + if (service != null) { + sql.append(" WHERE service = "); + sql.append(service.value); + } + + sql.append(" GROUP BY name, service ORDER BY name"); + + if (reverse != null && reverse) { + sql.append(" DESC"); + } + + HSQLDBRepository.limitOffsetSql(sql, limit, offset); + + List arbitraryResources = new ArrayList<>(); + + try (ResultSet resultSet = this.repository.checkedExecute(sql.toString())) { + if (resultSet == null) + return null; + + do { + String name = resultSet.getString(1); + Service serviceResult = Service.valueOf(resultSet.getInt(2)); + + // We should filter out resources without names + if (name == null) { + continue; + } + + ArbitraryResourceInfo arbitraryResourceInfo = new ArbitraryResourceInfo(); + arbitraryResourceInfo.name = name; + arbitraryResourceInfo.service = serviceResult; + + arbitraryResources.add(arbitraryResourceInfo); + } while (resultSet.next()); + + return arbitraryResources; + } catch (SQLException e) { + throw new DataException("Unable to fetch arbitrary transactions from repository", e); + } + } + // Peer file tracking