Skip to content

Commit 4741ab1

Browse files
authored
Merge pull request #714 from utopia-php/attributes-fix-schemaless
Add support for schemaless attributes in Database and Structure classes
2 parents 873f2ae + 533e530 commit 4741ab1

11 files changed

Lines changed: 321 additions & 49 deletions

File tree

src/Database/Database.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,7 @@ public function createCollection(string $id, array $attributes = [], array $inde
14111411
$this->adapter->getSupportForSpatialAttributes(),
14121412
$this->adapter->getSupportForSpatialIndexNull(),
14131413
$this->adapter->getSupportForSpatialIndexOrder(),
1414+
$this->adapter->getSupportForAttributes()
14141415
);
14151416
foreach ($indexes as $index) {
14161417
if (!$validator->isValid($index)) {
@@ -2420,6 +2421,7 @@ public function updateAttribute(string $collection, string $id, ?string $type =
24202421
$this->adapter->getSupportForSpatialAttributes(),
24212422
$this->adapter->getSupportForSpatialIndexNull(),
24222423
$this->adapter->getSupportForSpatialIndexOrder(),
2424+
$this->adapter->getSupportForAttributes()
24232425
);
24242426

24252427
foreach ($indexes as $index) {
@@ -3363,6 +3365,7 @@ public function createIndex(string $collection, string $id, string $type, array
33633365
$this->adapter->getSupportForSpatialAttributes(),
33643366
$this->adapter->getSupportForSpatialIndexNull(),
33653367
$this->adapter->getSupportForSpatialIndexOrder(),
3368+
$this->adapter->getSupportForAttributes()
33663369
);
33673370
if (!$validator->isValid($index)) {
33683371
throw new IndexException($validator->getDescription());
@@ -3906,6 +3909,7 @@ public function createDocument(string $collection, Document $document): Document
39063909
$this->adapter->getIdAttributeType(),
39073910
$this->adapter->getMinDateTime(),
39083911
$this->adapter->getMaxDateTime(),
3912+
$this->adapter->getSupportForAttributes()
39093913
);
39103914
if (!$structure->isValid($document)) {
39113915
throw new StructureException($structure->getDescription());
@@ -4006,6 +4010,7 @@ public function createDocuments(
40064010
$this->adapter->getIdAttributeType(),
40074011
$this->adapter->getMinDateTime(),
40084012
$this->adapter->getMaxDateTime(),
4013+
$this->adapter->getSupportForAttributes()
40094014
);
40104015
if (!$validator->isValid($document)) {
40114016
throw new StructureException($validator->getDescription());
@@ -4559,6 +4564,7 @@ public function updateDocument(string $collection, string $id, Document $documen
45594564
$this->adapter->getIdAttributeType(),
45604565
$this->adapter->getMinDateTime(),
45614566
$this->adapter->getMaxDateTime(),
4567+
$this->adapter->getSupportForAttributes()
45624568
);
45634569
if (!$structureValidator->isValid($document)) { // Make sure updated structure still apply collection rules (if any)
45644570
throw new StructureException($structureValidator->getDescription());
@@ -4693,6 +4699,7 @@ public function updateDocuments(
46934699
$this->adapter->getIdAttributeType(),
46944700
$this->adapter->getMinDateTime(),
46954701
$this->adapter->getMaxDateTime(),
4702+
$this->adapter->getSupportForAttributes()
46964703
);
46974704

46984705
if (!$validator->isValid($updates)) {
@@ -5404,6 +5411,7 @@ public function upsertDocumentsWithIncrease(
54045411
$this->adapter->getIdAttributeType(),
54055412
$this->adapter->getMinDateTime(),
54065413
$this->adapter->getMaxDateTime(),
5414+
$this->adapter->getSupportForAttributes()
54075415
);
54085416

54095417
if (!$validator->isValid($document)) {
@@ -6397,6 +6405,7 @@ public function find(string $collection, array $queries = [], string $forPermiss
63976405
$this->maxQueryValues,
63986406
$this->adapter->getMinDateTime(),
63996407
$this->adapter->getMaxDateTime(),
6408+
$this->adapter->getSupportForAttributes()
64006409
);
64016410
if (!$validator->isValid($queries)) {
64026411
throw new QueryException($validator->getDescription());

src/Database/Validator/Index.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Index extends Validator
3030

3131
protected bool $spatialIndexOrderSupport;
3232

33+
protected bool $supportForAttributes;
3334
/**
3435
* @param array<Document> $attributes
3536
* @param int $maxLength
@@ -40,14 +41,15 @@ class Index extends Validator
4041
* @param bool $spatialIndexOrderSupport
4142
* @throws DatabaseException
4243
*/
43-
public function __construct(array $attributes, int $maxLength, array $reservedKeys = [], bool $arrayIndexSupport = false, bool $spatialIndexSupport = false, bool $spatialIndexNullSupport = false, bool $spatialIndexOrderSupport = false)
44+
public function __construct(array $attributes, int $maxLength, array $reservedKeys = [], bool $arrayIndexSupport = false, bool $spatialIndexSupport = false, bool $spatialIndexNullSupport = false, bool $spatialIndexOrderSupport = false, bool $supportForAttributes = true)
4445
{
4546
$this->maxLength = $maxLength;
4647
$this->reservedKeys = $reservedKeys;
4748
$this->arrayIndexSupport = $arrayIndexSupport;
4849
$this->spatialIndexSupport = $spatialIndexSupport;
4950
$this->spatialIndexNullSupport = $spatialIndexNullSupport;
5051
$this->spatialIndexOrderSupport = $spatialIndexOrderSupport;
52+
$this->supportForAttributes = $supportForAttributes;
5153

5254
foreach ($attributes as $attribute) {
5355
$key = \strtolower($attribute->getAttribute('key', $attribute->getAttribute('$id')));
@@ -75,7 +77,7 @@ public function getDescription(): string
7577
public function checkAttributesNotFound(Document $index): bool
7678
{
7779
foreach ($index->getAttribute('attributes', []) as $attribute) {
78-
if (!isset($this->attributes[\strtolower($attribute)])) {
80+
if ($this->supportForAttributes && !isset($this->attributes[\strtolower($attribute)])) {
7981
$this->message = 'Invalid index attribute "' . $attribute . '" not found';
8082
return false;
8183
}
@@ -123,6 +125,9 @@ public function checkDuplicatedAttributes(Document $index): bool
123125
*/
124126
public function checkFulltextIndexNonString(Document $index): bool
125127
{
128+
if (!$this->supportForAttributes) {
129+
return true;
130+
}
126131
if ($index->getAttribute('type') === Database::INDEX_FULLTEXT) {
127132
foreach ($index->getAttribute('attributes', []) as $attribute) {
128133
$attribute = $this->attributes[\strtolower($attribute)] ?? new Document();
@@ -141,6 +146,9 @@ public function checkFulltextIndexNonString(Document $index): bool
141146
*/
142147
public function checkArrayIndex(Document $index): bool
143148
{
149+
if (!$this->supportForAttributes) {
150+
return true;
151+
}
144152
$attributes = $index->getAttribute('attributes', []);
145153
$orders = $index->getAttribute('orders', []);
146154
$lengths = $index->getAttribute('lengths', []);

src/Database/Validator/Queries/Documents.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function __construct(
3030
int $maxValuesCount = 100,
3131
\DateTime $minAllowedDate = new \DateTime('0000-01-01'),
3232
\DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
33+
bool $supportForAttributes = true
3334
) {
3435
$attributes[] = new Document([
3536
'$id' => '$id',
@@ -66,9 +67,10 @@ public function __construct(
6667
$maxValuesCount,
6768
$minAllowedDate,
6869
$maxAllowedDate,
70+
$supportForAttributes
6971
),
70-
new Order($attributes),
71-
new Select($attributes),
72+
new Order($attributes, $supportForAttributes),
73+
new Select($attributes, $supportForAttributes),
7274
];
7375

7476
parent::__construct($attributes, $indexes, $validators);

src/Database/Validator/Query/Filter.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function __construct(
3131
private readonly int $maxValuesCount = 100,
3232
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
3333
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
34+
private bool $supportForAttributes = true
3435
) {
3536
foreach ($attributes as $attribute) {
3637
$this->schema[$attribute->getAttribute('key', $attribute->getAttribute('$id'))] = $attribute->getArrayCopy();
@@ -67,7 +68,7 @@ protected function isValidAttribute(string $attribute): bool
6768
}
6869

6970
// Search for attribute in schema
70-
if (!isset($this->schema[$attribute])) {
71+
if ($this->supportForAttributes && !isset($this->schema[$attribute])) {
7172
$this->message = 'Attribute not found in schema: ' . $attribute;
7273
return false;
7374
}
@@ -94,6 +95,9 @@ protected function isValidAttributeAndValues(string $attribute, array $values, s
9495
$attribute = \explode('.', $attribute)[0];
9596
}
9697

98+
if (!$this->supportForAttributes && !isset($this->schema[$attribute])) {
99+
return true;
100+
}
97101
$attributeSchema = $this->schema[$attribute];
98102

99103
if (count($values) > $this->maxValuesCount) {

src/Database/Validator/Query/Order.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ class Order extends Base
1414

1515
/**
1616
* @param array<Document> $attributes
17+
* @param bool $supportForAttributes
1718
*/
18-
public function __construct(array $attributes = [])
19+
public function __construct(array $attributes = [], protected bool $supportForAttributes = true)
1920
{
2021
foreach ($attributes as $attribute) {
2122
$this->schema[$attribute->getAttribute('key', $attribute->getAttribute('$id'))] = $attribute->getArrayCopy();
@@ -29,7 +30,7 @@ public function __construct(array $attributes = [])
2930
protected function isValidAttribute(string $attribute): bool
3031
{
3132
// Search for attribute in schema
32-
if (!isset($this->schema[$attribute])) {
33+
if ($this->supportForAttributes && !isset($this->schema[$attribute])) {
3334
$this->message = 'Attribute not found in schema: ' . $attribute;
3435
return false;
3536
}

src/Database/Validator/Query/Select.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ class Select extends Base
2929

3030
/**
3131
* @param array<Document> $attributes
32+
* @param bool $supportForAttributes
3233
*/
33-
public function __construct(array $attributes = [])
34+
public function __construct(array $attributes = [], protected bool $supportForAttributes = true)
3435
{
3536
foreach ($attributes as $attribute) {
3637
$this->schema[$attribute->getAttribute('key', $attribute->getAttribute('$id'))] = $attribute->getArrayCopy();
@@ -89,7 +90,7 @@ public function isValid($value): bool
8990
continue;
9091
}
9192

92-
if (!isset($this->schema[$attribute]) && $attribute !== '*') {
93+
if ($this->supportForAttributes && !isset($this->schema[$attribute]) && $attribute !== '*') {
9394
$this->message = 'Attribute not found in schema: ' . $attribute;
9495
return false;
9596
}

src/Database/Validator/Structure.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function __construct(
106106
private readonly string $idAttributeType,
107107
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
108108
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
109+
private bool $supportForAttributes = true
109110
) {
110111
}
111112

@@ -251,7 +252,11 @@ public function isValid($document): bool
251252
*/
252253
protected function checkForAllRequiredValues(array $structure, array $attributes, array &$keys): bool
253254
{
254-
foreach ($attributes as $key => $attribute) { // Check all required attributes are set
255+
if (!$this->supportForAttributes) {
256+
return true;
257+
}
258+
259+
foreach ($attributes as $attribute) { // Check all required attributes are set
255260
$name = $attribute['$id'] ?? '';
256261
$required = $attribute['required'] ?? false;
257262

@@ -276,6 +281,9 @@ protected function checkForAllRequiredValues(array $structure, array $attributes
276281
*/
277282
protected function checkForUnknownAttributes(array $structure, array $keys): bool
278283
{
284+
if (!$this->supportForAttributes) {
285+
return true;
286+
}
279287
foreach ($structure as $key => $value) {
280288
if (!array_key_exists($key, $keys)) { // Check no unknown attributes are set
281289
$this->message = 'Unknown attribute: "'.$key.'"';
@@ -357,8 +365,10 @@ protected function checkForInvalidAttributeValues(array $structure, array $keys)
357365
break;
358366

359367
default:
360-
$this->message = 'Unknown attribute type "'.$type.'"';
361-
return false;
368+
if ($this->supportForAttributes) {
369+
$this->message = 'Unknown attribute type "'.$type.'"';
370+
return false;
371+
}
362372
}
363373

364374
/** Error message label, either 'format' or 'type' */

0 commit comments

Comments
 (0)