Skip to content

Commit ab03a38

Browse files
committed
implements search on null/notnull metadata
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
1 parent 8bda5e9 commit ab03a38

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

apps/dav/lib/Files/FileSearchBackend.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use OCP\Files\Folder;
4040
use OCP\Files\IRootFolder;
4141
use OCP\Files\Node;
42+
use OCP\Files\Search\ISearchComparison;
4243
use OCP\Files\Search\ISearchOperator;
4344
use OCP\Files\Search\ISearchOrder;
4445
use OCP\Files\Search\ISearchQuery;
@@ -367,22 +368,30 @@ private function transformSearchOperation(Operator $operator) {
367368
if (count($operator->arguments) !== 2) {
368369
throw new \InvalidArgumentException('Invalid number of arguments for ' . $trimmedType . ' operation');
369370
}
370-
if (!($operator->arguments[0] instanceof SearchPropertyDefinition)) {
371-
throw new \InvalidArgumentException('Invalid argument 1 for ' . $trimmedType . ' operation, expected property');
372-
}
373371
if (!($operator->arguments[1] instanceof Literal)) {
374372
throw new \InvalidArgumentException('Invalid argument 2 for ' . $trimmedType . ' operation, expected literal');
375373
}
376-
374+
$value = $operator->arguments[1]->value;
375+
case Operator::OPERATION_IS_DEFINED:
376+
if (!($operator->arguments[0] instanceof SearchPropertyDefinition)) {
377+
throw new \InvalidArgumentException('Invalid argument 1 for ' . $trimmedType . ' operation, expected property');
378+
}
377379
$property = $operator->arguments[0];
378-
$value = $this->castValue($property, $operator->arguments[1]->value);
380+
379381
if (str_starts_with($property->name, FilesPlugin::FILE_METADATA_PREFIX)) {
380-
return new SearchComparison($trimmedType, substr($property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX)), $value, IMetadataQuery::EXTRA);
382+
$field = substr($property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX));
383+
$extra = IMetadataQuery::EXTRA;
381384
} else {
382-
return new SearchComparison($trimmedType, $this->mapPropertyNameToColumn($property), $value);
385+
$field = $this->mapPropertyNameToColumn($property);
383386
}
384387

385-
// no break
388+
return new SearchComparison(
389+
ISearchComparison::COMPARE_DEFINED,
390+
$field,
391+
$this->castValue($property, $value ?? ''),
392+
$extra ?? ''
393+
);
394+
386395
case Operator::OPERATION_IS_COLLECTION:
387396
return new SearchComparison('eq', 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE);
388397
default:
@@ -416,7 +425,11 @@ private function mapPropertyNameToColumn(SearchPropertyDefinition $property) {
416425
}
417426

418427
private function castValue(SearchPropertyDefinition $property, $value) {
419-
switch ($property->dataType) {
428+
if ($value === '') {
429+
return '';
430+
}
431+
432+
switch ($property->dataType) {
420433
case SearchPropertyDefinition::DATATYPE_BOOLEAN:
421434
return $value === 'yes';
422435
case SearchPropertyDefinition::DATATYPE_DECIMAL:

lib/private/Files/Cache/SearchBuilder.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class SearchBuilder {
4747
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte',
4848
ISearchComparison::COMPARE_LESS_THAN => 'lt',
4949
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte',
50+
ISearchComparison::COMPARE_DEFINED => 'isNotNull',
5051
];
5152

5253
protected static $searchOperatorNegativeMap = [
@@ -57,6 +58,7 @@ class SearchBuilder {
5758
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt',
5859
ISearchComparison::COMPARE_LESS_THAN => 'gte',
5960
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'gt',
61+
ISearchComparison::COMPARE_DEFINED => 'isNull',
6062
];
6163

6264
public const TAG_FAVORITE = '_$!<Favorite>!$_';

lib/public/Files/Search/ISearchComparison.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ interface ISearchComparison extends ISearchOperator {
3535
public const COMPARE_LESS_THAN_EQUAL = 'lte';
3636
public const COMPARE_LIKE = 'like';
3737
public const COMPARE_LIKE_CASE_SENSITIVE = 'clike';
38+
public const COMPARE_DEFINED = 'defined';
3839

3940
public const HINT_PATH_EQ_HASH = 'path_eq_hash'; // transform `path = "$path"` into `path_hash = md5("$path")`, on by default
4041

0 commit comments

Comments
 (0)