From 916a838873dc9c2b0adb53ecbad4b1170fd9bdd2 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 5 Oct 2021 15:42:59 +0200 Subject: [PATCH] [21] generate a better optimized query for path prefix search filters Signed-off-by: Robin Appelman --- lib/private/Files/Cache/Cache.php | 10 ++++- lib/private/Files/Cache/Wrapper/CacheJail.php | 40 ++++++++----------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index b851076e2c1..ae707fb5b54 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -800,7 +800,7 @@ class Cache implements ICache { * @param IResult $result * @return CacheEntry[] */ - private function searchResultToCacheEntries(IResult $result): array { + protected function searchResultToCacheEntries(IResult $result): array { $files = $result->fetchAll(); return array_map(function (array $data) { @@ -837,7 +837,7 @@ class Cache implements ICache { }, $files); } - public function searchQuery(ISearchQuery $searchQuery) { + protected function buildSearchQuery(ISearchQuery $searchQuery): IQueryBuilder { $builder = $this->getQueryBuilder(); $query = $builder->selectFileCache('file'); @@ -877,6 +877,12 @@ class Cache implements ICache { $query->setFirstResult($searchQuery->getOffset()); } + return $query; + } + + public function searchQuery(ISearchQuery $searchQuery) { + $query = $this->buildSearchQuery($searchQuery); + $result = $query->execute(); $cacheEntries = $this->searchResultToCacheEntries($result); $result->closeCursor(); diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index 8c6a1d21e76..5c4a75bfefc 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -29,13 +29,10 @@ namespace OC\Files\Cache\Wrapper; use OC\Files\Cache\Cache; -use OC\Files\Search\SearchBinaryOperator; -use OC\Files\Search\SearchComparison; +use OC\Files\Cache\QuerySearchHelper; use OC\Files\Search\SearchQuery; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Cache\ICacheEntry; -use OCP\Files\Search\ISearchBinaryOperator; -use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchQuery; /** @@ -63,6 +60,7 @@ class CacheJail extends CacheWrapper { } else { $this->unjailedRoot = $root; } + $this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader); } protected function getRoot() { @@ -260,7 +258,7 @@ class CacheJail extends CacheWrapper { ->whereStorageId() ->andWhere($query->expr()->orX( $query->expr()->like('path', $query->createNamedParameter($this->getGetUnjailedRoot() . '/%')), - $query->expr()->eq('path_hash', $query->createNamedParameter(md5($this->getGetUnjailedRoot()))), + $query->expr()->eq('path', $query->createNamedParameter($this->getGetUnjailedRoot())), )) ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern))); @@ -292,7 +290,7 @@ class CacheJail extends CacheWrapper { ->whereStorageId() ->andWhere($query->expr()->orX( $query->expr()->like('path', $query->createNamedParameter($this->getGetUnjailedRoot() . '/%')), - $query->expr()->eq('path_hash', $query->createNamedParameter(md5($this->getGetUnjailedRoot()))), + $query->expr()->eq('path', $query->createNamedParameter($this->getGetUnjailedRoot())), )); if (strpos($mimetype, '/')) { @@ -311,27 +309,21 @@ class CacheJail extends CacheWrapper { return $this->formatSearchResults($results); } - public function searchQuery(ISearchQuery $query) { + public function searchQuery(ISearchQuery $searchQuery) { if ($this->getGetUnjailedRoot() === '' || $this->getGetUnjailedRoot() === '/') { - return parent::searchQuery($query); + return parent::searchQuery($searchQuery); } - $prefixFilter = new SearchComparison( - ISearchComparison::COMPARE_LIKE, - 'path', - $this->getGetUnjailedRoot() . '/%' - ); - $rootFilter = new SearchComparison( - ISearchComparison::COMPARE_EQUAL, - 'path', - $this->getGetUnjailedRoot() - ); - $operation = new SearchBinaryOperator( - ISearchBinaryOperator::OPERATOR_AND, - [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [$prefixFilter, $rootFilter]) , $query->getSearchOperation()] - ); - $simpleQuery = new SearchQuery($operation, $query->getLimit(), $query->getOffset(), $query->getOrder(), $query->getUser()); - $results = $this->getCache()->searchQuery($simpleQuery); + $query = $this->buildSearchQuery($searchQuery); + + $query->andWhere($query->expr()->orX( + $query->expr()->like('path', $query->createNamedParameter($this->getGetUnjailedRoot() . '/%')), + $query->expr()->eq('path', $query->createNamedParameter($this->getGetUnjailedRoot())), + )); + + $result = $query->execute(); + $results = $this->searchResultToCacheEntries($result); + $result->closeCursor(); return $this->formatSearchResults($results); } -- 2.39.5