2017-02-02 20:19:16 +03:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
|
|
|
|
*
|
|
|
|
* @license GNU AGPL version 3 or any later version
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Test\Files\Cache;
|
|
|
|
|
2017-02-02 20:20:08 +03:00
|
|
|
use OC\DB\QueryBuilder\Literal;
|
|
|
|
use OC\Files\Cache\QuerySearchHelper;
|
|
|
|
use OC\Files\Search\SearchBinaryOperator;
|
|
|
|
use OC\Files\Search\SearchComparison;
|
|
|
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
|
|
|
use OCP\Files\IMimeTypeLoader;
|
|
|
|
use OCP\Files\Search\ISearchBinaryOperator;
|
|
|
|
use OCP\Files\Search\ISearchComparison;
|
|
|
|
use OCP\Files\Search\ISearchOperator;
|
2017-02-02 20:19:16 +03:00
|
|
|
use Test\TestCase;
|
|
|
|
|
2017-02-02 20:20:08 +03:00
|
|
|
/**
|
|
|
|
* @group DB
|
|
|
|
*/
|
2017-02-02 20:19:16 +03:00
|
|
|
class QuerySearchHelperTest extends TestCase {
|
2017-02-02 20:20:08 +03:00
|
|
|
/** @var IQueryBuilder */
|
|
|
|
private $builder;
|
|
|
|
|
2020-08-11 22:32:18 +03:00
|
|
|
/** @var IMimeTypeLoader|\PHPUnit\Framework\MockObject\MockObject */
|
2017-02-02 20:20:08 +03:00
|
|
|
private $mimetypeLoader;
|
|
|
|
|
|
|
|
/** @var QuerySearchHelper */
|
|
|
|
private $querySearchHelper;
|
|
|
|
|
|
|
|
/** @var integer */
|
|
|
|
private $numericStorageId;
|
|
|
|
|
2019-11-27 17:27:18 +03:00
|
|
|
protected function setUp(): void {
|
2017-02-02 20:20:08 +03:00
|
|
|
parent::setUp();
|
|
|
|
$this->builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
|
|
|
|
$this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class);
|
|
|
|
|
|
|
|
$this->mimetypeLoader->expects($this->any())
|
|
|
|
->method('getId')
|
|
|
|
->willReturnMap([
|
|
|
|
['text', 1],
|
|
|
|
['text/plain', 2],
|
|
|
|
['text/xml', 3],
|
|
|
|
['image/jpg', 4],
|
|
|
|
['image/png', 5],
|
|
|
|
['image', 6],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->mimetypeLoader->expects($this->any())
|
|
|
|
->method('getMimetypeById')
|
|
|
|
->willReturnMap([
|
|
|
|
[1, 'text'],
|
|
|
|
[2, 'text/plain'],
|
|
|
|
[3, 'text/xml'],
|
|
|
|
[4, 'image/jpg'],
|
|
|
|
[5, 'image/png'],
|
|
|
|
[6, 'image']
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
|
|
|
|
$this->numericStorageId = 10000;
|
|
|
|
|
|
|
|
$this->builder->select(['fileid'])
|
|
|
|
->from('filecache')
|
|
|
|
->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId)));
|
|
|
|
}
|
|
|
|
|
2019-11-27 17:27:18 +03:00
|
|
|
protected function tearDown(): void {
|
2017-02-02 20:20:08 +03:00
|
|
|
parent::tearDown();
|
|
|
|
|
|
|
|
$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
|
|
|
|
|
|
|
|
$builder->delete('filecache')
|
|
|
|
->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->numericStorageId, IQueryBuilder::PARAM_INT)));
|
|
|
|
|
|
|
|
$builder->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function addCacheEntry(array $data) {
|
|
|
|
$data['storage'] = $this->numericStorageId;
|
|
|
|
$data['etag'] = 'unimportant';
|
|
|
|
$data['storage_mtime'] = $data['mtime'];
|
|
|
|
if (!isset($data['path'])) {
|
|
|
|
$data['path'] = 'random/' . $this->getUniqueID();
|
|
|
|
}
|
|
|
|
$data['path_hash'] = md5($data['path']);
|
|
|
|
if (!isset($data['mtime'])) {
|
|
|
|
$data['mtime'] = 100;
|
|
|
|
}
|
|
|
|
if (!isset($data['size'])) {
|
|
|
|
$data['size'] = 100;
|
|
|
|
}
|
|
|
|
$data['name'] = basename($data['path']);
|
|
|
|
$data['parent'] = -1;
|
|
|
|
if (isset($data['mimetype'])) {
|
2021-01-12 12:15:48 +03:00
|
|
|
[$mimepart,] = explode('/', $data['mimetype']);
|
2017-02-02 20:20:08 +03:00
|
|
|
$data['mimepart'] = $this->mimetypeLoader->getId($mimepart);
|
|
|
|
$data['mimetype'] = $this->mimetypeLoader->getId($data['mimetype']);
|
|
|
|
} else {
|
|
|
|
$data['mimepart'] = 1;
|
|
|
|
$data['mimetype'] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
|
|
|
|
|
|
|
|
$values = [];
|
|
|
|
foreach ($data as $key => $value) {
|
|
|
|
$values[$key] = $builder->createNamedParameter($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
$builder->insert('filecache')
|
|
|
|
->values($values)
|
|
|
|
->execute();
|
2017-07-22 13:21:00 +03:00
|
|
|
|
|
|
|
return $builder->getLastInsertId();
|
2017-02-02 20:20:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private function search(ISearchOperator $operator) {
|
|
|
|
$dbOperator = $this->querySearchHelper->searchOperatorToDBExpr($this->builder, $operator);
|
|
|
|
$this->builder->andWhere($dbOperator);
|
2020-11-05 12:50:53 +03:00
|
|
|
|
|
|
|
$result = $this->builder->execute();
|
|
|
|
$rows = $result->fetchAll(\PDO::FETCH_COLUMN);
|
|
|
|
$result->closeCursor();
|
|
|
|
|
|
|
|
return $rows;
|
2017-02-02 20:20:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function comparisonProvider() {
|
|
|
|
return [
|
2017-07-22 13:21:00 +03:00
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125), [1]],
|
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [0]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 125), []],
|
2017-07-22 13:21:00 +03:00
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50), [0, 1]],
|
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), [0]],
|
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%'), [0, 1]],
|
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpg'), [0]],
|
|
|
|
[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'image/%'), [0, 1]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
|
2018-01-16 15:22:28 +03:00
|
|
|
new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125)
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [0]],
|
2018-01-16 15:22:28 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'text/%')
|
|
|
|
]), []],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 100),
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [0, 1]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [0]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125),
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [0]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [1]],
|
2017-02-02 20:20:08 +03:00
|
|
|
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
|
|
|
|
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%bar'),
|
2017-07-22 13:21:00 +03:00
|
|
|
]), [1]],
|
2017-02-02 20:20:08 +03:00
|
|
|
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider comparisonProvider
|
|
|
|
*
|
|
|
|
* @param ISearchOperator $operator
|
|
|
|
* @param array $fileIds
|
|
|
|
*/
|
|
|
|
public function testComparison(ISearchOperator $operator, array $fileIds) {
|
2017-07-22 13:21:00 +03:00
|
|
|
$fileId = [];
|
|
|
|
$fileId[] = $this->addCacheEntry([
|
2017-02-02 20:20:08 +03:00
|
|
|
'path' => 'foobar',
|
|
|
|
'mtime' => 100,
|
|
|
|
'size' => 50,
|
|
|
|
'mimetype' => 'image/jpg'
|
|
|
|
]);
|
|
|
|
|
2017-07-22 13:21:00 +03:00
|
|
|
$fileId[] = $this->addCacheEntry([
|
2017-02-02 20:20:08 +03:00
|
|
|
'path' => 'fooasd',
|
|
|
|
'mtime' => 150,
|
|
|
|
'size' => 50,
|
|
|
|
'mimetype' => 'image/png'
|
|
|
|
]);
|
|
|
|
|
2020-04-09 14:53:40 +03:00
|
|
|
$fileIds = array_map(function ($i) use ($fileId) {
|
2017-07-22 13:21:00 +03:00
|
|
|
return $fileId[$i];
|
|
|
|
}, $fileIds);
|
|
|
|
|
2017-02-02 20:20:08 +03:00
|
|
|
$results = $this->search($operator);
|
2017-02-02 20:19:16 +03:00
|
|
|
|
2017-02-21 20:18:41 +03:00
|
|
|
sort($fileIds);
|
|
|
|
sort($results);
|
|
|
|
|
2017-02-02 20:20:08 +03:00
|
|
|
$this->assertEquals($fileIds, $results);
|
|
|
|
}
|
2017-02-02 20:19:16 +03:00
|
|
|
}
|