Browse Source

use searchoperation for storage filter instead of db expression

Signed-off-by: Robin Appelman <robin@icewind.nl>
Robin Appelman 3 years ago
parent
commit
9774fb1573

+ 13 - 8
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()),
+			]
 		);
 	}
 }

+ 3 - 2
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 {

+ 5 - 3
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 {

+ 13 - 11
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/%')));
 		}

+ 16 - 10
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() . '/%'),
+					],
+				)
+			]
 		);
 	}
 

+ 3 - 3
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 {

+ 5 - 3
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 {

+ 4 - 6
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.