Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,8 @@ public function createDocument(string $collection, Document $document): Document
throw new DatabaseException('Error creating document empty "$sequence"');
}

$document['$sequence'] = (int)$document['$sequence'];

if (isset($stmtPermissions)) {
$stmtPermissions->execute();
}
Expand Down Expand Up @@ -1640,7 +1642,7 @@ public function find(string $collection, array $queries = [], ?int $limit = 25,
unset($results[$index]['_uid']);
}
if (\array_key_exists('_id', $document)) {
$results[$index]['$sequence'] = $document['_id'];
$results[$index]['$sequence'] = (int)$document['_id'];
unset($results[$index]['_id']);
}
if (\array_key_exists('_tenant', $document)) {
Expand Down
3 changes: 2 additions & 1 deletion src/Database/Adapter/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ public function createDocument(string $collection, Document $document): Document
$lastInsertedId = $this->getPDO()->lastInsertId();
// Sequence can be manually set as well
$document['$sequence'] ??= $lastInsertedId;
$document['$sequence'] = (int)$document['$sequence'];

if (isset($stmtPermissions)) {
$this->execute($stmtPermissions);
Expand Down Expand Up @@ -1525,7 +1526,7 @@ public function find(string $collection, array $queries = [], ?int $limit = 25,
unset($results[$index]['_uid']);
}
if (\array_key_exists('_id', $document)) {
$results[$index]['$sequence'] = $document['_id'];
$results[$index]['$sequence'] = (int)$document['_id'];
unset($results[$index]['_id']);
}
if (\array_key_exists('_tenant', $document)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Database/Adapter/SQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public function getDocument(string $collection, string $id, array $queries = [],
$document = $document[0];

if (\array_key_exists('_id', $document)) {
$document['$sequence'] = $document['_id'];
$document['$sequence'] = (int)$document['_id'];
unset($document['_id']);
}
if (\array_key_exists('_uid', $document)) {
Expand Down
5 changes: 5 additions & 0 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -6507,6 +6507,11 @@ public function casting(Document $collection, Document $document): Document
case self::VAR_BOOLEAN:
$node = (bool)$node;
break;
case self::VAR_ID:
if ($this->adapter->getIdAttributeType() === 'int'){
$node = (int)$node;
}
break;
case self::VAR_INTEGER:
$node = (int)$node;
break;
Expand Down
6 changes: 3 additions & 3 deletions src/Database/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ public function getId(): string
}

/**
* @return string
* @return mixed
*/
public function getSequence(): string
public function getSequence(): mixed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider backward compatibility implications of the return type change.

The return type change from string to mixed could break existing code that expects a string value. This change allows the method to return integers, strings, or null, which aligns with the new VAR_SEQUENCE attribute type but may require updates to consuming code.

Consider documenting the possible return types and their meanings in the method's PHPDoc comment.


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of getSequence() method to assess backward compatibility impact
# Expected: Identify code that might assume string return type

echo "Searching for getSequence() method calls..."
rg -A 3 -B 1 "getSequence\(\)" --type php

echo -e "\nSearching for type-specific operations on sequence values..."
rg -A 2 -B 2 "->getSequence\(\)->" --type php
rg -A 2 -B 2 "strlen.*getSequence" --type php
rg -A 2 -B 2 "substr.*getSequence" --type php

Length of output: 14544


Refine getSequence() return type annotation and document nullability

The change from string to mixed is safe—no direct string-only operations were found (only concatenation and PDO binding, which handle int|string|null via PHP’s implicit casts). However, the method’s PHPDoc and signature can be more precise:

  • File: src/Database/Document.php (around the getSequence() declaration)
    • Update the @return tag from mixed to int|string|null
    • Document what each type means (e.g. integer for auto-increment adapters, string for UUIDs, null when unset)

Suggested diff:

     /**
-    * @return mixed
+    * @return int|string|null  Sequence value:
+    *                           - int:  auto-increment sequences
+    *                           - string: UUID or custom identifiers
+    *                           - null: when no sequence attribute is set
     */
-    public function getSequence(): mixed
+    public function getSequence(): int|string|null
🤖 Prompt for AI Agents
In src/Database/Document.php around lines 65 to 67, refine the getSequence()
method's PHPDoc and return type by changing the @return annotation from mixed to
int|string|null, and update the method signature to reflect this nullable union
type. Add documentation explaining that int represents auto-increment adapters,
string represents UUIDs, and null indicates the sequence is unset.

{
return $this->getAttribute('$sequence', '');
return $this->getAttribute('$sequence');
}

/**
Expand Down
11 changes: 6 additions & 5 deletions src/Database/Validator/Sequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ public function isValid($value): bool
return false;
}

if (gettype($value) !== 'string') {
return false;
}

if ($this->idAttributeType === 'string') {
return preg_match('/^[a-f0-9]{24}$/i', $value) === 1;
} elseif ($this->idAttributeType === 'int') {
$validator = new Integer(loose: true);

if (gettype($value) !== 'integer') {
return false;
}

$validator = new Integer();
if (!$validator->isValid($value)) {
return false;
}
Expand Down
31 changes: 15 additions & 16 deletions tests/e2e/Adapter/Scopes/DocumentTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function testCreateDocument(): Document
'colors' => ['pink', 'green', 'blue'],
'empty' => [],
'with-dash' => 'Works',
'id' => '1000000',
'id' => 1000000,
]));

$this->assertNotEmpty(true, $document->getId());
Expand All @@ -91,13 +91,13 @@ public function testCreateDocument(): Document
$this->assertEquals(['pink', 'green', 'blue'], $document->getAttribute('colors'));
$this->assertEquals([], $document->getAttribute('empty'));
$this->assertEquals('Works', $document->getAttribute('with-dash'));
$this->assertIsString($document->getAttribute('id'));
$this->assertEquals('1000000', $document->getAttribute('id'));
$this->assertIsInt($document->getAttribute('id'));
$this->assertEquals(1000000, $document->getAttribute('id'));

// Test create document with manual internal id
$manualIdDocument = $database->createDocument('documents', new Document([
'$id' => '56000',
'$sequence' => '56000',
'$sequence' => 56000,
'$permissions' => [
Permission::read(Role::any()),
Permission::read(Role::user(ID::custom('1'))),
Expand Down Expand Up @@ -214,7 +214,7 @@ public function testCreateDocument(): Document

try {
$database->createDocument('documents', new Document([
'$sequence' => '0',
'$sequence' => 0,
'$permissions' => [],
'string' => '',
'integer_signed' => 1,
Expand Down Expand Up @@ -270,7 +270,7 @@ public function testCreateDocument(): Document
* Insert ID attribute with '0'
*/
$documentId0 = $database->createDocument('documents', new Document([
'id' => '0',
'id' => 0,
'$permissions' => [Permission::read(Role::any())],
'string' => '',
'integer_signed' => 1,
Expand All @@ -285,21 +285,20 @@ public function testCreateDocument(): Document
'with-dash' => '',
]));
$this->assertNotEmpty(true, $documentId0->getSequence());
$this->assertIsString($documentId0->getAttribute('id'));
$this->assertEquals('0', $documentId0->getAttribute('id'));
$this->assertIsInt($documentId0->getAttribute('id'));
$this->assertEquals(0, $documentId0->getAttribute('id'));

$documentId0 = $database->getDocument('documents', $documentId0->getId());
$this->assertNotEmpty(true, $documentId0->getSequence());
$this->assertIsString($documentId0->getAttribute('id'));
$this->assertEquals('0', $documentId0->getAttribute('id'));
$this->assertIsInt($documentId0->getAttribute('id'));
$this->assertEquals(0, $documentId0->getAttribute('id'));

$documentId0 = $database->findOne('documents', [
query::equal('id', ['0'])
query::equal('id', [0])
]);
$this->assertNotEmpty(true, $documentId0->getSequence());
$this->assertIsString($documentId0->getAttribute('id'));
$this->assertEquals('0', $documentId0->getAttribute('id'));

$this->assertIsInt($documentId0->getAttribute('id'));
$this->assertEquals(0, $documentId0->getAttribute('id'));

return $document;
}
Expand Down Expand Up @@ -386,7 +385,7 @@ public function testCreateDocumentsWithAutoIncrement(): void

for ($i = $sequence; $i <= ($sequence + $count); $i++) {
$documents[] = new Document([
'$sequence' => (string)$i,
'$sequence' => $i,
'$permissions' => [
Permission::read(Role::any()),
Permission::create(Role::any()),
Expand Down Expand Up @@ -4371,7 +4370,7 @@ public function testExceptionCaseInsensitiveDuplicate(Document $document): Docum
$database = static::getDatabase();

$document->setAttribute('$id', 'caseSensitive');
$document->setAttribute('$sequence', '200');
$document->setAttribute('$sequence', 200);
$database->createDocument($document->getCollection(), $document);

$document->setAttribute('$id', 'CaseSensitive');
Expand Down
Loading