folder filtering in sql

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2021-03-19 13:41:00 +01:00
parent d257108409
commit 245d3b2162
No known key found for this signature in database
GPG Key ID: 42B69D8A64526EFB
2 changed files with 21 additions and 18 deletions

View File

@ -32,6 +32,7 @@ namespace OC\Files\Node;
use OC\DB\QueryBuilder\Literal; use OC\DB\QueryBuilder\Literal;
use OC\Files\Mount\MountPoint; use OC\Files\Mount\MountPoint;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchQuery; use OC\Files\Search\SearchQuery;
use OC\Files\Storage\Wrapper\Jail; use OC\Files\Storage\Wrapper\Jail;
@ -44,6 +45,7 @@ use OCP\Files\FileInfo;
use OCP\Files\Mount\IMountPoint; use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException; use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException; use OCP\Files\NotPermittedException;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator; use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery; use OCP\Files\Search\ISearchQuery;
@ -252,17 +254,6 @@ class Folder extends Node implements \OCP\Files\Folder {
throw new \InvalidArgumentException('searching by owner is only allows on the users home folder'); throw new \InvalidArgumentException('searching by owner is only allows on the users home folder');
} }
$subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX;
$subQueryOffset = $query->getOffset();
$noLimitQuery = new SearchQuery(
$query->getSearchOperation(),
$subQueryLimit,
0,
$query->getOrder(),
$query->getUser()
);
$files = [];
$rootLength = strlen($this->path); $rootLength = strlen($this->path);
$mount = $this->root->getMount($this->path); $mount = $this->root->getMount($this->path);
$storage = $mount->getStorage(); $storage = $mount->getStorage();
@ -271,20 +262,33 @@ class Folder extends Node implements \OCP\Files\Folder {
if ($internalPath !== '') { if ($internalPath !== '') {
$internalPath = $internalPath . '/'; $internalPath = $internalPath . '/';
} }
$internalRootLength = strlen($internalPath);
$subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX;
$subQueryOffset = $query->getOffset();
$rootQuery = new SearchQuery(
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'),
$query->getSearchOperation(),
]
),
$subQueryLimit,
0,
$query->getOrder(),
$query->getUser()
);
$files = [];
$cache = $storage->getCache(''); $cache = $storage->getCache('');
$results = $cache->searchQuery($noLimitQuery); $results = $cache->searchQuery($rootQuery);
$count = count($results); $count = count($results);
$results = array_slice($results, $subQueryOffset, $subQueryLimit); $results = array_slice($results, $subQueryOffset, $subQueryLimit);
$subQueryOffset = max(0, $subQueryOffset - $count); $subQueryOffset = max(0, $subQueryOffset - $count);
$subQueryLimit = max(0, $subQueryLimit - $count); $subQueryLimit = max(0, $subQueryLimit - $count);
foreach ($results as $result) { 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) { if (!$limitToHome) {
@ -329,7 +333,7 @@ class Folder extends Node implements \OCP\Files\Folder {
private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, string $trimRoot, ICacheEntry $cacheEntry): FileInfo { private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, string $trimRoot, ICacheEntry $cacheEntry): FileInfo {
$trimLength = strlen($trimRoot); $trimLength = strlen($trimRoot);
$cacheEntry['internalPath'] = $cacheEntry['path']; $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); return new \OC\Files\FileInfo($this->path . '/' . $cacheEntry['path'], $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
} }

View File

@ -354,7 +354,6 @@ class FolderTest extends NodeTest {
$cache->method('searchQuery') $cache->method('searchQuery')
->willReturn([ ->willReturn([
new CacheEntry(['fileid' => 3, 'path' => 'files/foo', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']), 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') $root->method('getMountsIn')