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. 22
      lib/private/Files/Cache/QuerySearchHelper.php
  5. 24
      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\FailedCache;
use OC\Files\Cache\Wrapper\CacheJail; use OC\Files\Cache\Wrapper\CacheJail;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Storage\Wrapper\Jail; use OC\Files\Storage\Wrapper\Jail;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICacheEntry; use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\StorageNotAvailableException; use OCP\Files\StorageNotAvailableException;
/** /**
@ -182,18 +186,19 @@ class Cache extends CacheJail {
// Not a valid action for Shared Cache // Not a valid action for Shared Cache
} }
public function getQueryFilterForStorage(IQueryBuilder $builder) {
public function getQueryFilterForStorage(): ISearchOperator {
// Do the normal jail behavior for non files // Do the normal jail behavior for non files
if ($this->storage->getItemType() !== 'file') { if ($this->storage->getItemType() !== 'file') {
return parent::getQueryFilterForStorage($builder);
return parent::getQueryFilterForStorage();
} }
// for single file shares we don't need to do the LIKE // 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\FileInfo;
use OCP\Files\IMimeTypeLoader; use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
use OCP\Files\Storage\IStorage; use OCP\Files\Storage\IStorage;
use OCP\IDBConnection; 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 { public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

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

@ -21,10 +21,12 @@
*/ */
namespace OC\Files\Cache; namespace OC\Files\Cache;
use OC\Files\Search\SearchComparison;
use OCP\Constants; use OCP\Constants;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry; use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
/** /**
@ -140,8 +142,8 @@ class FailedCache implements ICache {
throw new \Exception("Invalid cache"); 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 { public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

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

@ -25,6 +25,7 @@
*/ */
namespace OC\Files\Cache; namespace OC\Files\Cache;
use OC\Files\Search\SearchBinaryOperator;
use OC\SystemConfig; use OC\SystemConfig;
use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICache;
@ -47,7 +48,7 @@ class QuerySearchHelper {
ISearchComparison::COMPARE_GREATER_THAN => 'gt', ISearchComparison::COMPARE_GREATER_THAN => 'gt',
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte', ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte',
ISearchComparison::COMPARE_LESS_THAN => 'lt', ISearchComparison::COMPARE_LESS_THAN => 'lt',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte'
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte',
]; ];
protected static $searchOperatorNegativeMap = [ protected static $searchOperatorNegativeMap = [
@ -56,7 +57,7 @@ class QuerySearchHelper {
ISearchComparison::COMPARE_GREATER_THAN => 'lte', ISearchComparison::COMPARE_GREATER_THAN => 'lte',
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt', ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt',
ISearchComparison::COMPARE_LESS_THAN => 'gte', ISearchComparison::COMPARE_LESS_THAN => 'gte',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt'
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt',
]; ];
public const TAG_FAVORITE = '_$!<Favorite>!$_'; public const TAG_FAVORITE = '_$!<Favorite>!$_';
@ -195,7 +196,8 @@ class QuerySearchHelper {
'size' => 'integer', 'size' => 'integer',
'tagname' => 'string', 'tagname' => 'string',
'favorite' => 'boolean', 'favorite' => 'boolean',
'fileid' => 'integer'
'fileid' => 'integer',
'storage' => 'integer',
]; ];
$comparisons = [ $comparisons = [
'mimetype' => ['eq', 'like'], 'mimetype' => ['eq', 'like'],
@ -205,7 +207,8 @@ class QuerySearchHelper {
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'], 'size' => ['eq', 'gt', 'lt', 'gte', 'lte'],
'tagname' => ['eq', 'like'], 'tagname' => ['eq', 'like'],
'favorite' => ['eq'], 'favorite' => ['eq'],
'fileid' => ['eq']
'fileid' => ['eq'],
'storage' => ['eq'],
]; ];
if (!isset($types[$operator->getField()])) { if (!isset($types[$operator->getField()])) {
@ -274,12 +277,6 @@ class QuerySearchHelper {
$query = $builder->selectFileCache('file'); $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())) { if ($this->shouldJoinTags($searchQuery->getSearchOperation())) {
$user = $searchQuery->getUser(); $user = $searchQuery->getUser();
if ($user === null) { if ($user === null) {
@ -300,6 +297,11 @@ class QuerySearchHelper {
$query->andWhere($searchExpr); $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)) { if ($searchQuery->limitToHome() && ($this instanceof HomeCache)) {
$query->andWhere($builder->expr()->like('path', $query->expr()->literal('files/%'))); $query->andWhere($builder->expr()->like('path', $query->expr()->literal('files/%')));
} }

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

@ -28,8 +28,12 @@
namespace OC\Files\Cache\Wrapper; namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache; 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\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 * 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)); 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\Cache;
use OC\Files\Cache\QuerySearchHelper; use OC\Files\Cache\QuerySearchHelper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry; use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
class CacheWrapper extends Cache { class CacheWrapper extends Cache {
@ -309,8 +309,8 @@ class CacheWrapper extends Cache {
return parent::getById($id); 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 { public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

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

@ -23,11 +23,13 @@
namespace OC\Lockdown\Filesystem; namespace OC\Lockdown\Filesystem;
use OC\Files\Cache\CacheEntry; use OC\Files\Cache\CacheEntry;
use OC\Files\Search\SearchComparison;
use OCP\Constants; use OCP\Constants;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry; use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo; use OCP\Files\FileInfo;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
class NullCache implements ICache { 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'); 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 { public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {

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

@ -22,8 +22,7 @@
*/ */
namespace OCP\Files\Cache; namespace OCP\Files\Cache;
use OCP\DB\QueryBuilder\ICompositeExpression;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
/** /**
@ -270,14 +269,13 @@ interface ICache {
/** /**
* Get the query expression required to filter files within this storage. * 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 * but storage wrappers can add additional expressions to filter down things further
* *
* @param IQueryBuilder $builder
* @return string|ICompositeExpression
* @return ISearchOperator
* @since 22.0.0 * @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. * Construct a cache entry from a search result row *if* the entry belongs to this storage.

Loading…
Cancel
Save