From badd6ad2b0dbf97bf963e632469fd120aa39ef4d Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 23 Jun 2023 11:55:49 +0100 Subject: [PATCH] Added optional minLevel filter to `GET /arbitrary/resources/search` and the `SEARCH_QDN_RESOURCES` action. --- Q-Apps.md | 1 + .../api/resource/ArbitraryResource.java | 3 ++- .../repository/ArbitraryRepository.java | 2 +- .../hsqldb/HSQLDBArbitraryRepository.java | 21 ++++++++++++++----- src/main/resources/q-apps/q-apps.js | 1 + 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Q-Apps.md b/Q-Apps.md index 1b4f33bb..bf44a981 100644 --- a/Q-Apps.md +++ b/Q-Apps.md @@ -376,6 +376,7 @@ let res = await qortalRequest({ exactMatchNames: true, // Optional - if true, partial name matches are excluded default: false, // Optional - if true, only resources without identifiers are returned mode: "LATEST", // Optional - whether to return all resources or just the latest for a name/service combination. Possible values: ALL,LATEST. Default: LATEST + minLevel: 1, // Optional - whether to filter results by minimum account level includeStatus: false, // Optional - will take time to respond, so only request if necessary includeMetadata: false, // Optional - will take time to respond, so only request if necessary nameListFilter: "QApp1234Subscriptions", // Optional - will only return results if they are from a name included in supplied list diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index b7eb6cd4..22a74f42 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -172,6 +172,7 @@ public class ArbitraryResource { @Parameter(description = "Exact match names only (if true, partial name matches are excluded)") @QueryParam("exactmatchnames") Boolean exactMatchNamesOnly, @Parameter(description = "Default resources (without identifiers) only") @QueryParam("default") Boolean defaultResource, @Parameter(description = "Search mode") @QueryParam("mode") SearchMode mode, + @Parameter(description = "Min level") @QueryParam("minlevel") Integer minLevel, @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, @@ -208,7 +209,7 @@ public class ArbitraryResource { List resources = repository.getArbitraryRepository() .searchArbitraryResources(service, query, identifier, names, title, description, usePrefixOnly, - exactMatchNames, defaultRes, mode, followedOnly, excludeBlocked, includeMetadata, includeStatus, + exactMatchNames, defaultRes, mode, minLevel, followedOnly, excludeBlocked, includeMetadata, includeStatus, before, after, limit, offset, reverse); if (resources == null) { diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 8cff1231..c586871f 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -42,7 +42,7 @@ public interface ArbitraryRepository { public List getArbitraryResources(Service service, String identifier, List names, boolean defaultResource, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Integer limit, Integer offset, Boolean reverse) throws DataException; - public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; + public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, List namesFilter, boolean defaultResource, SearchMode mode, Integer minLevel, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException; // Arbitrary resources cache save/load diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index a20036de..85c60b4c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -580,8 +580,8 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { "WHERE name IS NOT NULL"); if (service != null) { - sql.append(" AND service = "); - sql.append(service.value); + sql.append(" AND service = ?"); + bindParams.add(service.value); } if (defaultResource) { @@ -719,7 +719,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { @Override public List searchArbitraryResources(Service service, String query, String identifier, List names, String title, String description, boolean prefixOnly, - List exactMatchNames, boolean defaultResource, SearchMode mode, Boolean followedOnly, Boolean excludeBlocked, + List exactMatchNames, boolean defaultResource, SearchMode mode, Integer minLevel, Boolean followedOnly, Boolean excludeBlocked, Boolean includeMetadata, Boolean includeStatus, Long before, Long after, Integer limit, Integer offset, Boolean reverse) throws DataException { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); @@ -746,11 +746,22 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { break; } + if (minLevel != null) { + // Join tables necessary for level filter + sql.append(" JOIN Names USING (name) JOIN Accounts ON Accounts.account=Names.owner"); + } + sql.append(" LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) WHERE name IS NOT NULL"); + if (minLevel != null) { + // Add level filter + sql.append(" AND Accounts.level >= ?"); + bindParams.add(minLevel); + } + if (service != null) { - sql.append(" AND service = "); - sql.append(service.value); + sql.append(" AND service = ?"); + bindParams.add(service.value); } // Handle general query matches diff --git a/src/main/resources/q-apps/q-apps.js b/src/main/resources/q-apps/q-apps.js index 6cc1bf08..885a9ba6 100644 --- a/src/main/resources/q-apps/q-apps.js +++ b/src/main/resources/q-apps/q-apps.js @@ -233,6 +233,7 @@ window.addEventListener("message", (event) => { if (data.exactMatchNames != null) url = url.concat("&exactmatchnames=" + new Boolean(data.exactMatchNames).toString()); if (data.default != null) url = url.concat("&default=" + new Boolean(data.default).toString()); if (data.mode != null) url = url.concat("&mode=" + data.mode); + if (data.minLevel != null) url = url.concat("&minlevel=" + data.minLevel); if (data.includeStatus != null) url = url.concat("&includestatus=" + new Boolean(data.includeStatus).toString()); if (data.includeMetadata != null) url = url.concat("&includemetadata=" + new Boolean(data.includeMetadata).toString()); if (data.nameListFilter != null) url = url.concat("&namefilter=" + data.nameListFilter);