do cachejail search filtering in sql
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
f9c9e27e46
commit
564390e303
|
@ -113,7 +113,7 @@ class Cache implements ICache {
|
||||||
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
|
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getQueryBuilder() {
|
protected function getQueryBuilder() {
|
||||||
return new CacheQueryBuilder(
|
return new CacheQueryBuilder(
|
||||||
$this->connection,
|
$this->connection,
|
||||||
\OC::$server->getSystemConfig(),
|
\OC::$server->getSystemConfig(),
|
||||||
|
|
|
@ -175,6 +175,7 @@ class QuerySearchHelper {
|
||||||
'mimetype' => 'string',
|
'mimetype' => 'string',
|
||||||
'mtime' => 'integer',
|
'mtime' => 'integer',
|
||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
|
'path' => 'string',
|
||||||
'size' => 'integer',
|
'size' => 'integer',
|
||||||
'tagname' => 'string',
|
'tagname' => 'string',
|
||||||
'favorite' => 'boolean',
|
'favorite' => 'boolean',
|
||||||
|
@ -184,6 +185,7 @@ class QuerySearchHelper {
|
||||||
'mimetype' => ['eq', 'like'],
|
'mimetype' => ['eq', 'like'],
|
||||||
'mtime' => ['eq', 'gt', 'lt', 'gte', 'lte'],
|
'mtime' => ['eq', 'gt', 'lt', 'gte', 'lte'],
|
||||||
'name' => ['eq', 'like'],
|
'name' => ['eq', 'like'],
|
||||||
|
'path' => ['eq', 'like'],
|
||||||
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'],
|
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'],
|
||||||
'tagname' => ['eq', 'like'],
|
'tagname' => ['eq', 'like'],
|
||||||
'favorite' => ['eq'],
|
'favorite' => ['eq'],
|
||||||
|
|
|
@ -30,8 +30,13 @@
|
||||||
namespace OC\Files\Cache\Wrapper;
|
namespace OC\Files\Cache\Wrapper;
|
||||||
|
|
||||||
use OC\Files\Cache\Cache;
|
use OC\Files\Cache\Cache;
|
||||||
|
use OC\Files\Search\SearchBinaryOperator;
|
||||||
|
use OC\Files\Search\SearchComparison;
|
||||||
use OC\Files\Search\SearchQuery;
|
use OC\Files\Search\SearchQuery;
|
||||||
|
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\ISearchQuery;
|
use OCP\Files\Search\ISearchQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +55,8 @@ class CacheJail extends CacheWrapper {
|
||||||
public function __construct($cache, $root) {
|
public function __construct($cache, $root) {
|
||||||
parent::__construct($cache);
|
parent::__construct($cache);
|
||||||
$this->root = $root;
|
$this->root = $root;
|
||||||
|
$this->connection = \OC::$server->getDatabaseConnection();
|
||||||
|
$this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRoot() {
|
protected function getRoot() {
|
||||||
|
@ -222,7 +229,26 @@ class CacheJail extends CacheWrapper {
|
||||||
* @return array an array of file data
|
* @return array an array of file data
|
||||||
*/
|
*/
|
||||||
public function search($pattern) {
|
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);
|
return $this->formatSearchResults($results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,12 +259,40 @@ class CacheJail extends CacheWrapper {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function searchByMime($mimetype) {
|
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);
|
return $this->formatSearchResults($results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchQuery(ISearchQuery $query) {
|
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->getCache()->searchQuery($simpleQuery);
|
||||||
$results = $this->formatSearchResults($results);
|
$results = $this->formatSearchResults($results);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
namespace Test\Files\Cache\Wrapper;
|
namespace Test\Files\Cache\Wrapper;
|
||||||
|
|
||||||
use OC\Files\Cache\Wrapper\CacheJail;
|
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;
|
use Test\Files\Cache\CacheTest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +51,38 @@ class CacheJailTest extends CacheTest {
|
||||||
$this->assertEquals('foobar', $result[0]['path']);
|
$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() {
|
public function testClearKeepEntriesOutsideJail() {
|
||||||
$file1 = 'foo/foobar';
|
$file1 = 'foo/foobar';
|
||||||
$file2 = 'foo/foobar/asd';
|
$file2 = 'foo/foobar/asd';
|
||||||
|
|
Loading…
Reference in New Issue