[21] generate a better optimized query for path prefix search filters

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2021-10-05 15:42:59 +02:00
parent 6039a43d13
commit 916a838873
No known key found for this signature in database
GPG key ID: 42B69D8A64526EFB
2 changed files with 24 additions and 26 deletions

View file

@ -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();

View file

@ -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);
}