Skip to content

Commit 4018440

Browse files
committed
Merge branch 'main' of github.com:utopia-php/database into fix-encode-permissions
2 parents 8735c8f + e021d48 commit 4018440

File tree

19 files changed

+487
-78
lines changed

19 files changed

+487
-78
lines changed

src/Database/Adapter.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,13 @@ abstract public function getMaxIndexLength(): int;
862862
*/
863863
abstract public function getMinDateTime(): \DateTime;
864864

865+
/**
866+
* Get the primitive type of the primary key type for this adapter
867+
*
868+
* @return string
869+
*/
870+
abstract public function getIdAttributeType(): string;
871+
865872
/**
866873
* Get the maximum supported DateTime value
867874
*

src/Database/Adapter/MariaDB.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,6 +1749,9 @@ protected function getSQLType(string $type, int $size, bool $signed = true, bool
17491749
}
17501750

17511751
switch ($type) {
1752+
case Database::VAR_ID:
1753+
return 'BIGINT UNSIGNED';
1754+
17521755
case Database::VAR_STRING:
17531756
// $size = $size * 4; // Convert utf8mb4 size to bytes
17541757
if ($size > 16777215) {

src/Database/Adapter/Pool.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,11 @@ protected function execute(mixed $stmt): bool
495495
return $this->delegate(__FUNCTION__, \func_get_args());
496496
}
497497

498+
public function getIdAttributeType(): string
499+
{
500+
return $this->delegate(__FUNCTION__, \func_get_args());
501+
}
502+
498503
public function getSequences(string $collection, array $documents): array
499504
{
500505
return $this->delegate(__FUNCTION__, \func_get_args());

src/Database/Adapter/Postgres.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,9 @@ protected function getSQLType(string $type, int $size, bool $signed = true, bool
18621862
}
18631863

18641864
switch ($type) {
1865+
case Database::VAR_ID:
1866+
return 'BIGINT';
1867+
18651868
case Database::VAR_STRING:
18661869
// $size = $size * 4; // Convert utf8mb4 size to bytes
18671870
if ($size > $this->getMaxVarcharLength()) {

src/Database/Adapter/SQL.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,10 @@ public function getAttributeWidth(Document $collection): int
10231023
}
10241024

10251025
switch ($attribute['type']) {
1026+
case Database::VAR_ID:
1027+
$total += 8; // BIGINT 8 bytes
1028+
break;
1029+
10261030
case Database::VAR_STRING:
10271031
/**
10281032
* Text / Mediumtext / Longtext
@@ -1620,6 +1624,14 @@ public function getMaxVarcharLength(): int
16201624
return 16381; // Floor value for Postgres:16383 | MySQL:16381 | MariaDB:16382
16211625
}
16221626

1627+
/**
1628+
* @return string
1629+
*/
1630+
public function getIdAttributeType(): string
1631+
{
1632+
return Database::VAR_INTEGER;
1633+
}
1634+
16231635
/**
16241636
* @return int
16251637
*/

src/Database/Database.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class Database
4141
public const VAR_FLOAT = 'double';
4242
public const VAR_BOOLEAN = 'boolean';
4343
public const VAR_DATETIME = 'datetime';
44+
public const VAR_ID = 'id';
45+
public const VAR_OBJECT_ID = 'objectId';
4446

4547
public const INT_MAX = 2147483647;
4648
public const BIG_INT_MAX = PHP_INT_MAX;
@@ -167,8 +169,8 @@ class Database
167169
],
168170
[
169171
'$id' => '$sequence',
170-
'type' => self::VAR_STRING,
171-
'size' => Database::LENGTH_KEY,
172+
'type' => self::VAR_ID,
173+
'size' => 0,
172174
'required' => true,
173175
'signed' => true,
174176
'array' => false,
@@ -186,6 +188,7 @@ class Database
186188
[
187189
'$id' => '$tenant',
188190
'type' => self::VAR_INTEGER,
191+
//'type' => self::VAR_ID, // Inconsistency with other VAR_ID since this is an INT
189192
'size' => 0,
190193
'required' => false,
191194
'default' => null,
@@ -1789,6 +1792,9 @@ private function validateAttribute(
17891792
$this->checkAttribute($collection, $attribute);
17901793

17911794
switch ($type) {
1795+
case self::VAR_ID:
1796+
1797+
break;
17921798
case self::VAR_STRING:
17931799
if ($size > $this->adapter->getLimitForString()) {
17941800
throw new DatabaseException('Max size allowed for string is: ' . number_format($this->adapter->getLimitForString()));
@@ -3637,6 +3643,7 @@ public function createDocument(string $collection, Document $document): Document
36373643

36383644
$structure = new Structure(
36393645
$collection,
3646+
$this->adapter->getIdAttributeType(),
36403647
$this->adapter->getMinDateTime(),
36413648
$this->adapter->getMaxDateTime(),
36423649
);
@@ -3730,6 +3737,7 @@ public function createDocuments(
37303737

37313738
$validator = new Structure(
37323739
$collection,
3740+
$this->adapter->getIdAttributeType(),
37333741
$this->adapter->getMinDateTime(),
37343742
$this->adapter->getMaxDateTime(),
37353743
);
@@ -4274,6 +4282,7 @@ public function updateDocument(string $collection, string $id, Document $documen
42744282

42754283
$structureValidator = new Structure(
42764284
$collection,
4285+
$this->adapter->getIdAttributeType(),
42774286
$this->adapter->getMinDateTime(),
42784287
$this->adapter->getMaxDateTime(),
42794288
);
@@ -4358,6 +4367,7 @@ public function updateDocuments(
43584367
$validator = new DocumentsValidator(
43594368
$attributes,
43604369
$indexes,
4370+
$this->adapter->getIdAttributeType(),
43614371
$this->maxQueryValues,
43624372
$this->adapter->getMinDateTime(),
43634373
$this->adapter->getMaxDateTime(),
@@ -4393,6 +4403,7 @@ public function updateDocuments(
43934403
// Check new document structure
43944404
$validator = new PartialStructure(
43954405
$collection,
4406+
$this->adapter->getIdAttributeType(),
43964407
$this->adapter->getMinDateTime(),
43974408
$this->adapter->getMaxDateTime(),
43984409
);
@@ -5043,6 +5054,7 @@ public function createOrUpdateDocumentsWithIncrease(
50435054

50445055
$validator = new Structure(
50455056
$collection,
5057+
$this->adapter->getIdAttributeType(),
50465058
$this->adapter->getMinDateTime(),
50475059
$this->adapter->getMaxDateTime(),
50485060
);
@@ -5823,6 +5835,7 @@ public function deleteDocuments(
58235835
$validator = new DocumentsValidator(
58245836
$attributes,
58255837
$indexes,
5838+
$this->adapter->getIdAttributeType(),
58265839
$this->maxQueryValues,
58275840
$this->adapter->getMinDateTime(),
58285841
$this->adapter->getMaxDateTime()
@@ -6018,6 +6031,7 @@ public function find(string $collection, array $queries = [], string $forPermiss
60186031
$validator = new DocumentsValidator(
60196032
$attributes,
60206033
$indexes,
6034+
$this->adapter->getIdAttributeType(),
60216035
$this->maxQueryValues,
60226036
$this->adapter->getMinDateTime(),
60236037
$this->adapter->getMaxDateTime(),
@@ -6228,6 +6242,7 @@ public function count(string $collection, array $queries = [], ?int $max = null)
62286242
$validator = new DocumentsValidator(
62296243
$attributes,
62306244
$indexes,
6245+
$this->adapter->getIdAttributeType(),
62316246
$this->maxQueryValues,
62326247
$this->adapter->getMinDateTime(),
62336248
$this->adapter->getMaxDateTime(),
@@ -6278,6 +6293,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
62786293
$validator = new DocumentsValidator(
62796294
$attributes,
62806295
$indexes,
6296+
$this->adapter->getIdAttributeType(),
62816297
$this->maxQueryValues,
62826298
$this->adapter->getMinDateTime(),
62836299
$this->adapter->getMaxDateTime(),
@@ -6500,6 +6516,12 @@ public function casting(Document $collection, Document $document): Document
65006516

65016517
foreach ($value as $index => $node) {
65026518
switch ($type) {
6519+
case self::VAR_ID:
6520+
// Disabled until Appwrite migrates to use real int ID's for MySQL
6521+
//$type = $this->adapter->getIdAttributeType();
6522+
//\settype($node, $type);
6523+
$node = (string)$node;
6524+
break;
65036525
case self::VAR_BOOLEAN:
65046526
$node = (bool)$node;
65056527
break;

src/Database/Validator/Queries/Documents.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ class Documents extends IndexedQueries
2020
*
2121
* @param array<mixed> $attributes
2222
* @param array<mixed> $indexes
23+
* @param string $idAttributeType
2324
* @throws Exception
2425
*/
2526
public function __construct(
2627
array $attributes,
2728
array $indexes,
29+
string $idAttributeType,
2830
int $maxValuesCount = 100,
2931
\DateTime $minAllowedDate = new \DateTime('0000-01-01'),
3032
\DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
@@ -38,7 +40,7 @@ public function __construct(
3840
$attributes[] = new Document([
3941
'$id' => '$sequence',
4042
'key' => '$sequence',
41-
'type' => Database::VAR_STRING,
43+
'type' => Database::VAR_ID,
4244
'array' => false,
4345
]);
4446
$attributes[] = new Document([
@@ -60,6 +62,7 @@ public function __construct(
6062
new Cursor(),
6163
new Filter(
6264
$attributes,
65+
$idAttributeType,
6366
$maxValuesCount,
6467
$minAllowedDate,
6568
$maxAllowedDate,

src/Database/Validator/Query/Filter.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Utopia\Database\Document;
77
use Utopia\Database\Query;
88
use Utopia\Database\Validator\Datetime as DatetimeValidator;
9+
use Utopia\Database\Validator\Sequence;
910
use Utopia\Validator\Boolean;
1011
use Utopia\Validator\FloatValidator;
1112
use Utopia\Validator\Integer;
@@ -25,7 +26,8 @@ class Filter extends Base
2526
* @param \DateTime $maxAllowedDate
2627
*/
2728
public function __construct(
28-
array $attributes = [],
29+
array $attributes,
30+
private readonly string $idAttributeType,
2931
private readonly int $maxValuesCount = 100,
3032
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
3133
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
@@ -106,6 +108,10 @@ protected function isValidAttributeAndValues(string $attribute, array $values, s
106108
$validator = null;
107109

108110
switch ($attributeType) {
111+
case Database::VAR_ID:
112+
$validator = new Sequence($this->idAttributeType, $attribute === '$sequence');
113+
break;
114+
109115
case Database::VAR_STRING:
110116
$validator = new Text(0, 0);
111117
break;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Utopia\Database\Validator;
4+
5+
use Utopia\Database\Database;
6+
use Utopia\Validator;
7+
use Utopia\Validator\Range;
8+
9+
class Sequence extends Validator
10+
{
11+
private string $idAttributeType;
12+
private bool $primary;
13+
14+
public function getDescription(): string
15+
{
16+
return 'Invalid sequence value';
17+
}
18+
19+
/**
20+
* Expression constructor
21+
*/
22+
public function __construct(string $idAttributeType, bool $primary)
23+
{
24+
$this->primary = $primary;
25+
$this->idAttributeType = $idAttributeType;
26+
}
27+
28+
public function isArray(): bool
29+
{
30+
return false;
31+
}
32+
33+
public function getType(): string
34+
{
35+
return self::TYPE_STRING;
36+
}
37+
38+
public function isValid($value): bool
39+
{
40+
if ($this->primary && empty($value)) {
41+
return false;
42+
}
43+
44+
if (!\is_string($value)) {
45+
return false;
46+
}
47+
48+
switch ($this->idAttributeType) {
49+
case Database::VAR_OBJECT_ID:
50+
return preg_match('/^[a-f0-9]{24}$/i', $value) === 1;
51+
52+
case Database::VAR_INTEGER:
53+
$start = ($this->primary) ? 1 : 0;
54+
$validator = new Range($start, Database::BIG_INT_MAX, Database::VAR_INTEGER);
55+
return $validator->isValid($value);
56+
57+
default:
58+
return false;
59+
}
60+
}
61+
}

src/Database/Validator/Structure.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ class Structure extends Validator
3232
],
3333
[
3434
'$id' => '$sequence',
35-
'type' => Database::VAR_STRING,
36-
'size' => 255,
35+
'type' => Database::VAR_ID,
36+
'size' => 0,
3737
'required' => false,
3838
'signed' => true,
3939
'array' => false,
@@ -50,7 +50,7 @@ class Structure extends Validator
5050
],
5151
[
5252
'$id' => '$tenant',
53-
'type' => Database::VAR_INTEGER,
53+
'type' => Database::VAR_INTEGER, // ? VAR_ID
5454
'size' => 8,
5555
'required' => false,
5656
'default' => null,
@@ -103,6 +103,7 @@ class Structure extends Validator
103103
*/
104104
public function __construct(
105105
protected readonly Document $collection,
106+
private readonly string $idAttributeType,
106107
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
107108
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
108109
) {
@@ -315,6 +316,10 @@ protected function checkForInvalidAttributeValues(array $structure, array $keys)
315316
$validators = [];
316317

317318
switch ($type) {
319+
case Database::VAR_ID:
320+
$validators[] = new Sequence($this->idAttributeType, $attribute['$id'] === '$sequence');
321+
break;
322+
318323
case Database::VAR_STRING:
319324
$validators[] = new Text($size, min: 0);
320325
break;

0 commit comments

Comments
 (0)