No known key found for this signature in database
GPG Key ID: CBCA68FBAEBF98C9
13 changed files with 632 additions and 1 deletions
-
23rdparty
-
76apps/dav/lib/Files/FileSearchBackend.php
-
155lib/private/Files/Cache/QuerySearchHelper.php
-
20lib/private/Files/Search/SearchBinaryOperator.php
-
67lib/private/Files/Search/SearchComparison.php
-
57lib/private/Files/Search/SearchOrder.php
-
23lib/private/Files/Search/SearchQuery.php
-
46lib/public/Files/Search/ISearchBinaryOperator.php
-
54lib/public/Files/Search/ISearchComparison.php
-
26lib/public/Files/Search/ISearchOperator.php
-
46lib/public/Files/Search/ISearchOrder.php
-
33lib/public/Files/Search/ISearchQuery.php
-
28tests/lib/Files/Cache/QuerySearchHelperTest.php
@ -1 +1 @@ |
|||
Subproject commit 489bcf4f81e462f4d74f0b76f58caeabd58e75de |
|||
Subproject commit 2838fa6777b1427c6c912a5e599a96639ac2b31f |
|||
@ -0,0 +1,76 @@ |
|||
<?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 OCA\DAV\Files; |
|||
|
|||
use OCA\DAV\Connector\Sabre\Directory; |
|||
use Sabre\DAV\Exception\NotFound; |
|||
use Sabre\DAV\Tree; |
|||
use SearchDAV\Backend\ISearchBackend; |
|||
use SearchDAV\Backend\SearchPropertyDefinition; |
|||
|
|||
class FileSearchBackend implements ISearchBackend { |
|||
/** @var Tree */ |
|||
private $tree; |
|||
|
|||
/** |
|||
* FileSearchBackend constructor. |
|||
* |
|||
* @param Tree $tree |
|||
*/ |
|||
public function __construct(Tree $tree) { |
|||
$this->tree = $tree; |
|||
} |
|||
|
|||
/** |
|||
* Search endpoint will be remote.php/dav/files |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getArbiterPath() { |
|||
return 'files'; |
|||
} |
|||
|
|||
public function isValidScope($href, $depth, $path) { |
|||
// only allow scopes inside the dav server
|
|||
if (is_null($path)) { |
|||
return false; |
|||
} |
|||
|
|||
try { |
|||
$node = $this->tree->getNodeForPath($path); |
|||
return $node instanceof Directory; |
|||
} catch (NotFound $e) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function getPropertyDefinitionsForScope($href, $path) { |
|||
// all valid scopes support the same schema
|
|||
|
|||
return [ |
|||
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER), |
|||
new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), |
|||
new SearchPropertyDefinition('{DAV:}displayname', true, true, true), |
|||
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER), |
|||
]; |
|||
} |
|||
} |
|||
@ -0,0 +1,155 @@ |
|||
<?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 OC\Files\Cache; |
|||
|
|||
use OCP\DB\QueryBuilder\IQueryBuilder; |
|||
use OCP\Files\IMimeTypeLoader; |
|||
use OCP\Files\Search\ISearchBinaryOperator; |
|||
use OCP\Files\Search\ISearchComparison; |
|||
use OCP\Files\Search\ISearchOperator; |
|||
|
|||
/** |
|||
* Tools for transforming search queries into database queries |
|||
*/ |
|||
class QuerySearchUtil { |
|||
static protected $searchOperatorMap = [ |
|||
ISearchComparison::COMPARE_LIKE => 'iLike', |
|||
ISearchComparison::COMPARE_EQUAL => 'eq', |
|||
ISearchComparison::COMPARE_GREATER_THAN => 'gt', |
|||
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte', |
|||
ISearchComparison::COMPARE_LESS_THAN => 'lt', |
|||
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte' |
|||
]; |
|||
|
|||
static protected $searchOperatorNegativeMap = [ |
|||
ISearchComparison::COMPARE_LIKE => 'notLike', |
|||
ISearchComparison::COMPARE_EQUAL => 'neq', |
|||
ISearchComparison::COMPARE_GREATER_THAN => 'lte', |
|||
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt', |
|||
ISearchComparison::COMPARE_LESS_THAN => 'gte', |
|||
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt' |
|||
]; |
|||
|
|||
/** @var IMimeTypeLoader */ |
|||
private $mimetypeLoader; |
|||
|
|||
/** |
|||
* QuerySearchUtil constructor. |
|||
* |
|||
* @param IMimeTypeLoader $mimetypeLoader |
|||
*/ |
|||
public function __construct(IMimeTypeLoader $mimetypeLoader) { |
|||
$this->mimetypeLoader = $mimetypeLoader; |
|||
} |
|||
|
|||
public function searchOperatorToDBExpr(IQueryBuilder $builder, ISearchOperator $operator) { |
|||
$expr = $builder->expr(); |
|||
if ($operator instanceof ISearchBinaryOperator) { |
|||
switch ($operator->getType()) { |
|||
case ISearchBinaryOperator::OPERATOR_NOT: |
|||
$negativeOperator = $operator->getArguments()[0]; |
|||
if ($negativeOperator instanceof ISearchComparison) { |
|||
return $this->searchComparisonToDBExpr($builder, $negativeOperator, self::$searchOperatorNegativeMap); |
|||
} else { |
|||
throw new \InvalidArgumentException('Binary operators inside "not" is not supported'); |
|||
} |
|||
case ISearchBinaryOperator::OPERATOR_AND: |
|||
return $expr->andX($this->searchOperatorToDBExpr($operator->getArguments()[0], $operator->getArguments()[1])); |
|||
case ISearchBinaryOperator::OPERATOR_OR: |
|||
return $expr->orX($this->searchOperatorToDBExpr($operator->getArguments()[0], $operator->getArguments()[1])); |
|||
default: |
|||
throw new \InvalidArgumentException('Invalid operator type: ' . $operator->getType()); |
|||
} |
|||
} else if ($operator instanceof ISearchComparison) { |
|||
return $this->searchComparisonToDBExpr($builder, $operator, self::$searchOperatorMap); |
|||
} else { |
|||
throw new \InvalidArgumentException('Invalid operator type: ' . get_class($operator)); |
|||
} |
|||
} |
|||
|
|||
private function searchComparisonToDBExpr(IQueryBuilder $builder, ISearchComparison $comparison, array $operatorMap) { |
|||
if (!$this->isValidComparison($comparison)) { |
|||
throw new \InvalidArgumentException('Invalid comparison ' . $operator->getType() . ' on field ' . $operator->getField()); |
|||
} |
|||
|
|||
list($field, $value) = $this->getOperatorFieldAndValue($comparison); |
|||
if (isset($operatorMap[$comparison->getType()])) { |
|||
$queryOperator = $operatorMap[$comparison->getType()]; |
|||
return $builder->expr()->$queryOperator($field, $this->getParameterForValue($builder, $value)); |
|||
} else { |
|||
throw new \InvalidArgumentException('Invalid operator type: ' . $comparison->getType()); |
|||
} |
|||
} |
|||
|
|||
private function getOperatorFieldAndValue(ISearchComparison $operator) { |
|||
$field = $operator->getField(); |
|||
$value = $operator->getValue(); |
|||
if ($field === 'mimetype') { |
|||
if ($operator->getType() === ISearchComparison::COMPARE_EQUAL) { |
|||
$value = $this->mimetypeLoader->getId($value); |
|||
} else if ($operator->getType() === ISearchComparison::COMPARE_LIKE) { |
|||
// transform "mimetype='foo/%'" to "mimepart='foo'"
|
|||
if (preg_match('|(.+)/%|', $value, $matches)) { |
|||
$field = 'mimepart'; |
|||
$value = $this->mimetypeLoader->getId($matches[1]); |
|||
} |
|||
} |
|||
} |
|||
return [$field, $value]; |
|||
} |
|||
|
|||
private function isValidComparison(ISearchComparison $operator) { |
|||
$types = [ |
|||
'mimetype' => 'string', |
|||
'mtime' => \DateTime::class, |
|||
'name' => 'string', |
|||
'size' => 'integer' |
|||
]; |
|||
$comparisons = [ |
|||
'mimetype' => ['eq', 'like'], |
|||
'mtime' => ['eq', 'gt', 'lt', 'gte', 'lte'], |
|||
'name' => ['eq', 'like'], |
|||
'size' => ['eq', 'gt', 'lt', 'gte', 'lte'] |
|||
]; |
|||
|
|||
if (!isset($types[$operator->getField()])) { |
|||
return false; |
|||
} |
|||
$type = $types[$operator->getField()]; |
|||
if (gettype($operator->getValue()) !== $type && !(is_a($operator->getValue(), $type))) { |
|||
return false; |
|||
} |
|||
return in_array($operator->getType(), $comparisons[$operator->getField()]); |
|||
} |
|||
|
|||
private function getParameterForValue(IQueryBuilder $builder, $value) { |
|||
if ($value instanceof \DateTime) { |
|||
$value = $value->getTimestamp(); |
|||
} |
|||
if (is_numeric($value)) { |
|||
$type = IQueryBuilder::PARAM_INT; |
|||
} else { |
|||
$type = IQueryBuilder::PARAM_STR; |
|||
} |
|||
return $builder->createNamedParameter($value, $type); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<?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/>. |
|||
* |
|||
*/ |
|||
@ -0,0 +1,67 @@ |
|||
<?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 OC\Files\Search; |
|||
|
|||
use OCP\Files\Search\ISearchComparison; |
|||
|
|||
class SearchComparison implements ISearchComparison { |
|||
/** @var string */ |
|||
private $type; |
|||
/** @var string */ |
|||
private $field; |
|||
/** @var string|integer|\DateTime */ |
|||
private $value; |
|||
|
|||
/** |
|||
* SearchComparison constructor. |
|||
* |
|||
* @param string $type |
|||
* @param string $field |
|||
* @param \DateTime|int|string $value |
|||
*/ |
|||
public function __construct($type, $field, $value) { |
|||
$this->type = $type; |
|||
$this->field = $field; |
|||
$this->value = $value; |
|||
} |
|||
|
|||
/** |
|||
* @return string |
|||
*/ |
|||
public function getType() { |
|||
return $this->type; |
|||
} |
|||
|
|||
/** |
|||
* @return string |
|||
*/ |
|||
public function getField() { |
|||
return $this->field; |
|||
} |
|||
|
|||
/** |
|||
* @return \DateTime|int|string |
|||
*/ |
|||
public function getValue() { |
|||
return $this->value; |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
<?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 OC\Files\Search; |
|||
|
|||
|
|||
use OCP\Files\Search\ISearchOrder; |
|||
|
|||
class SearchOrder implements ISearchOrder { |
|||
/** @var string */ |
|||
private $direction; |
|||
/** @var string */ |
|||
private $field; |
|||
|
|||
/** |
|||
* SearchOrder constructor. |
|||
* |
|||
* @param string $direction |
|||
* @param string $field |
|||
*/ |
|||
public function __construct($direction, $field) { |
|||
$this->direction = $direction; |
|||
$this->field = $field; |
|||
} |
|||
|
|||
/** |
|||
* @return string |
|||
*/ |
|||
public function getDirection() { |
|||
return $this->direction; |
|||
} |
|||
|
|||
/** |
|||
* @return string |
|||
*/ |
|||
public function getField() { |
|||
return $this->field; |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
<?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 OC\Files\Search; |
|||
|
|||
@ -0,0 +1,46 @@ |
|||
<?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 OCP\Files\Search; |
|||
|
|||
interface ISearchBinaryOperator extends ISearchOperator { |
|||
const OPERATOR_AND = 'and'; |
|||
const OPERATOR_OR = 'or'; |
|||
const OPERATOR_NOT = 'not'; |
|||
|
|||
/** |
|||
* The type of binary operator |
|||
* |
|||
* One of the ISearchBinaryOperator::OPERATOR_* constants |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getType(); |
|||
|
|||
/** |
|||
* The arguments for the binary operator |
|||
* |
|||
* One argument for the 'not' operator and two for 'and' and 'or' |
|||
* |
|||
* @return ISearchOperator[] |
|||
*/ |
|||
public function getArguments(); |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
<?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 OCP\Files\Search; |
|||
|
|||
interface ISearchComparison extends ISearchOperator { |
|||
const COMPARE_EQUAL = 'eq'; |
|||
const COMPARE_GREATER_THAN = 'gt'; |
|||
const COMPARE_GREATER_THAN_EQUAL = 'gte'; |
|||
const COMPARE_LESS_THAN = 'lt'; |
|||
const COMPARE_LESS_THAN_EQUAL = 'lte'; |
|||
const COMPARE_LIKE = 'like'; |
|||
|
|||
/** |
|||
* Get the type of comparison, one of the ISearchComparison::COMPARE_* constants |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getType(); |
|||
|
|||
/** |
|||
* Get the name of the field to compare with |
|||
* |
|||
* i.e. 'size', 'name' or 'mimetype' |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getField(); |
|||
|
|||
/** |
|||
* Get the value to compare the field with |
|||
* |
|||
* @return string|integer|\DateTime |
|||
*/ |
|||
public function getValue(); |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
<?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 OCP\Files\Search; |
|||
|
|||
interface ISearchCondition { |
|||
|
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
<?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 OCP\Files\Search; |
|||
|
|||
/** |
|||
* @since 12.0.0 |
|||
*/ |
|||
interface ISearchOrder { |
|||
const DIRECTION_ASCENDING = 'asc'; |
|||
const DIRECTION_DESCENDING = 'desc'; |
|||
|
|||
/** |
|||
* The direction to sort in, either ISearchOrder::DIRECTION_ASCENDING or ISearchOrder::DIRECTION_DESCENDING |
|||
* |
|||
* @return string |
|||
* @since 12.0.0 |
|||
*/ |
|||
public function getDirection(); |
|||
|
|||
/** |
|||
* The field to sort on |
|||
* |
|||
* @return string |
|||
* @since 12.0.0 |
|||
*/ |
|||
public function getField(); |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
<?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 OCP\Files\Search; |
|||
|
|||
/** |
|||
* @since 12.0.0 |
|||
*/ |
|||
interface ISearchQuery { |
|||
/** |
|||
* @return ISearchOperator |
|||
* @since 12.0.0 |
|||
*/ |
|||
public function getSearchOperation(); |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<?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; |
|||
|
|||
use Test\TestCase; |
|||
|
|||
class QuerySearchHelperTest extends TestCase { |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue