From 8551ee079dfcc49c85ecea3a042077dc85790c67 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 19 Mar 2021 13:41:00 +0100 Subject: [PATCH] folder filtering in sql Signed-off-by: Robin Appelman --- lib/private/Files/Node/Folder.php | 36 ++++++++++++++++------------- tests/lib/Files/Node/FolderTest.php | 1 - 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index 39445437a36..4b63a26c272 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -33,6 +33,7 @@ namespace OC\Files\Node; use OC\DB\QueryBuilder\Literal; use OC\Files\Mount\MountPoint; +use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\Files\Storage\Wrapper\Jail; @@ -45,6 +46,7 @@ use OCP\Files\FileInfo; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchOperator; use OCP\Files\Search\ISearchQuery; @@ -253,10 +255,23 @@ class Folder extends Node implements \OCP\Files\Folder { throw new \InvalidArgumentException('searching by owner is only allows on the users home folder'); } + $rootLength = strlen($this->path); + $mount = $this->root->getMount($this->path); + $storage = $mount->getStorage(); + $internalPath = $mount->getInternalPath($this->path); + $internalPath = rtrim($internalPath, '/'); + if ($internalPath !== '') { + $internalPath = $internalPath . '/'; + } + $subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX; $subQueryOffset = $query->getOffset(); - $noLimitQuery = new SearchQuery( - $query->getSearchOperation(), + $rootQuery = new SearchQuery( + new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [ + new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'), + $query->getSearchOperation(), + ] + ), $subQueryLimit, 0, $query->getOrder(), @@ -264,28 +279,17 @@ class Folder extends Node implements \OCP\Files\Folder { ); $files = []; - $rootLength = strlen($this->path); - $mount = $this->root->getMount($this->path); - $storage = $mount->getStorage(); - $internalPath = $mount->getInternalPath($this->path); - $internalPath = rtrim($internalPath, '/'); - if ($internalPath !== '') { - $internalPath = $internalPath . '/'; - } - $internalRootLength = strlen($internalPath); $cache = $storage->getCache(''); - $results = $cache->searchQuery($noLimitQuery); + $results = $cache->searchQuery($rootQuery); $count = count($results); $results = array_slice($results, $subQueryOffset, $subQueryLimit); $subQueryOffset = max(0, $subQueryOffset - $count); $subQueryLimit = max(0, $subQueryLimit - $count); foreach ($results as $result) { - if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) { - $files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result); - } + $files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result); } if (!$limitToHome) { @@ -330,7 +334,7 @@ class Folder extends Node implements \OCP\Files\Folder { private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, string $trimRoot, ICacheEntry $cacheEntry): FileInfo { $trimLength = strlen($trimRoot); $cacheEntry['internalPath'] = $cacheEntry['path']; - $cacheEntry['path'] = $appendRoot . substr($cacheEntry['path'], $trimLength); + $cacheEntry['path'] = $appendRoot . substr($cacheEntry['path'], $trimLength); return new \OC\Files\FileInfo($this->path . '/' . $cacheEntry['path'], $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount); } diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 339a77edcc3..39dcffe5ae3 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -354,7 +354,6 @@ class FolderTest extends NodeTest { $cache->method('searchQuery') ->willReturn([ new CacheEntry(['fileid' => 3, 'path' => 'files/foo', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']), - new CacheEntry(['fileid' => 3, 'path' => 'files_trashbin/foo2.d12345', 'name' => 'foo2.d12345', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']), ]); $root->method('getMountsIn') -- 2.39.5