From 8551ee079dfcc49c85ecea3a042077dc85790c67 Mon Sep 17 00:00:00 2001
From: Robin Appelman <robin@icewind.nl>
Date: Fri, 19 Mar 2021 13:41:00 +0100
Subject: [PATCH] folder filtering in sql

Signed-off-by: Robin Appelman <robin@icewind.nl>
---
 lib/private/Files/Node/Folder.php   | 36 ++++++++++++++++-------------
 tests/lib/Files/Node/FolderTest.php |  1 -
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 39445437a36..4b63a26c272 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -33,6 +33,7 @@ namespace OC\Files\Node;
 
 use OC\DB\QueryBuilder\Literal;
 use OC\Files\Mount\MountPoint;
+use OC\Files\Search\SearchBinaryOperator;
 use OC\Files\Search\SearchComparison;
 use OC\Files\Search\SearchQuery;
 use OC\Files\Storage\Wrapper\Jail;
@@ -45,6 +46,7 @@ use OCP\Files\FileInfo;
 use OCP\Files\Mount\IMountPoint;
 use OCP\Files\NotFoundException;
 use OCP\Files\NotPermittedException;
+use OCP\Files\Search\ISearchBinaryOperator;
 use OCP\Files\Search\ISearchComparison;
 use OCP\Files\Search\ISearchOperator;
 use OCP\Files\Search\ISearchQuery;
@@ -253,10 +255,23 @@ class Folder extends Node implements \OCP\Files\Folder {
 			throw new \InvalidArgumentException('searching by owner is only allows on the users home folder');
 		}
 
+		$rootLength = strlen($this->path);
+		$mount = $this->root->getMount($this->path);
+		$storage = $mount->getStorage();
+		$internalPath = $mount->getInternalPath($this->path);
+		$internalPath = rtrim($internalPath, '/');
+		if ($internalPath !== '') {
+			$internalPath = $internalPath . '/';
+		}
+
 		$subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX;
 		$subQueryOffset = $query->getOffset();
-		$noLimitQuery = new SearchQuery(
-			$query->getSearchOperation(),
+		$rootQuery = new SearchQuery(
+			new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+					new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'),
+					$query->getSearchOperation(),
+				]
+			),
 			$subQueryLimit,
 			0,
 			$query->getOrder(),
@@ -264,28 +279,17 @@ class Folder extends Node implements \OCP\Files\Folder {
 		);
 
 		$files = [];
-		$rootLength = strlen($this->path);
-		$mount = $this->root->getMount($this->path);
-		$storage = $mount->getStorage();
-		$internalPath = $mount->getInternalPath($this->path);
-		$internalPath = rtrim($internalPath, '/');
-		if ($internalPath !== '') {
-			$internalPath = $internalPath . '/';
-		}
-		$internalRootLength = strlen($internalPath);
 
 		$cache = $storage->getCache('');
 
-		$results = $cache->searchQuery($noLimitQuery);
+		$results = $cache->searchQuery($rootQuery);
 		$count = count($results);
 		$results = array_slice($results, $subQueryOffset, $subQueryLimit);
 		$subQueryOffset = max(0, $subQueryOffset - $count);
 		$subQueryLimit = max(0, $subQueryLimit - $count);
 
 		foreach ($results as $result) {
-			if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
-				$files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result);
-			}
+			$files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result);
 		}
 
 		if (!$limitToHome) {
@@ -330,7 +334,7 @@ class Folder extends Node implements \OCP\Files\Folder {
 	private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, string $trimRoot, ICacheEntry $cacheEntry): FileInfo {
 		$trimLength = strlen($trimRoot);
 		$cacheEntry['internalPath'] = $cacheEntry['path'];
-		$cacheEntry['path'] = $appendRoot .  substr($cacheEntry['path'], $trimLength);
+		$cacheEntry['path'] = $appendRoot . substr($cacheEntry['path'], $trimLength);
 		return new \OC\Files\FileInfo($this->path . '/' . $cacheEntry['path'], $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
 	}
 
diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php
index 339a77edcc3..39dcffe5ae3 100644
--- a/tests/lib/Files/Node/FolderTest.php
+++ b/tests/lib/Files/Node/FolderTest.php
@@ -354,7 +354,6 @@ class FolderTest extends NodeTest {
 		$cache->method('searchQuery')
 			->willReturn([
 				new CacheEntry(['fileid' => 3, 'path' => 'files/foo', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']),
-				new CacheEntry(['fileid' => 3, 'path' => 'files_trashbin/foo2.d12345', 'name' => 'foo2.d12345', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']),
 			]);
 
 		$root->method('getMountsIn')
-- 
GitLab