From a286db2dfdccb7452fcf58f54e3476e959c387eb Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 15 Apr 2023 15:55:52 +0100 Subject: [PATCH] "namefilter" param in `GET /arbitrary/resources/search` is now exact match, which makes more sense when filtering results by names in a list. --- .../qortal/api/resource/ArbitraryResource.java | 16 +++++++++------- .../qortal/repository/ArbitraryRepository.java | 2 +- .../hsqldb/HSQLDBArbitraryRepository.java | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index e07bcd2e..8b03b608 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -174,29 +174,31 @@ public class ArbitraryResource { @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") List names, - @Parameter(description = "Filter names by list (partial matches allowed)") @QueryParam("namefilter") String nameListFilter, @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(ref = "limit") @QueryParam("limit") Integer limit, - @Parameter(ref = "offset") @QueryParam("offset") Integer offset, - @Parameter(ref = "reverse") @QueryParam("reverse") Boolean reverse, + @Parameter(description = "Filter names by list (exact matches only)") @QueryParam("namefilter") String nameListFilter, @Parameter(description = "Include followed names only") @QueryParam("followedonly") Boolean followedOnly, @Parameter(description = "Exclude blocked content") @QueryParam("excludeblocked") Boolean excludeBlocked, @Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus, - @Parameter(description = "Include metadata") @QueryParam("includemetadata") Boolean includeMetadata) { + @Parameter(description = "Include metadata") @QueryParam("includemetadata") Boolean includeMetadata, + @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()) { boolean defaultRes = Boolean.TRUE.equals(defaultResource); boolean usePrefixOnly = Boolean.TRUE.equals(prefixOnly); + List exactMatchNames = new ArrayList<>(); + if (nameListFilter != null) { // Load names from supplied list of names - names.addAll(ResourceListManager.getInstance().getStringsInList(nameListFilter)); + exactMatchNames.addAll(ResourceListManager.getInstance().getStringsInList(nameListFilter)); } List resources = repository.getArbitraryRepository() - .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, defaultRes, followedOnly, excludeBlocked, limit, offset, reverse); + .searchArbitraryResources(service, query, identifier, names, usePrefixOnly, exactMatchNames, defaultRes, followedOnly, excludeBlocked, limit, offset, reverse); if (resources == null) { return new ArrayList<>(); diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 9eea6bc2..9d9ed8ce 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -26,7 +26,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, List namesFilter, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException; public List getArbitraryResourceCreatorNames(Service service, String identifier, boolean defaultResource, Integer limit, Integer offset, Boolean reverse) 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 8d94c8bd..0a4e429f 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -393,7 +393,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, boolean prefixOnly, - boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, + List exactMatchNames, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -436,7 +436,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { bindParams.add(queryWildcard); } - // Handle name matches + // Handle name searches if (names != null && !names.isEmpty()) { sql.append(" AND ("); @@ -450,6 +450,18 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { sql.append(")"); } + // Handle name exact matches + if (exactMatchNames != null && !exactMatchNames.isEmpty()) { + sql.append(" AND name IN (?"); + bindParams.add(exactMatchNames.get(0)); + + for (int i = 1; i < exactMatchNames.size(); ++i) { + sql.append(", ?"); + bindParams.add(exactMatchNames.get(i)); + } + sql.append(")"); + } + // Handle "followed only" if (followedOnly != null && followedOnly) { List followedNames = ListUtils.followedNames();