Browse Source

Added GET /arbitrary/resources/search API

Example usage

List all websites with a name containing the word "crow" (using default identifier):
http://localhost:12391/arbitrary/resources/search?service=WEBSITE&query=crow&default=true&limit=20

List all resources with name or identifier containing the word "crow":
http://localhost:12391/arbitrary/resources/search?query=crow&default=false&limit=20
trade-portal-updates
CalDescent 3 years ago
parent
commit
85c61c1bc1
  1. 43
      src/main/java/org/qortal/api/resource/ArbitraryResource.java
  2. 2
      src/main/java/org/qortal/repository/ArbitraryRepository.java
  3. 69
      src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java

43
src/main/java/org/qortal/api/resource/ArbitraryResource.java

@ -121,6 +121,49 @@ public class ArbitraryResource {
}
}
@GET
@Path("/resources/search")
@Operation(
summary = "Search arbitrary resources available on chain, optionally filtered by service.\n" +
"If default is set to true, only resources without identifiers will be returned.",
responses = {
@ApiResponse(
content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryResourceInfo.class))
)
}
)
@ApiErrors({ApiError.REPOSITORY_ISSUE})
public List<ArbitraryResourceInfo> searchResources(
@QueryParam("service") Service service,
@QueryParam("query") String query,
@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()) {
boolean defaultRes = Boolean.TRUE.equals(defaultResource);
List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository()
.searchArbitraryResources(service, query, defaultRes, limit, offset, reverse);
if (resources == null) {
return new ArrayList<>();
}
if (includeStatus != null && includeStatus == true) {
resources = this.addStatusToResources(resources);
}
return resources;
} catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}
}
@GET
@Path("/resources/names")
@Operation(

2
src/main/java/org/qortal/repository/ArbitraryRepository.java

@ -26,6 +26,8 @@ public interface ArbitraryRepository {
public List<ArbitraryResourceInfo> getArbitraryResources(Service service, String identifier, String name, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException;
public List<ArbitraryResourceInfo> searchArbitraryResources(Service service, String query, 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;

69
src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java

@ -367,6 +367,75 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
}
}
@Override
public List<ArbitraryResourceInfo> searchArbitraryResources(Service service, String query,
boolean defaultResource, Integer limit, Integer offset, Boolean reverse) throws DataException {
StringBuilder sql = new StringBuilder(512);
List<Object> bindParams = new ArrayList<>();
// For now we are searching anywhere in the fields
// Note that this will bypass any indexes so may not scale well
// Longer term we probably want to copy resources to their own table anyway
String queryWildcard = String.format("%%%s%%", query.toLowerCase());
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 and search name only
sql.append(" AND LCASE(name) LIKE ? AND identifier IS NULL");
bindParams.add(queryWildcard);
}
else {
// Non-default resource requested
// In this case we search the identifier as well as the name
sql.append(" AND (LCASE(name) LIKE ? OR LCASE(identifier) LIKE ?)");
bindParams.add(queryWildcard);
bindParams.add(queryWildcard);
}
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 (nameResult == 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 {

Loading…
Cancel
Save