Skip to content

Commit 6b5274e

Browse files
committed
Fix validator
1 parent 05f6e75 commit 6b5274e

1 file changed

Lines changed: 133 additions & 57 deletions

File tree

src/Database/Validator/Index.php

Lines changed: 133 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ public function __construct(
5353
}
5454
}
5555

56+
/**
57+
* Get Type
58+
*
59+
* Returns validator type.
60+
*
61+
* @return string
62+
*/
63+
public function getType(): string
64+
{
65+
return self::TYPE_OBJECT;
66+
}
67+
5668
/**
5769
* Returns validator description
5870
* @return string
@@ -62,11 +74,69 @@ public function getDescription(): string
6274
return $this->message;
6375
}
6476

77+
/**
78+
* Is array
79+
*
80+
* Function will return true if object is array.
81+
*
82+
* @return bool
83+
*/
84+
public function isArray(): bool
85+
{
86+
return false;
87+
}
88+
89+
/**
90+
* Is valid.
91+
*
92+
* Returns true index if valid.
93+
* @param Document $value
94+
* @return bool
95+
* @throws DatabaseException
96+
*/
97+
public function isValid($value): bool
98+
{
99+
if (!$this->checkValidAttributes($value)) {
100+
return false;
101+
}
102+
if (!$this->checkEmptyIndexAttributes($value)) {
103+
return false;
104+
}
105+
if (!$this->checkDuplicatedAttributes($value)) {
106+
return false;
107+
}
108+
if (!$this->checkMultipleFulltextIndexes($value)) {
109+
return false;
110+
}
111+
if (!$this->checkFulltextIndexNonString($value)) {
112+
return false;
113+
}
114+
if (!$this->checkArrayIndexes($value)) {
115+
return false;
116+
}
117+
if (!$this->checkIndexLengths($value)) {
118+
return false;
119+
}
120+
if (!$this->checkReservedNames($value)) {
121+
return false;
122+
}
123+
if (!$this->checkSpatialIndexes($value)) {
124+
return false;
125+
}
126+
if (!$this->checkNonSpatialIndexOnSpatialAttributes($value)) {
127+
return false;
128+
}
129+
if (!$this->checkVectorIndexes($value)) {
130+
return false;
131+
}
132+
return true;
133+
}
134+
65135
/**
66136
* @param Document $index
67137
* @return bool
68138
*/
69-
public function checkAttributesNotFound(Document $index): bool
139+
public function checkValidAttributes(Document $index): bool
70140
{
71141
foreach ($index->getAttribute('attributes', []) as $attribute) {
72142
if ($this->supportForAttributes && !isset($this->attributes[\strtolower($attribute)])) {
@@ -136,7 +206,7 @@ public function checkFulltextIndexNonString(Document $index): bool
136206
* @param Document $index
137207
* @return bool
138208
*/
139-
public function checkArrayIndex(Document $index): bool
209+
public function checkArrayIndexes(Document $index): bool
140210
{
141211
if (!$this->supportForAttributes) {
142212
return true;
@@ -189,7 +259,7 @@ public function checkArrayIndex(Document $index): bool
189259
* @param Document $index
190260
* @return bool
191261
*/
192-
public function checkIndexLength(Document $index): bool
262+
public function checkIndexLengths(Document $index): bool
193263
{
194264
if ($index->getAttribute('type') === Database::INDEX_FULLTEXT) {
195265
return true;
@@ -271,7 +341,7 @@ public function checkReservedNames(Document $index): bool
271341
* @param Document $index
272342
* @return bool
273343
*/
274-
public function checkSpatialIndex(Document $index): bool
344+
public function checkSpatialIndexes(Document $index): bool
275345
{
276346
$type = $index->getAttribute('type');
277347

@@ -315,7 +385,7 @@ public function checkSpatialIndex(Document $index): bool
315385
* @param Document $index
316386
* @return bool
317387
*/
318-
public function checkNonSpatialIndexOnSpatialAttribute(Document $index): bool
388+
public function checkNonSpatialIndexOnSpatialAttributes(Document $index): bool
319389
{
320390
$type = $index->getAttribute('type');
321391

@@ -344,7 +414,7 @@ public function checkNonSpatialIndexOnSpatialAttribute(Document $index): bool
344414
* @return bool
345415
* @throws DatabaseException
346416
*/
347-
public function checkVectorIndex(Document $index): bool
417+
public function checkVectorIndexes(Document $index): bool
348418
{
349419
$type = $index->getAttribute('type');
350420

@@ -385,69 +455,75 @@ public function checkVectorIndex(Document $index): bool
385455
}
386456

387457
/**
388-
* Is valid.
389-
*
390-
* Returns true index if valid.
391-
* @param Document $value
458+
* @param Document $index
392459
* @return bool
393-
* @throws DatabaseException
394460
*/
395-
public function isValid($value): bool
461+
public function checkMultipleFulltextIndexes(Document $index): bool
396462
{
397-
if (!$this->checkAttributesNotFound($value)) {
398-
return false;
399-
}
400-
if (!$this->checkEmptyIndexAttributes($value)) {
401-
return false;
402-
}
403-
if (!$this->checkDuplicatedAttributes($value)) {
404-
return false;
405-
}
406-
if (!$this->checkFulltextIndexNonString($value)) {
407-
return false;
408-
}
409-
if (!$this->checkArrayIndex($value)) {
410-
return false;
411-
}
412-
if (!$this->checkIndexLength($value)) {
413-
return false;
414-
}
415-
if (!$this->checkReservedNames($value)) {
416-
return false;
417-
}
418-
if (!$this->checkSpatialIndex($value)) {
419-
return false;
420-
}
421-
if (!$this->checkNonSpatialIndexOnSpatialAttribute($value)) {
422-
return false;
463+
if ($this->supportForMultipleFulltextIndexes) {
464+
return true;
423465
}
424-
if (!$this->checkVectorIndex($value)) {
425-
return false;
466+
467+
if ($index->getAttribute('type') === Database::INDEX_FULLTEXT) {
468+
foreach ($this->indexes as $existingIndex) {
469+
if ($existingIndex->getId() === $index->getId()) {
470+
continue;
471+
}
472+
if ($existingIndex->getAttribute('type') === Database::INDEX_FULLTEXT) {
473+
$this->message = 'There is already a fulltext index in the collection';
474+
return false;
475+
}
476+
}
426477
}
478+
427479
return true;
428480
}
429481

430482
/**
431-
* Is array
432-
*
433-
* Function will return true if object is array.
434-
*
483+
* @param Document $index
435484
* @return bool
436485
*/
437-
public function isArray(): bool
486+
public function checkIdenticalIndexes(Document $index): bool
438487
{
439-
return false;
440-
}
488+
if ($this->supportForIdenticalIndexes) {
489+
return true;
490+
}
441491

442-
/**
443-
* Get Type
444-
*
445-
* Returns validator type.
446-
*
447-
* @return string
448-
*/
449-
public function getType(): string
450-
{
451-
return self::TYPE_OBJECT;
492+
$indexAttributes = $index->getAttribute('attributes', []);
493+
$indexOrders = $index->getAttribute('orders', []);
494+
$indexType = $index->getAttribute('type', '');
495+
496+
foreach ($this->indexes as $existingIndex) {
497+
$existingAttributes = $existingIndex->getAttribute('attributes', []);
498+
$existingOrders = $existingIndex->getAttribute('orders', []);
499+
$existingType = $existingIndex->getAttribute('type', '');
500+
501+
$attributesMatch = false;
502+
if (empty(\array_diff($existingAttributes, $indexAttributes)) &&
503+
empty(\array_diff($indexAttributes, $existingAttributes))) {
504+
$attributesMatch = true;
505+
}
506+
507+
$ordersMatch = false;
508+
if (empty(\array_diff($existingOrders, $indexOrders)) &&
509+
empty(\array_diff($indexOrders, $existingOrders))) {
510+
$ordersMatch = true;
511+
}
512+
513+
if ($attributesMatch && $ordersMatch) {
514+
// Allow fulltext + key/unique combinations (different purposes)
515+
$regularTypes = [Database::INDEX_KEY, Database::INDEX_UNIQUE];
516+
$isRegularIndex = \in_array($indexType, $regularTypes);
517+
$isRegularExisting = \in_array($existingType, $regularTypes);
518+
519+
// Only reject if both are regular index types (key or unique)
520+
if ($isRegularIndex && $isRegularExisting) {
521+
$this->message = 'There is already an index with the same attributes and orders';
522+
return false;
523+
}
524+
}
525+
}
526+
527+
return true;
452528
}
453529
}

0 commit comments

Comments
 (0)