Added "identifier", "name", and "prefix" parameters to GET /arbitrary/resources/search endpoint.

- "identifier" is an alternative to "query" that will search identifiers only.
- "name" is an alternative to "query" that will search names only.
- "query" remains the same as before - it searches both name and identifier fields.
- "prefix" is a boolean, and when true it will only match the beginning of each field. Works with "identifier", "name", and "query" params.
This commit is contained in:
CalDescent 2023-03-17 19:47:57 +00:00
parent d9cac6db39
commit 5656100197
3 changed files with 39 additions and 17 deletions

View File

@ -157,7 +157,10 @@ public class ArbitraryResource {
@ApiErrors({ApiError.REPOSITORY_ISSUE}) @ApiErrors({ApiError.REPOSITORY_ISSUE})
public List<ArbitraryResourceInfo> searchResources( public List<ArbitraryResourceInfo> searchResources(
@QueryParam("service") Service service, @QueryParam("service") Service service,
@QueryParam("query") String query, @Parameter(description = "Query (searches both name and identifier fields)") @QueryParam("query") String query,
@Parameter(description = "Identifier (searches identifier field only)") @QueryParam("identifier") String identifier,
@Parameter(description = "Name (searches name field only)") @QueryParam("name") String name,
@Parameter(description = "Prefix only (if true, only the beginning of fields are matched)") @QueryParam("prefix") Boolean prefixOnly,
@Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource,
@Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "limit") @QueryParam("limit") Integer limit,
@Parameter(ref = "offset") @QueryParam("offset") Integer offset, @Parameter(ref = "offset") @QueryParam("offset") Integer offset,
@ -168,9 +171,10 @@ public class ArbitraryResource {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
boolean defaultRes = Boolean.TRUE.equals(defaultResource); boolean defaultRes = Boolean.TRUE.equals(defaultResource);
boolean usePrefixOnly = Boolean.TRUE.equals(prefixOnly);
List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository() List<ArbitraryResourceInfo> resources = repository.getArbitraryRepository()
.searchArbitraryResources(service, query, defaultRes, limit, offset, reverse); .searchArbitraryResources(service, query, identifier, name, usePrefixOnly, defaultRes, limit, offset, reverse);
if (resources == null) { if (resources == null) {
return new ArrayList<>(); return new ArrayList<>();

View File

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

View File

@ -378,16 +378,11 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
} }
@Override @Override
public List<ArbitraryResourceInfo> searchArbitraryResources(Service service, String query, public List<ArbitraryResourceInfo> searchArbitraryResources(Service service, String query, String identifier, String name, boolean prefixOnly,
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);
List<Object> bindParams = new ArrayList<>(); 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, MAX(size) AS max_size FROM ArbitraryTransactions WHERE 1=1"); sql.append("SELECT name, service, identifier, MAX(size) AS max_size FROM ArbitraryTransactions WHERE 1=1");
if (service != null) { if (service != null) {
@ -395,16 +390,39 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
sql.append(service.value); sql.append(service.value);
} }
if (defaultResource) { // Handle general query matches
// Default resource requested - use NULL identifier and search name only if (query != null) {
sql.append(" AND LCASE(name) LIKE ? AND identifier IS NULL"); // Search anywhere in the fields, unless "prefixOnly" has been requested
// Note that without prefixOnly it will bypass any indexes so may not scale well
// Longer term we probably want to copy resources to their own table anyway
String queryWildcard = prefixOnly ? String.format("%s%%", query.toLowerCase()) : String.format("%%%s%%", query.toLowerCase());
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);
}
}
// Handle identifier matches
if (identifier != null) {
// Search anywhere in the identifier, unless "prefixOnly" has been requested
String queryWildcard = prefixOnly ? String.format("%s%%", identifier.toLowerCase()) : String.format("%%%s%%", identifier.toLowerCase());
sql.append(" AND LCASE(identifier) LIKE ?");
bindParams.add(queryWildcard); bindParams.add(queryWildcard);
} }
else {
// Non-default resource requested // Handle name matches
// In this case we search the identifier as well as the name if (name != null) {
sql.append(" AND (LCASE(name) LIKE ? OR LCASE(identifier) LIKE ?)"); // Search anywhere in the identifier, unless "prefixOnly" has been requested
bindParams.add(queryWildcard); String queryWildcard = prefixOnly ? String.format("%s%%", name.toLowerCase()) : String.format("%%%s%%", name.toLowerCase());
sql.append(" AND LCASE(name) LIKE ?");
bindParams.add(queryWildcard); bindParams.add(queryWildcard);
} }