|
10 | 10 |
|
11 | 11 | use OC\FilesMetadata\FilesMetadataManager; |
12 | 12 | use OC\SystemConfig; |
| 13 | +use OCP\DB\Exception; |
13 | 14 | use OCP\DB\QueryBuilder\IQueryBuilder; |
14 | 15 | use OCP\Files\Cache\IFileAccess; |
15 | 16 | use OCP\Files\IMimeTypeLoader; |
@@ -94,4 +95,70 @@ public function getByFileIdsInStorage(array $fileIds, int $storageId): array { |
94 | 95 | $rows = $query->executeQuery()->fetchAll(); |
95 | 96 | return $this->rowsToEntries($rows); |
96 | 97 | } |
| 98 | + |
| 99 | + /** |
| 100 | + * Retrieves files stored in a specific storage that have a specified ancestor in the file hierarchy. |
| 101 | + * Allows filtering by mime types, encryption status, and limits the number of results. |
| 102 | + * |
| 103 | + * @param int $storageId The ID of the storage to search within. |
| 104 | + * @param int $rootId The file ID of the ancestor to base the search on. |
| 105 | + * @param int $lastFileId The last processed file ID. Only files with a higher ID will be included. Defaults to 0. |
| 106 | + * @param array $mimeTypes An array of mime types to filter the results. If empty, no mime type filtering will be applied. |
| 107 | + * @param bool $endToEndEncrypted Whether to include EndToEndEncrypted files |
| 108 | + * @param bool $serverSideEncrypted Whether to include ServerSideEncrypted files |
| 109 | + * @param int $maxResults The maximum number of results to retrieve. If set to 0, all matching files will be retrieved. |
| 110 | + * @return \Generator A generator yielding matching files as cache entries. |
| 111 | + * @throws Exception |
| 112 | + */ |
| 113 | + public function getByAncestorInStorage(int $storageId, int $rootId, int $lastFileId = 0, array $mimeTypes = [], bool $endToEndEncrypted = true, bool $serverSideEncrypted = true, int $maxResults = 100): \Generator { |
| 114 | + $qb = $this->getQuery(); |
| 115 | + $qb->selectFileCache(); |
| 116 | + $qb->andWhere($qb->expr()->eq('filecache.fileid', $qb->createNamedParameter($rootId, IQueryBuilder::PARAM_INT))); |
| 117 | + $result = $qb->executeQuery(); |
| 118 | + /** @var array{path:string}|false $root */ |
| 119 | + $root = $result->fetch(); |
| 120 | + $result->closeCursor(); |
| 121 | + |
| 122 | + if ($root === false) { |
| 123 | + throw new Exception('Could not fetch storage root'); |
| 124 | + } |
| 125 | + |
| 126 | + $qb = $this->getQuery(); |
| 127 | + |
| 128 | + $path = $root['path'] === '' ? '' : $root['path'] . '/'; |
| 129 | + |
| 130 | + $qb->select('*') |
| 131 | + ->from('filecache', 'filecache') |
| 132 | + ->andWhere($qb->expr()->like('filecache.path', $qb->createNamedParameter($path . '%'))) |
| 133 | + ->andWhere($qb->expr()->eq('filecache.storage', $qb->createNamedParameter($storageId))) |
| 134 | + ->andWhere($qb->expr()->gt('filecache.fileid', $qb->createNamedParameter($lastFileId))); |
| 135 | + |
| 136 | + if (!$endToEndEncrypted) { |
| 137 | + $qb->innerJoin('filecache', 'filecache', 'p', $qb->expr()->eq('filecache.parent', 'p.fileid')); |
| 138 | + $qb->andWhere($qb->expr()->eq('p.encrypted', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); |
| 139 | + } |
| 140 | + |
| 141 | + if (!$serverSideEncrypted) { |
| 142 | + $qb->andWhere($qb->expr()->eq('filecache.encrypted', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); |
| 143 | + } |
| 144 | + |
| 145 | + if (count($mimeTypes) > 0) { |
| 146 | + $qb->andWhere($qb->expr()->in('filecache.mimetype', $qb->createNamedParameter($mimeTypes, IQueryBuilder::PARAM_INT_ARRAY))); |
| 147 | + } |
| 148 | + |
| 149 | + if ($maxResults !== 0) { |
| 150 | + $qb->setMaxResults($maxResults); |
| 151 | + } |
| 152 | + $files = $qb->orderBy('filecache.fileid', 'ASC') |
| 153 | + ->executeQuery(); |
| 154 | + |
| 155 | + while ( |
| 156 | + /** @var array */ |
| 157 | + $row = $files->fetch() |
| 158 | + ) { |
| 159 | + yield Cache::cacheEntryFromData($row, $this->mimeTypeLoader); |
| 160 | + } |
| 161 | + |
| 162 | + $files->closeCursor(); |
| 163 | + } |
97 | 164 | } |
0 commit comments