You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nextcloud-server/lib/private/Files/Cache/CacheQueryBuilder.php

126 lines
3.7 KiB

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Files\Cache;
use OC\DB\QueryBuilder\ExtendedQueryBuilder;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\FilesMetadata\IFilesMetadataManager;
use OCP\FilesMetadata\IMetadataQuery;
/**
* Query builder with commonly used helpers for filecache queries
*/
class CacheQueryBuilder extends ExtendedQueryBuilder {
private ?string $alias = null;
public function __construct(
IQueryBuilder $queryBuilder,
private IFilesMetadataManager $filesMetadataManager,
) {
parent::__construct($queryBuilder);
}
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>
3 years ago
public function selectTagUsage(): self {
$this
->select('systemtag.name', 'systemtag.id', 'systemtag.visibility', 'systemtag.editable', 'systemtag.etag', 'systemtag.color')
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>
3 years ago
->selectAlias($this->createFunction('COUNT(filecache.fileid)'), 'number_files')
->selectAlias($this->createFunction('MAX(filecache.fileid)'), 'ref_file_id')
->from('filecache', 'filecache')
->leftJoin('filecache', 'systemtag_object_mapping', 'systemtagmap', $this->expr()->andX(
$this->expr()->eq('filecache.fileid', $this->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)),
$this->expr()->eq('systemtagmap.objecttype', $this->createNamedParameter('files'))
))
->leftJoin('systemtagmap', 'systemtag', 'systemtag', $this->expr()->andX(
$this->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'),
$this->expr()->eq('systemtag.visibility', $this->createNamedParameter(true))
))
->groupBy('systemtag.name', 'systemtag.id', 'systemtag.visibility', 'systemtag.editable');
return $this;
}
public function selectFileCache(?string $alias = null, bool $joinExtendedCache = true) {
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>
3 years ago
$name = $alias ?: 'filecache';
$this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", "$name.name", 'mimetype', 'mimepart', 'size', 'mtime',
'storage_mtime', 'encrypted', "$name.etag", "$name.permissions", 'checksum', 'unencrypted_size')
->from('filecache', $name);
if ($joinExtendedCache) {
$this->addSelect('metadata_etag', 'creation_time', 'upload_time');
$this->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid'));
}
$this->alias = $name;
return $this;
}
public function whereStorageId(int $storageId) {
$this->andWhere($this->expr()->eq('storage', $this->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
return $this;
}
public function whereFileId(int $fileId) {
$alias = $this->alias;
if ($alias) {
$alias .= '.';
} else {
$alias = '';
}
$this->andWhere($this->expr()->eq("{$alias}fileid", $this->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
return $this;
}
public function wherePath(string $path) {
$this->andWhere($this->expr()->eq('path_hash', $this->createNamedParameter(md5($path))));
return $this;
}
public function whereParent(int $parent) {
$alias = $this->alias;
if ($alias) {
$alias .= '.';
} else {
$alias = '';
}
$this->andWhere($this->expr()->eq("{$alias}parent", $this->createNamedParameter($parent, IQueryBuilder::PARAM_INT)));
return $this;
}
public function whereParentInParameter(string $parameter) {
$alias = $this->alias;
if ($alias) {
$alias .= '.';
} else {
$alias = '';
}
$this->andWhere($this->expr()->in("{$alias}parent", $this->createParameter($parameter)));
return $this;
}
/**
* join metadata to current query builder and returns an helper
*
* @return IMetadataQuery
*/
public function selectMetadata(): IMetadataQuery {
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($this, $this->alias, 'fileid');
$metadataQuery->retrieveMetadata();
return $metadataQuery;
}
}