diff options
author | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2023-04-27 22:24:16 +0200 |
---|---|---|
committer | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2023-05-09 23:51:48 +0200 |
commit | 6bff6a56672f08ebe1255bfad73abebd91b25428 (patch) | |
tree | 093af1d534e73a053a9a4ea24ea4ebf3eaada283 /lib/private/Files/Cache/QuerySearchHelper.php | |
parent | f734a7646639549b626c05b12a789c8cdedf2511 (diff) | |
download | nextcloud-server-6bff6a56672f08ebe1255bfad73abebd91b25428.tar.gz nextcloud-server-6bff6a56672f08ebe1255bfad73abebd91b25428.zip |
PoC: SystemTags endpoint to return tags used by a user with meta data
Target case is photos app: when visiting the tags category, all systemtags
of the whole cloud are retrieved. In subequent steps the next tag is
requested until the browser view is filled with tag tiles (i.e. previews
are requested just as well).
With this approach, we incorpoate the dav search and look for user related
tags that are used by them, and already returns the statistics (number of
files tagged with the respective tag) as well as a file id for the purpose
to load the preview. This defaults to the file with the highest id.
Call:
curl -s -u 'user:password' \
'https://my.nc.srv/remote.php/dav/systemtags-current' \
-X PROPFIND -H 'Accept: text/plain' \
-H 'Accept-Language: en-US,en;q=0.5' -H 'Depth: 1' \
-H 'Content-Type: text/plain;charset=UTF-8' \
--data @/home/doe/request-systemtag-props.xml
With request-systemtag-props.xml:
<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:">
<d:prop xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
<oc:id/>
<oc:display-name/>
<oc:user-visible/>
<oc:user-assignable/>
<oc:can-assign/>
<nc:files-assigned/>
<nc:reference-fileid/>
</d:prop>
</d:propfind>
Example output:
…
<d:response>
<d:href>/master/remote.php/dav/systemtags/84</d:href>
<d:propstat>
<d:prop>
<oc:id>84</oc:id>
<oc:display-name>Computer</oc:display-name>
<oc:user-visible>true</oc:user-visible>
<oc:user-assignable>true</oc:user-assignable>
<oc:can-assign>true</oc:can-assign>
<nc:files-assigned>42</nc:files-assigned>
<nc:reference-fileid>924022</nc:reference-fileid>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/remote.php/dav/systemtags/97</d:href>
<d:propstat>
<d:prop>
<oc:id>97</oc:id>
<oc:display-name>Bear</oc:display-name>
<oc:user-visible>true</oc:user-visible>
<oc:user-assignable>true</oc:user-assignable>
<oc:can-assign>true</oc:can-assign>
<nc:files-assigned>1</nc:files-assigned>
<nc:reference-fileid>923422</nc:reference-fileid>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
…
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'lib/private/Files/Cache/QuerySearchHelper.php')
-rw-r--r-- | lib/private/Files/Cache/QuerySearchHelper.php | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index eba2aac927b..c2eed5688b5 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -74,6 +74,41 @@ class QuerySearchHelper { ); } + protected function applySearchConstraints(CacheQueryBuilder $query, ISearchQuery $searchQuery, array $caches): void { + $storageFilters = array_values(array_map(function (ICache $cache) { + return $cache->getQueryFilterForStorage(); + }, $caches)); + $storageFilter = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $storageFilters); + $filter = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [$searchQuery->getSearchOperation(), $storageFilter]); + $this->queryOptimizer->processOperator($filter); + + $searchExpr = $this->searchBuilder->searchOperatorToDBExpr($query, $filter); + if ($searchExpr) { + $query->andWhere($searchExpr); + } + + $this->searchBuilder->addSearchOrdersToQuery($query, $searchQuery->getOrder()); + + if ($searchQuery->getLimit()) { + $query->setMaxResults($searchQuery->getLimit()); + } + if ($searchQuery->getOffset()) { + $query->setFirstResult($searchQuery->getOffset()); + } + } + + public function findUsedTagsInCaches(ISearchQuery $searchQuery, array $caches): array { + $query = $this->getQueryBuilder(); + $query->selectTagUsage(); + + $this->applySearchConstraints($query, $searchQuery, $caches); + + $result = $query->execute(); + $tags = $result->fetchAll(); + $result->closeCursor(); + return $tags; + } + /** * Perform a file system search in multiple caches * @@ -127,26 +162,7 @@ class QuerySearchHelper { )); } - $storageFilters = array_values(array_map(function (ICache $cache) { - return $cache->getQueryFilterForStorage(); - }, $caches)); - $storageFilter = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $storageFilters); - $filter = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [$searchQuery->getSearchOperation(), $storageFilter]); - $this->queryOptimizer->processOperator($filter); - - $searchExpr = $this->searchBuilder->searchOperatorToDBExpr($builder, $filter); - if ($searchExpr) { - $query->andWhere($searchExpr); - } - - $this->searchBuilder->addSearchOrdersToQuery($query, $searchQuery->getOrder()); - - if ($searchQuery->getLimit()) { - $query->setMaxResults($searchQuery->getLimit()); - } - if ($searchQuery->getOffset()) { - $query->setFirstResult($searchQuery->getOffset()); - } + $this->applySearchConstraints($query, $searchQuery, $caches); $result = $query->execute(); $files = $result->fetchAll(); @@ -158,7 +174,7 @@ class QuerySearchHelper { $result->closeCursor(); // loop through all caches for each result to see if the result matches that storage - // results are grouped by the same array keys as the caches argument to allow the caller to distringuish the source of the results + // results are grouped by the same array keys as the caches argument to allow the caller to distinguish the source of the results $results = array_fill_keys(array_keys($caches), []); foreach ($rawEntries as $rawEntry) { foreach ($caches as $cacheKey => $cache) { |