aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/Files/Cache/Cache.php2
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php2
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php60
-rw-r--r--tests/lib/Files/Cache/Wrapper/CacheJailTest.php37
4 files changed, 97 insertions, 4 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 2513abd525f..840523c1890 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -121,7 +121,7 @@ class Cache implements ICache {
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
}
- private function getQueryBuilder() {
+ protected function getQueryBuilder() {
return new CacheQueryBuilder(
$this->connection,
\OC::$server->getSystemConfig(),
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index 574b4c18d5d..5e33ad235a0 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -175,6 +175,7 @@ class QuerySearchHelper {
'mimetype' => 'string',
'mtime' => 'integer',
'name' => 'string',
+ 'path' => 'string',
'size' => 'integer',
'tagname' => 'string',
'favorite' => 'boolean',
@@ -184,6 +185,7 @@ class QuerySearchHelper {
'mimetype' => ['eq', 'like'],
'mtime' => ['eq', 'gt', 'lt', 'gte', 'lte'],
'name' => ['eq', 'like'],
+ 'path' => ['eq', 'like'],
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'],
'tagname' => ['eq', 'like'],
'favorite' => ['eq'],
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 6c1c17be028..27590fb7418 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -29,8 +29,13 @@
namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchQuery;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchQuery;
/**
@@ -49,6 +54,8 @@ class CacheJail extends CacheWrapper {
public function __construct($cache, $root) {
parent::__construct($cache);
$this->root = $root;
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
}
protected function getRoot() {
@@ -221,7 +228,26 @@ class CacheJail extends CacheWrapper {
* @return array an array of file data
*/
public function search($pattern) {
- $results = $this->getCache()->search($pattern);
+ // normalize pattern
+ $pattern = $this->normalize($pattern);
+
+ if ($pattern === '%%') {
+ return [];
+ }
+
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId()
+ ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%')))
+ ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern)));
+
+ $result = $query->execute();
+ $files = $result->fetchAll();
+ $result->closeCursor();
+
+ $results = array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $files);
return $this->formatSearchResults($results);
}
@@ -232,12 +258,40 @@ class CacheJail extends CacheWrapper {
* @return array
*/
public function searchByMime($mimetype) {
- $results = $this->getCache()->searchByMime($mimetype);
+ $mimeId = $this->mimetypeLoader->getId($mimetype);
+
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId()
+ ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%')));
+
+ if (strpos($mimetype, '/')) {
+ $query->andWhere($query->expr()->eq('mimetype', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
+ } else {
+ $query->andWhere($query->expr()->eq('mimepart', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
+ }
+
+ $result = $query->execute();
+ $files = $result->fetchAll();
+ $result->closeCursor();
+
+ $results = array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $files);
return $this->formatSearchResults($results);
}
public function searchQuery(ISearchQuery $query) {
- $simpleQuery = new SearchQuery($query->getSearchOperation(), 0, 0, $query->getOrder(), $query->getUser());
+ $prefixFilter = new SearchComparison(
+ ISearchComparison::COMPARE_LIKE,
+ 'path',
+ $this->getRoot() . '/%'
+ );
+ $operation = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_AND,
+ [$prefixFilter, $query->getSearchOperation()]
+ );
+ $simpleQuery = new SearchQuery($operation, 0, 0, $query->getOrder(), $query->getUser());
$results = $this->getCache()->searchQuery($simpleQuery);
$results = $this->formatSearchResults($results);
diff --git a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php
index f0943ba5a03..83173efd3b6 100644
--- a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php
+++ b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php
@@ -9,6 +9,11 @@
namespace Test\Files\Cache\Wrapper;
use OC\Files\Cache\Wrapper\CacheJail;
+use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchQuery;
+use OC\User\User;
+use OCP\Files\Search\ISearchComparison;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\Files\Cache\CacheTest;
/**
@@ -46,6 +51,38 @@ class CacheJailTest extends CacheTest {
$this->assertEquals('foobar', $result[0]['path']);
}
+ public function testSearchMimeOutsideJail() {
+ $file1 = 'foo/foobar';
+ $file2 = 'folder/foobar';
+ $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
+
+ $this->sourceCache->put($file1, $data1);
+ $this->sourceCache->put($file2, $data1);
+
+ $this->assertCount(2, $this->sourceCache->searchByMime('foo/folder'));
+
+ $result = $this->cache->search('%foobar%');
+ $this->assertCount(1, $result);
+ $this->assertEquals('foobar', $result[0]['path']);
+ }
+
+ public function testSearchQueryOutsideJail() {
+ $file1 = 'foo/foobar';
+ $file2 = 'folder/foobar';
+ $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
+
+ $this->sourceCache->put($file1, $data1);
+ $this->sourceCache->put($file2, $data1);
+
+ $user = new User('foo', null, $this->createMock(EventDispatcherInterface::class));
+ $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user);
+ $this->assertCount(2, $this->sourceCache->searchQuery($query));
+
+ $result = $this->cache->search('%foobar%');
+ $this->assertCount(1, $result);
+ $this->assertEquals('foobar', $result[0]['path']);
+ }
+
public function testClearKeepEntriesOutsideJail() {
$file1 = 'foo/foobar';
$file2 = 'foo/foobar/asd';