-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathIndexedQueries.php
More file actions
118 lines (99 loc) · 3.03 KB
/
IndexedQueries.php
File metadata and controls
118 lines (99 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
namespace Utopia\Database\Validator;
use Exception;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Base;
class IndexedQueries extends Queries
{
/**
* @var array<Document>
*/
protected array $attributes = [];
/**
* @var array<Document>
*/
protected array $indexes = [];
/**
* Expression constructor
*
* This Queries Validator filters indexes for only available indexes
*
* @param array<Document> $attributes
* @param array<Document> $indexes
* @param array<Base> $validators
* @throws Exception
*/
public function __construct(array $attributes = [], array $indexes = [], array $validators = [])
{
$this->attributes = $attributes;
$this->indexes[] = new Document([
'type' => Database::INDEX_UNIQUE,
'attributes' => ['$id']
]);
$this->indexes[] = new Document([
'type' => Database::INDEX_KEY,
'attributes' => ['$createdAt']
]);
$this->indexes[] = new Document([
'type' => Database::INDEX_KEY,
'attributes' => ['$updatedAt']
]);
foreach ($indexes as $index) {
$this->indexes[] = $index;
}
parent::__construct($validators);
}
/**
* @param mixed $value
* @return bool
* @throws Exception
*/
public function isValid($value): bool
{
if (!parent::isValid($value)) {
return false;
}
$queries = [];
foreach ($value as $query) {
if (! $query instanceof Query) {
try {
$query = Query::parse($query);
} catch (\Throwable $e) {
$this->message = 'Invalid query: '.$e->getMessage();
return false;
}
}
if ($query->isNested()) {
if (! self::isValid($query->getValues())) {
return false;
}
}
$queries[] = $query;
}
$grouped = Query::groupByType($queries);
$filters = $grouped['filters'];
foreach ($filters as $filter) {
if (
$filter->getMethod() === Query::TYPE_SEARCH ||
$filter->getMethod() === Query::TYPE_NOT_SEARCH
) {
$matched = false;
foreach ($this->indexes as $index) {
if (
$index->getAttribute('type') === Database::INDEX_FULLTEXT
&& $index->getAttribute('attributes') === [$filter->getAttribute()]
) {
$matched = true;
}
}
if (!$matched) {
$this->message = "Searching by attribute \"{$filter->getAttribute()}\" requires a fulltext index.";
return false;
}
}
}
return true;
}
}