Skip to content

Commit 9c3defb

Browse files
fix: align bigint handling and validator refactors from PR feedback
Agent-Logs-Url: https://github.com/utopia-php/database/sessions/8522088a-f191-48f9-9d1b-4ab793aa8e45 Co-authored-by: ArnabChatterjee20k <83803257+ArnabChatterjee20k@users.noreply.github.com>
1 parent 0e43fd4 commit 9c3defb

5 files changed

Lines changed: 34 additions & 46 deletions

File tree

src/Database/Database.php

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,6 +2122,10 @@ public function createAttribute(string $collection, string $id, string $type, in
21222122
$filters = array_unique($filters);
21232123
}
21242124

2125+
if ($type === self::VAR_BIGINT) {
2126+
$size = 0;
2127+
}
2128+
21252129
$existsInSchema = false;
21262130

21272131
$schemaAttributes = $this->adapter->getSupportForSchemaAttributes()
@@ -2315,6 +2319,10 @@ public function createAttributes(string $collection, array $attributes): bool
23152319
$attribute['filters'] = [];
23162320
}
23172321

2322+
if ($attribute['type'] === self::VAR_BIGINT) {
2323+
$attribute['size'] = 0;
2324+
}
2325+
23182326
$existsInSchema = false;
23192327

23202328
try {
@@ -2487,6 +2495,10 @@ private function validateAttribute(
24872495
array $filters,
24882496
?array $schemaAttributes = null
24892497
): Document {
2498+
if ($type === self::VAR_BIGINT) {
2499+
$size = 0;
2500+
}
2501+
24902502
$attribute = new Document([
24912503
'$id' => ID::custom($id),
24922504
'key' => $id,
@@ -2519,12 +2531,12 @@ private function validateAttribute(
25192531
supportForVectors: $this->adapter->getSupportForVectors(),
25202532
supportForSpatialAttributes: $this->adapter->getSupportForSpatialAttributes(),
25212533
supportForObject: $this->adapter->getSupportForObject(),
2534+
supportUnsignedBigInt: $this->adapter->getSupportForUnsignedBigInt(),
25222535
attributeCountCallback: fn () => $this->adapter->getCountOfAttributes($collectionClone),
25232536
attributeWidthCallback: fn () => $this->adapter->getAttributeWidth($collectionClone),
25242537
filterCallback: fn ($id) => $this->adapter->filter($id),
25252538
isMigrating: $this->isMigrating(),
25262539
sharedTables: $this->getSharedTables(),
2527-
supportUnsignedBigInt: $this->adapter->getSupportForUnsignedBigInt(),
25282540
);
25292541

25302542
$validator->isValid($attribute);
@@ -2877,6 +2889,10 @@ public function updateAttribute(string $collection, string $id, ?string $type =
28772889
$formatOptions ??= $attribute->getAttribute('formatOptions');
28782890
$filters ??= $attribute->getAttribute('filters');
28792891

2892+
if ($type === self::VAR_BIGINT) {
2893+
$size = 0;
2894+
}
2895+
28802896
if ($required === true && !\is_null($default)) {
28812897
$default = null;
28822898
}
@@ -2920,14 +2936,6 @@ public function updateAttribute(string $collection, string $id, ?string $type =
29202936
}
29212937
break;
29222938
case self::VAR_BIGINT:
2923-
$sizeString = BigIntValidator::normalizeUnsignedString((string)$size);
2924-
$limit = (!$signed && $this->adapter->getSupportForUnsignedBigInt())
2925-
? BigIntValidator::UNSIGNED_MAX
2926-
: BigIntValidator::SIGNED_MAX;
2927-
2928-
if (BigIntValidator::compareUnsignedStrings($sizeString, $limit) > 0) {
2929-
throw new DatabaseException('Max size allowed for bigint is: ' . BigIntValidator::formatIntegerString($limit));
2930-
}
29312939
break;
29322940
case self::VAR_FLOAT:
29332941
case self::VAR_BOOLEAN:
@@ -5599,8 +5607,8 @@ public function createDocument(string $collection, Document $document): Document
55995607
$this->adapter->getMinDateTime(),
56005608
$this->adapter->getMaxDateTime(),
56015609
$this->adapter->getSupportForAttributes(),
5602-
null,
5603-
$this->adapter->getSupportForUnsignedBigInt()
5610+
$this->adapter->getSupportForUnsignedBigInt(),
5611+
null
56045612
);
56055613
if (!$structure->isValid($document)) {
56065614
throw new StructureException($structure->getDescription());
@@ -5709,8 +5717,8 @@ public function createDocuments(
57095717
$this->adapter->getMinDateTime(),
57105718
$this->adapter->getMaxDateTime(),
57115719
$this->adapter->getSupportForAttributes(),
5712-
null,
5713-
$this->adapter->getSupportForUnsignedBigInt()
5720+
$this->adapter->getSupportForUnsignedBigInt(),
5721+
null
57145722
);
57155723
if (!$validator->isValid($document)) {
57165724
throw new StructureException($validator->getDescription());
@@ -6282,8 +6290,8 @@ public function updateDocument(string $collection, string $id, Document $documen
62826290
$this->adapter->getMinDateTime(),
62836291
$this->adapter->getMaxDateTime(),
62846292
$this->adapter->getSupportForAttributes(),
6285-
$old,
6286-
$this->adapter->getSupportForUnsignedBigInt()
6293+
$this->adapter->getSupportForUnsignedBigInt(),
6294+
$old
62876295
);
62886296
if (!$structureValidator->isValid($document)) { // Make sure updated structure still apply collection rules (if any)
62896297
throw new StructureException($structureValidator->getDescription());
@@ -7297,8 +7305,8 @@ public function upsertDocumentsWithIncrease(
72977305
$this->adapter->getMinDateTime(),
72987306
$this->adapter->getMaxDateTime(),
72997307
$this->adapter->getSupportForAttributes(),
7300-
$old->isEmpty() ? null : $old,
7301-
$this->adapter->getSupportForUnsignedBigInt()
7308+
$this->adapter->getSupportForUnsignedBigInt(),
7309+
$old->isEmpty() ? null : $old
73027310
);
73037311

73047312
if (!$validator->isValid($document)) {

src/Database/Validator/Attribute.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ public function __construct(
5555
protected bool $supportForVectors = false,
5656
protected bool $supportForSpatialAttributes = false,
5757
protected bool $supportForObject = false,
58+
protected bool $supportUnsignedBigInt = false,
5859
protected mixed $attributeCountCallback = null,
5960
protected mixed $attributeWidthCallback = null,
6061
protected mixed $filterCallback = null,
6162
protected bool $isMigrating = false,
6263
protected bool $sharedTables = false,
63-
protected bool $supportUnsignedBigInt = false,
6464
) {
6565
// Keep backwards compatibility for existing validator construction sites.
6666
if ($this->maxBigIntLength === 0) {

src/Database/Validator/Query/Filter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function __construct(
3232
private readonly int $maxValuesCount = 5000,
3333
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
3434
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
35-
private bool $supportForAttributes = true,
35+
private readonly bool $supportForAttributes = true,
3636
private readonly bool $supportUnsignedBigInt = true
3737
) {
3838
foreach ($attributes as $attribute) {

src/Database/Validator/Structure.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ public function __construct(
109109
private readonly \DateTime $minAllowedDate = new \DateTime('0000-01-01'),
110110
private readonly \DateTime $maxAllowedDate = new \DateTime('9999-12-31'),
111111
private bool $supportForAttributes = true,
112-
private readonly ?Document $currentDocument = null,
113-
private readonly bool $supportUnsignedBigInt = true
112+
private readonly bool $supportUnsignedBigInt = true,
113+
private readonly ?Document $currentDocument = null
114114
) {
115115
}
116116

@@ -340,7 +340,7 @@ protected function checkForInvalidAttributeValues(Document $document, array $str
340340
// BIGINT accepts both PHP int and numeric strings.
341341
// If the numeric string is within PHP's int range, normalize it to an int
342342
// so downstream code gets a numeric value without precision loss.
343-
if ($type === Database::VAR_BIGINT && \is_string($value) && $this->isBigIntStringWithinPhpIntRange($value, $signed)) {
343+
if ($type === Database::VAR_BIGINT && \is_string($value) && BigInt::fitsPhpInt($value, $signed)) {
344344
$normalized = (int)$value;
345345
$document->setAttribute($key, $normalized);
346346
$value = $normalized;
@@ -461,11 +461,6 @@ protected function checkForInvalidAttributeValues(Document $document, array $str
461461
return true;
462462
}
463463

464-
public function isBigIntStringWithinPhpIntRange(string $value, bool $signed): bool
465-
{
466-
return BigInt::fitsPhpInt($value, $signed);
467-
}
468-
469464
/**
470465
* Is array
471466
*

tests/e2e/Adapter/Scopes/AttributeTests.php

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,7 +2222,7 @@ public function testCreateAttributesIntegerSizeLimit(): void
22222222
}
22232223

22242224

2225-
public function testCreateAttributesBigIntIgnoresSizeLimit(): void
2225+
public function testCreateAttributesBigIntIgnoresSizeMetadata(): void
22262226
{
22272227
/** @var Database $database */
22282228
$database = $this->getDatabase();
@@ -2235,13 +2235,10 @@ public function testCreateAttributesBigIntIgnoresSizeLimit(): void
22352235
$collectionName = 'bigint_ignores_size_limit';
22362236
$database->createCollection($collectionName);
22372237

2238-
$limit = $database->getAdapter()->getLimitForBigInt() / 2;
2239-
$size = (int)$limit + 1;
2240-
22412238
$attributes = [[
22422239
'$id' => 'foo',
22432240
'type' => Database::VAR_BIGINT,
2244-
'size' => $size,
2241+
'size' => 9999,
22452242
'required' => false
22462243
]];
22472244

@@ -2252,10 +2249,10 @@ public function testCreateAttributesBigIntIgnoresSizeLimit(): void
22522249
$attrs = $collection->getAttribute('attributes');
22532250
$this->assertCount(1, $attrs);
22542251
$this->assertEquals('foo', $attrs[0]['$id']);
2255-
$this->assertEquals($size, $attrs[0]['size']);
2252+
$this->assertEquals(0, $attrs[0]['size']);
22562253
}
22572254

2258-
public function testCreateAttributesBigIntValidationSignedUnsignedAndSizeMetadata(): void
2255+
public function testCreateAttributesBigIntValidationSignedUnsignedAndMetadata(): void
22592256
{
22602257
/** @var Database $database */
22612258
$database = $this->getDatabase();
@@ -2301,18 +2298,6 @@ public function testCreateAttributesBigIntValidationSignedUnsignedAndSizeMetadat
23012298
$this->assertEquals(0, $signedAttribute['size']);
23022299
$this->assertEquals(0, $unsignedAttribute['size']);
23032300

2304-
// Signed overflow check (only when we can build an int beyond adapter signed max).
2305-
$signedLimit = (int)$database->getAdapter()->getLimitForBigInt();
2306-
if ($signedLimit < \PHP_INT_MAX) {
2307-
try {
2308-
$database->updateAttribute($collectionName, 'signed_bigint', size: $signedLimit + 1);
2309-
$this->fail('Expected DatabaseException for signed bigint size overflow');
2310-
} catch (\Throwable $e) {
2311-
$this->assertInstanceOf(DatabaseException::class, $e);
2312-
$this->assertStringContainsString('Max size allowed for bigint', $e->getMessage());
2313-
}
2314-
}
2315-
23162301
$largeUnsignedAttribute = [[
23172302
'$id' => 'unsigned_bigint_large',
23182303
'type' => Database::VAR_BIGINT,

0 commit comments

Comments
 (0)