diff options
author | Marcel Klehr <mklehr@gmx.net> | 2025-03-31 15:35:36 +0200 |
---|---|---|
committer | Marcel Klehr <mklehr@gmx.net> | 2025-07-15 09:15:16 +0200 |
commit | 3eef614769bec38ffe989f0c8f3f6f1824f21e29 (patch) | |
tree | cb6afdfb0941018dd1a0e5cf49a8ae0f384a4be4 | |
parent | 845b78086bfe117e87253fdefb12e8e19a57c640 (diff) | |
download | nextcloud-server-3eef614769bec38ffe989f0c8f3f6f1824f21e29.tar.gz nextcloud-server-3eef614769bec38ffe989f0c8f3f6f1824f21e29.zip |
feat(IFileAccess#getMounts): Add new method to retrieve all distinct mounts
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
-rw-r--r-- | lib/private/Files/Cache/FileAccess.php | 63 | ||||
-rw-r--r-- | lib/public/Files/Cache/IFileAccess.php | 15 |
2 files changed, 77 insertions, 1 deletions
diff --git a/lib/private/Files/Cache/FileAccess.php b/lib/private/Files/Cache/FileAccess.php index 6835fb948d6..863f17437c1 100644 --- a/lib/private/Files/Cache/FileAccess.php +++ b/lib/private/Files/Cache/FileAccess.php @@ -103,7 +103,7 @@ class FileAccess implements IFileAccess { * @param int $storageId The ID of the storage to search within. * @param int $rootId The file ID of the ancestor to base the search on. * @param int $lastFileId The last processed file ID. Only files with a higher ID will be included. Defaults to 0. - * @param array $mimeTypes An array of mime types to filter the results. If empty, no mime type filtering will be applied. + * @param list<int> $mimeTypes An array of mime types to filter the results. If empty, no mime type filtering will be applied. * @param bool $endToEndEncrypted Whether to include EndToEndEncrypted files * @param bool $serverSideEncrypted Whether to include ServerSideEncrypted files * @param int $maxResults The maximum number of results to retrieve. If set to 0, all matching files will be retrieved. @@ -161,4 +161,65 @@ class FileAccess implements IFileAccess { $files->closeCursor(); } + + /** + * Retrieves a list of all distinct mounts. + * Allows filtering by specific mount providers and excluding certain mount points. + * Optionally rewrites home directory root paths to avoid cache and trashbin. + * + * @param list<string> $mountProviders An array of mount provider class names to filter. If empty, all providers will be included. + * @param string|false $excludeMountPoints A string pattern to exclude mount points. Set to false to not exclude any mount points. + * @param bool $rewriteHomeDirectories Whether to rewrite the root path IDs for home directories to only include user files. + * @return \Generator A generator yielding mount configurations as an array containing 'storage_id', 'root_id', and 'override_root'. + * @throws Exception + */ + public function getDistinctMounts(array $mountProviders = [], string|false $excludeMountPoints = false, bool $rewriteHomeDirectories = true): \Generator { + $qb = $this->connection->getQueryBuilder(); + $qb->selectDistinct(['root_id', 'storage_id', 'mount_provider_class']) + ->from('mounts'); + if (count($mountProviders) > 0) { + $qb->where($qb->expr()->in('mount_provider_class', $qb->createPositionalParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY))); + } + if ($excludeMountPoints !== false) { + $qb->andWhere($qb->expr()->notLike('mount_point', $qb->createPositionalParameter($excludeMountPoints))); + } + $result = $qb->executeQuery(); + + + while ( + /** @var array{storage_id:int, root_id:int,mount_provider_class:string} $row */ + $row = $result->fetch() + ) { + $storageId = (int)$row['storage_id']; + $rootId = (int)$row['root_id']; + $overrideRoot = $rootId; + if (in_array($row['mount_provider_class'], [ + OC\Files\Mount\LocalHomeMountProvider::class, + OC\Files\Mount\ObjectHomeMountProvider::class, + ])) { + // Only crawl files, not cache or trashbin + $qb = $this->getQuery(); + try { + $qb->selectFileCache(); + /** @var array|false $root */ + $root = $qb + ->andWhere($qb->expr()->eq('filecache.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) + ->andWhere($qb->expr()->eq('filecache.path', $qb->createNamedParameter('files'))) + ->executeQuery()->fetch(); + if ($root !== false) { + $overrideRoot = intval($root['fileid']); + } + } catch (Exception $e) { + $this->logger->error('Could not fetch home storage files root for storage ' . $storageId, ['exception' => $e]); + continue; + } + } + yield [ + 'storage_id' => $storageId, + 'root_id' => $rootId, + 'override_root' => $overrideRoot, + ]; + } + $result->closeCursor(); + } } diff --git a/lib/public/Files/Cache/IFileAccess.php b/lib/public/Files/Cache/IFileAccess.php index 2a7cf2b27ae..4e819fcf942 100644 --- a/lib/public/Files/Cache/IFileAccess.php +++ b/lib/public/Files/Cache/IFileAccess.php @@ -99,4 +99,19 @@ interface IFileAccess { * @since 32.0.0 */ public function getByAncestorInStorage(int $storageId, int $rootId, int $lastFileId = 0, array $mimeTypes = [], bool $endToEndEncrypted = true, bool $serverSideEncrypted = true, int $maxResults = 100): \Generator; + + /** + * Retrieves a list of all distinct mounts. + * Allows filtering by specific mount providers and excluding certain mount points. + * Optionally rewrites home directory root paths to avoid cache and trashbin. + * + * @param list<string> $mountProviders An array of mount provider class names to filter. If empty, all providers will be included. + * @param string|false $excludeMountPoints A string pattern to exclude mount points. Set to false to not exclude any mount points. + * @param bool $rewriteHomeDirectories Whether to rewrite the root path IDs for home directories to only include user files. + * @return \Generator A generator yielding mount configurations as an array containing 'storage_id', 'root_id', and 'override_root'. + * @throws Exception + * + * @since 32.0.0 + */ + public function getDistinctMounts(array $mountProviders = [], string|false $excludeMountPoints = false, bool $rewriteHomeDirectories = true): \Generator; } |