Browse Source

use searchoperation for storage filter instead of db expression

Signed-off-by: Robin Appelman <robin@icewind.nl>
pull/26874/head
Robin Appelman 5 years ago
parent
commit
9774fb1573
No known key found for this signature in database GPG Key ID: 42B69D8A64526EFB
  1. 21
      apps/files_sharing/lib/Cache.php
  2. 5
      lib/private/Files/Cache/Cache.php
  3. 8
      lib/private/Files/Cache/FailedCache.php
  4. 24
      lib/private/Files/Cache/QuerySearchHelper.php
  5. 26
      lib/private/Files/Cache/Wrapper/CacheJail.php
  6. 6
      lib/private/Files/Cache/Wrapper/CacheWrapper.php
  7. 8
      lib/private/Lockdown/Filesystem/NullCache.php
  8. 10
      lib/public/Files/Cache/ICache.php

21
apps/files_sharing/lib/Cache.php

@ -30,9 +30,13 @@ namespace OCA\Files_Sharing;
use OC\Files\Cache\FailedCache;
use OC\Files\Cache\Wrapper\CacheJail;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Storage\Wrapper\Jail;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\StorageNotAvailableException;
/**
@ -182,18 +186,19 @@ class Cache extends CacheJail {
// Not a valid action for Shared Cache
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
public function getQueryFilterForStorage(): ISearchOperator {
// Do the normal jail behavior for non files
if ($this->storage->getItemType() !== 'file') {
return parent::getQueryFilterForStorage($builder);
return parent::getQueryFilterForStorage();
}
// for single file shares we don't need to do the LIKE
return $builder->expr()->andX(
parent::getQueryFilterForStorage($builder),
$builder->expr()->orX(
$builder->expr()->eq('path_hash', $builder->createNamedParameter(md5($this->getGetUnjailedRoot()))),
)
return new SearchBinaryOperator(
ISearchBinaryOperator::OPERATOR_AND,
[
\OC\Files\Cache\Cache::getQueryFilterForStorage(),
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
]
);
}
}

5
lib/private/Files/Cache/Cache.php

@ -54,6 +54,7 @@ use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
use OCP\Files\Storage\IStorage;
use OCP\IDBConnection;
@ -1050,8 +1051,8 @@ class Cache implements ICache {
];
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
return $builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId(), IQueryBuilder::PARAM_INT));
public function getQueryFilterForStorage(): ISearchOperator {
return new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', $this->getNumericStorageId());
}
public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

8
lib/private/Files/Cache/FailedCache.php

@ -21,10 +21,12 @@
*/
namespace OC\Files\Cache;
use OC\Files\Search\SearchComparison;
use OCP\Constants;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
/**
@ -140,8 +142,8 @@ class FailedCache implements ICache {
throw new \Exception("Invalid cache");
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
return 'false';
public function getQueryFilterForStorage(): ISearchOperator {
return new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', -1);
}
public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

24
lib/private/Files/Cache/QuerySearchHelper.php

@ -25,6 +25,7 @@
*/
namespace OC\Files\Cache;
use OC\Files\Search\SearchBinaryOperator;
use OC\SystemConfig;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache;
@ -47,7 +48,7 @@ class QuerySearchHelper {
ISearchComparison::COMPARE_GREATER_THAN => 'gt',
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte',
ISearchComparison::COMPARE_LESS_THAN => 'lt',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte'
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte',
];
protected static $searchOperatorNegativeMap = [
@ -56,7 +57,7 @@ class QuerySearchHelper {
ISearchComparison::COMPARE_GREATER_THAN => 'lte',
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt',
ISearchComparison::COMPARE_LESS_THAN => 'gte',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt'
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt',
];
public const TAG_FAVORITE = '_$!<Favorite>!$_';
@ -124,7 +125,7 @@ class QuerySearchHelper {
} else {
throw new \InvalidArgumentException('Binary operators inside "not" is not supported');
}
// no break
// no break
case ISearchBinaryOperator::OPERATOR_AND:
return call_user_func_array([$expr, 'andX'], $this->searchOperatorArrayToDBExprArray($builder, $operator->getArguments()));
case ISearchBinaryOperator::OPERATOR_OR:
@ -195,7 +196,8 @@ class QuerySearchHelper {
'size' => 'integer',
'tagname' => 'string',
'favorite' => 'boolean',
'fileid' => 'integer'
'fileid' => 'integer',
'storage' => 'integer',
];
$comparisons = [
'mimetype' => ['eq', 'like'],
@ -205,7 +207,8 @@ class QuerySearchHelper {
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'],
'tagname' => ['eq', 'like'],
'favorite' => ['eq'],
'fileid' => ['eq']
'fileid' => ['eq'],
'storage' => ['eq'],
];
if (!isset($types[$operator->getField()])) {
@ -274,12 +277,6 @@ class QuerySearchHelper {
$query = $builder->selectFileCache('file');
$storageFilters = array_map(function (ICache $cache) use ($builder) {
return $cache->getQueryFilterForStorage($builder);
}, $caches);
$query->andWhere($query->expr()->orX(...$storageFilters));
if ($this->shouldJoinTags($searchQuery->getSearchOperation())) {
$user = $searchQuery->getUser();
if ($user === null) {
@ -300,6 +297,11 @@ class QuerySearchHelper {
$query->andWhere($searchExpr);
}
$storageFilters = array_map(function (ICache $cache) {
return $cache->getQueryFilterForStorage();
}, $caches);
$query->andWhere($this->searchOperatorToDBExpr($builder, new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $storageFilters)));
if ($searchQuery->limitToHome() && ($this instanceof HomeCache)) {
$query->andWhere($builder->expr()->like('path', $query->expr()->literal('files/%')));
}

26
lib/private/Files/Cache/Wrapper/CacheJail.php

@ -28,8 +28,12 @@
namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
/**
* Jail to a subdirectory of the wrapped cache
@ -301,15 +305,17 @@ class CacheJail extends CacheWrapper {
return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
$escapedRoot = $builder->getConnection()->escapeLikeParameter($this->getGetUnjailedRoot());
return $builder->expr()->andX(
$this->getCache()->getQueryFilterForStorage($builder),
$builder->expr()->orX(
$builder->expr()->eq('path_hash', $builder->createNamedParameter(md5($this->getGetUnjailedRoot()))),
$builder->expr()->like('path', $builder->createNamedParameter($escapedRoot . '/%')),
)
public function getQueryFilterForStorage(): ISearchOperator {
return new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND,
[
$this->getCache()->getQueryFilterForStorage(),
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR,
[
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $this->getGetUnjailedRoot() . '/%'),
],
)
]
);
}

6
lib/private/Files/Cache/Wrapper/CacheWrapper.php

@ -31,9 +31,9 @@ namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
use OC\Files\Cache\QuerySearchHelper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
class CacheWrapper extends Cache {
@ -309,8 +309,8 @@ class CacheWrapper extends Cache {
return parent::getById($id);
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
return $this->getCache()->getQueryFilterForStorage($builder);
public function getQueryFilterForStorage(): ISearchOperator {
return $this->getCache()->getQueryFilterForStorage();
}
public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

8
lib/private/Lockdown/Filesystem/NullCache.php

@ -23,11 +23,13 @@
namespace OC\Lockdown\Filesystem;
use OC\Files\Cache\CacheEntry;
use OC\Files\Search\SearchComparison;
use OCP\Constants;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
class NullCache implements ICache {
@ -128,8 +130,8 @@ class NullCache implements ICache {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function getQueryFilterForStorage(IQueryBuilder $builder) {
return 'false';
public function getQueryFilterForStorage(): ISearchOperator {
return new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', -1);
}
public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

10
lib/public/Files/Cache/ICache.php

@ -22,8 +22,7 @@
*/
namespace OCP\Files\Cache;
use OCP\DB\QueryBuilder\ICompositeExpression;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
/**
@ -270,14 +269,13 @@ interface ICache {
/**
* Get the query expression required to filter files within this storage.
*
* In the most basic case this is just `$builder->expr()->eq('storage', $this->getNumericStorageId())`
* In the most basic case this is just comparing the storage id
* but storage wrappers can add additional expressions to filter down things further
*
* @param IQueryBuilder $builder
* @return string|ICompositeExpression
* @return ISearchOperator
* @since 22.0.0
*/
public function getQueryFilterForStorage(IQueryBuilder $builder);
public function getQueryFilterForStorage(): ISearchOperator;
/**
* Construct a cache entry from a search result row *if* the entry belongs to this storage.

Loading…
Cancel
Save