Skip to content

Conversation

@abnegate
Copy link
Member

@abnegate abnegate commented Jan 16, 2026

Summary by CodeRabbit

  • New Features

    • Adds support for VARCHAR, TEXT, MEDIUMTEXT and LONGTEXT types across database backends.
  • Validation

    • Centralized attribute validation updated to enforce sizes, defaults, index/fulltext rules and type compatibility for the new text types.
  • Indexing

    • Index and fulltext validation expanded to accept the new text-like types where applicable.
  • Tests

    • Extensive unit and end-to-end tests added to cover new types, arrays, defaults, size limits, and indexing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2026

Warning

Rate limit exceeded

@abnegate has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 428be5e and becf445.

📒 Files selected for processing (1)
  • src/Database/Adapter/MariaDB.php
📝 Walkthrough

Walkthrough

Introduces four string-like attribute types (VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, VAR_LONGTEXT), centralizes attribute validation via a new Attribute validator, updates adapters and width calculations to support the types, broadens validators/index/query rules, and adds tests.

Changes

Cohort / File(s) Summary
Database core & type constants
src/Database/Database.php
Adds public constants for VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, VAR_LONGTEXT and replaces inline attribute validation with an AttributeValidator-driven flow.
New Attribute validator
src/Database/Validator/Attribute.php
New validator class that centralizes duplicate checks, required-filters, format, limits, type constraints, and default-value validation; public API added for validator methods.
Adapters: type mappings & adapter surface
src/Database/Adapter/MariaDB.php, src/Database/Adapter/Postgres.php, src/Database/Adapter/Mongo.php, src/Database/Adapter.php, src/Database/Adapter/Pool.php
Maps new varchar/text variants to SQL or 'string' (Mongo), extends error messages; adds abstract/getter getMaxVarcharLength() to Adapter and delegates in Pool.
SQL width calculation
src/Database/Adapter/SQL.php
getAttributeWidth updated to include VAR_VARCHAR (size-aware) and TEXT/MEDIUMTEXT/LONGTEXT (treated as pointer-stored fixed contribution).
Validators: index/structure/query
src/Database/Validator/Index.php, src/Database/Validator/Structure.php, src/Database/Validator/Query/Filter.php
Broadens accepted string-like types for fulltext/trigram/index length checks and routes new types to Text validator for value validation.
Tests: e2e & unit coverage
tests/e2e/Adapter/Scopes/AttributeTests.php, tests/unit/Validator/AttributeTest.php, tests/unit/Validator/StructureTest.php
Adds extensive tests for VARCHAR/TEXT/MEDIUMTEXT/LONGTEXT covering creation, defaults, arrays, index behavior, limits, and validator error messages.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client
participant Database
participant AttributeValidator
participant Adapter
Client->>Database: createAttribute(request)
Database->>Database: clone collection + append attribute
Database->>AttributeValidator: instantiate with callbacks/config
AttributeValidator->>AttributeValidator: run checks (duplicates, filters, format, limits, type, default)
AttributeValidator-->>Database: validation result / throws
Database->>Adapter: persist schema change / map SQL type
Adapter-->>Database: ack / SQL emitted
Database-->>Client: createAttribute response

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ArnabChatterjee20k
  • fogelito

Poem

🐰 I hopped through types both short and long,
VAR_VARCHAR, TEXT — a stringy song,
A validator stitched each rule so neat,
Adapters hum and make each mapping meet,
Now attributes hop safe down every lane.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Add more string types" accurately summarizes the main objective of the pull request, which is to introduce support for additional string-based attribute types (VARCHAR, TEXT, MEDIUMTEXT, LONGTEXT) across the database adapter layer.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/Database/Adapter/MariaDB.php`:
- Line 1719: The thrown DatabaseException message concatenates an extra literal
"', ' . ', '" causing a double comma before Database::VAR_POINT; update the
construction in the throw in MariaDB.php (the DatabaseException(...) line) to
remove the stray "', ' . ', '" and ensure the list of constants
(Database::VAR_STRING, VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, VAR_LONGTEXT,
VAR_INTEGER, VAR_FLOAT, VAR_BOOLEAN, VAR_DATETIME, VAR_RELATIONSHIP,
Database::VAR_POINT, Database::VAR_LINESTRING, Database::VAR_POLYGON) are
concatenated with a single ", " separator so the message prints correctly.

In `@src/Database/Database.php`:
- Around line 2278-2280: In validateAttribute(), don't ignore
$validator->isValid($attribute); instead check its boolean result and when false
retrieve the validator messages (e.g. $validator->getMessages()) and surface
them by throwing the same exception type used by other validators in this file
(or returning a failure consistent with the file's pattern), so include the
collected messages in the exception/error so callers see why validation failed;
reference validateAttribute(), $validator and isValid() to locate the code to
change.

In `@src/Database/Validator/Attribute.php`:
- Around line 451-469: The schema validator currently allows array defaults for
attributes not declared as arrays; update the checkDefaultValue method (in class
Attribute, function checkDefaultValue) to reject array defaults when the
attribute is not an array: detect when $default is an array (is_array($default))
and the attribute is not marked as an array (check $type !== 'array' and/or
$attribute->getAttribute('array', false) !== true), then set an appropriate
$this->message and throw DatabaseException; keep the existing required-check and
call to validateDefaultTypes for non-array cases.

In `@tests/e2e/Adapter/Scopes/AttributeTests.php`:
- Around line 2315-2347: Wrap the two size-violation blocks (the VARCHAR and
TEXT createDocument tests) in a guard that checks the adapter's attribute
support (use $this->adapter->getSupportForAttributes()); only run the try/catch
+ assertInstanceOf(StructureException::class, $e) when that returns true,
otherwise skip those assertions (mirror the existing gating pattern elsewhere in
AttributeTests.php). Locate the blocks that create documents with
'varchar_field' and 'text_field' and conditionally execute them based on
$this->adapter->getSupportForAttributes().
🧹 Nitpick comments (1)
tests/unit/Validator/StructureTest.php (1)

1076-1136: Consider exercising text_array too.
text_array is defined but never asserted; adding a couple of cases would cover VAR_TEXT arrays.

🧪 Suggested test additions for text_array
@@
         $this->assertEquals(true, $validator->isValid(new Document([
             '$collection' => ID::custom('posts'),
             'varchar_array' => ['test1', 'test2', 'test3'],
             '$createdAt' => '2000-04-01T12:00:00.000+00:00',
             '$updatedAt' => '2000-04-01T12:00:00.000+00:00'
         ])));
+
+        $this->assertEquals(true, $validator->isValid(new Document([
+            '$collection' => ID::custom('posts'),
+            'text_array' => ['alpha', 'beta'],
+            '$createdAt' => '2000-04-01T12:00:00.000+00:00',
+            '$updatedAt' => '2000-04-01T12:00:00.000+00:00'
+        ])));
@@
         $this->assertEquals('Invalid document structure: Attribute "varchar_array[\'0\']" has invalid type. Value must be a valid string and no longer than 128 chars', $validator->getDescription());
+
+        $this->assertEquals(false, $validator->isValid(new Document([
+            '$collection' => ID::custom('posts'),
+            'text_array' => [123],
+            '$createdAt' => '2000-04-01T12:00:00.000+00:00',
+            '$updatedAt' => '2000-04-01T12:00:00.000+00:00'
+        ])));
+
+        $this->assertEquals('Invalid document structure: Attribute "text_array[\'0\']" has invalid type. Value must be a valid string and no longer than 65535 chars', $validator->getDescription());
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e6a033 and 329eb9e.

📒 Files selected for processing (11)
  • src/Database/Adapter/MariaDB.php
  • src/Database/Adapter/Mongo.php
  • src/Database/Adapter/Postgres.php
  • src/Database/Adapter/SQL.php
  • src/Database/Database.php
  • src/Database/Validator/Attribute.php
  • src/Database/Validator/Index.php
  • src/Database/Validator/Structure.php
  • tests/e2e/Adapter/Scopes/AttributeTests.php
  • tests/unit/Validator/AttributeTest.php
  • tests/unit/Validator/StructureTest.php
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-03T02:04:17.803Z
Learnt from: abnegate
Repo: utopia-php/database PR: 721
File: tests/e2e/Adapter/Scopes/DocumentTests.php:6418-6439
Timestamp: 2025-10-03T02:04:17.803Z
Learning: In tests/e2e/Adapter/Scopes/DocumentTests::testSchemalessDocumentInvalidInteralAttributeValidation (PHP), when the adapter reports getSupportForAttributes() === false (schemaless), the test should not expect exceptions from createDocuments for “invalid” internal attributes; remove try/catch and ensure the test passes without exceptions, keeping at least one assertion.

Applied to files:

  • tests/unit/Validator/AttributeTest.php
  • src/Database/Adapter/Mongo.php
  • tests/unit/Validator/StructureTest.php
  • src/Database/Database.php
  • tests/e2e/Adapter/Scopes/AttributeTests.php
  • src/Database/Validator/Attribute.php
📚 Learning: 2025-07-30T19:17:53.630Z
Learnt from: ArnabChatterjee20k
Repo: utopia-php/database PR: 642
File: src/Database/Validator/PartialStructure.php:43-52
Timestamp: 2025-07-30T19:17:53.630Z
Learning: In PartialStructure validator, when filtering for required attributes validation using the $requiredAttributes parameter, $this->attributes should be used instead of the merged $attributes array because this validation is specifically for internal attributes like $createdAt and $updatedAt that are defined in the base Structure class, not collection-specific attributes.

Applied to files:

  • tests/unit/Validator/AttributeTest.php
  • tests/unit/Validator/StructureTest.php
  • src/Database/Database.php
  • src/Database/Validator/Attribute.php
📚 Learning: 2025-10-29T12:27:57.071Z
Learnt from: ArnabChatterjee20k
Repo: utopia-php/database PR: 747
File: src/Database/Adapter/Mongo.php:1449-1453
Timestamp: 2025-10-29T12:27:57.071Z
Learning: In src/Database/Adapter/Mongo.php, when getSupportForAttributes() returns false (schemaless mode), the updateDocument method intentionally uses a raw document without $set operator for replacement-style updates, as confirmed by the repository maintainer ArnabChatterjee20k.

Applied to files:

  • src/Database/Adapter/Mongo.php
📚 Learning: 2025-10-16T08:48:36.715Z
Learnt from: fogelito
Repo: utopia-php/database PR: 739
File: src/Database/Adapter/Postgres.php:154-158
Timestamp: 2025-10-16T08:48:36.715Z
Learning: For the utopia-php/database repository, no migration scripts are needed for the collation change from utf8_ci to utf8_ci_ai in the Postgres adapter because there is no existing production data.

Applied to files:

  • src/Database/Adapter/Postgres.php
🧬 Code graph analysis (10)
src/Database/Adapter/SQL.php (1)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Adapter/MariaDB.php (2)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Adapter/SQL.php (1)
  • getMaxVarcharLength (2224-2227)
tests/unit/Validator/AttributeTest.php (1)
src/Database/Validator/Attribute.php (1)
  • Attribute (12-554)
src/Database/Adapter/Mongo.php (1)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Validator/Index.php (2)
src/Database/Query.php (1)
  • getAttribute (182-185)
src/Database/Database.php (1)
  • Database (40-9363)
tests/unit/Validator/StructureTest.php (1)
src/Database/Validator/Structure.php (2)
  • Structure (20-472)
  • getDescription (197-200)
src/Database/Database.php (1)
src/Database/Validator/Attribute.php (1)
  • Attribute (12-554)
src/Database/Adapter/Postgres.php (1)
src/Database/Database.php (1)
  • Database (40-9363)
tests/e2e/Adapter/Scopes/AttributeTests.php (1)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Validator/Attribute.php (5)
src/Database/Database.php (2)
  • Database (40-9363)
  • __construct (455-685)
src/Database/Exception.php (1)
  • Exception (7-21)
src/Database/Validator/Structure.php (2)
  • __construct (106-114)
  • Structure (20-472)
src/Database/Document.php (1)
  • getId (63-66)
src/Database/Query.php (1)
  • limit (656-659)
🪛 GitHub Actions: CodeQL
src/Database/Database.php

[error] 2266-2266: PHPStan analysis failed. Command: ./vendor/bin/phpstan analyse --level 7 src tests --memory-limit 2G. Error: Call to an undefined method Utopia\Database\Adapter::getMaxVarcharLength().

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Setup & Build Docker Image
🔇 Additional comments (56)
src/Database/Validator/Structure.php (1)

346-352: LGTM!

The new string type variants (VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, VAR_LONGTEXT) correctly fall through to use the Text validator with size constraints, maintaining consistency with the existing VAR_STRING handling.

src/Database/Adapter/Mongo.php (1)

2070-2073: LGTM!

The new string type variants correctly map to MongoDB's 'string' BSON type, maintaining consistency with VAR_STRING handling. This ensures proper partial filter expressions for indexes.

src/Database/Adapter/MariaDB.php (1)

1681-1694: LGTM!

The explicit mappings for VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, and VAR_LONGTEXT provide precise control over SQL column types. The VAR_VARCHAR validation with a helpful exception message guides developers toward appropriate alternatives when size limits are exceeded.

src/Database/Adapter/Postgres.php (2)

1925-1932: Postgres mapping for new string variants is solid.

The VARCHAR/TEXT mappings align with PostgreSQL’s supported types.


1969-1969: Error message list is now consistent with new types.

Good to see the expanded string variants reflected in the allowed-types message.

src/Database/Adapter/SQL.php (1)

1147-1158: Row-width estimation now covers the new string variants.

This keeps size accounting aligned with the updated type set.

src/Database/Validator/Index.php (4)

292-302: Fulltext validation now recognizes the new string-like types.

Looks aligned with the expanded type set.


355-361: Array/index length rules now cover VARCHAR/TEXT variants.

Good consistency with the updated string type list.


395-399: Index length handling expanded appropriately.

String-like variants are now validated consistently.


597-608: Trigram validation now supports the full string-like set.

Matches the new string type coverage.

tests/unit/Validator/AttributeTest.php (27)

16-52: Covers duplicate attribute detection.


54-76: Happy-path string attribute validation is covered.


78-102: String size boundary validation is well covered.


104-128: Varchar size limit enforcement is covered.


130-154: Text size limit assertion is covered.


156-180: Mediumtext size limit assertion is covered.


182-206: Integer size limit (signed) behavior is covered.


208-232: Unknown type handling is covered.


234-258: Datetime required-filter enforcement is covered.


260-282: Valid datetime with required filter is covered.


284-308: Default value restriction for required attributes is covered.


310-334: Default value type mismatch is covered.


336-361: Vector unsupported-path validation is covered.


363-388: Vector array rejection is covered.


390-415: Vector minimum-dimension validation is covered.


417-442: Vector maximum-dimension validation is covered.


444-469: Spatial unsupported-path validation is covered.


471-496: Spatial array restriction is covered.


498-523: Spatial size constraint is covered.


525-550: Object unsupported-path validation is covered.


552-577: Object array restriction is covered.


579-604: Object size constraint is covered.


606-634: Attribute-count limit enforcement is covered.


636-664: Row-width limit enforcement is covered.


666-691: Vector default type validation is covered.


693-718: Vector default length validation is covered.


720-745: Vector default numeric-element validation is covered.

tests/e2e/Adapter/Scopes/AttributeTests.php (2)

55-66: Nice coverage for new string defaults.

These additions align with the new string types and expand invalid-default coverage appropriately.


87-178: Updates to create/delete flows look consistent.

The new attribute/index/list/default additions and updated counts align with the expanded string types.

src/Database/Database.php (3)

28-52: New validator import + string-type constants look good.

This aligns cleanly with the added string-type support.


2328-2362: Default-type validation updates are consistent.

The new string variants are correctly treated as string defaults.


2258-2267: Mongo adapter is missing getMaxVarcharLength() implementation.

The method is defined in the SQL adapter but not in the base Adapter contract or the Mongo adapter. When Database.php line 2266 calls $this->adapter->getMaxVarcharLength() with a Mongo adapter instance, it will cause a fatal error at runtime. Add the method to the Adapter base class (as abstract) and implement it in all concrete adapters, or provide a safe fallback with a default value.

⛔ Skipped due to learnings
Learnt from: abnegate
Repo: utopia-php/database PR: 721
File: tests/e2e/Adapter/Scopes/AttributeTests.php:1329-1334
Timestamp: 2025-10-03T01:50:11.943Z
Learning: MongoDB has a 1024kb (1,048,576 bytes) limit for index entries. The MongoDB adapter's getMaxIndexLength() method should return this limit rather than 0.
Learnt from: abnegate
Repo: utopia-php/database PR: 721
File: tests/e2e/Adapter/Scopes/DocumentTests.php:6418-6439
Timestamp: 2025-10-03T02:04:17.803Z
Learning: In tests/e2e/Adapter/Scopes/DocumentTests::testSchemalessDocumentInvalidInteralAttributeValidation (PHP), when the adapter reports getSupportForAttributes() === false (schemaless), the test should not expect exceptions from createDocuments for “invalid” internal attributes; remove try/catch and ensure the test passes without exceptions, keeping at least one assertion.
Learnt from: ArnabChatterjee20k
Repo: utopia-php/database PR: 642
File: src/Database/Validator/PartialStructure.php:43-52
Timestamp: 2025-07-30T19:17:53.630Z
Learning: In PartialStructure validator, when filtering for required attributes validation using the $requiredAttributes parameter, $this->attributes should be used instead of the merged $attributes array because this validation is specifically for internal attributes like $createdAt and $updatedAt that are defined in the base Structure class, not collection-specific attributes.
tests/unit/Validator/StructureTest.php (5)

104-143: String-type fixture attributes look good.
Sizes align with expected VARCHAR/TEXT limits and stay optional.


892-944: Varchar validation coverage is solid.
Covers valid input, type mismatch, and boundary length.


946-998: Text validation coverage looks good.


1000-1036: Mediumtext validation test is clear.


1038-1074: Longtext validation test is clear.

src/Database/Validator/Attribute.php (9)

44-70: Constructor normalization is solid.
Lowercasing keys upfront helps avoid case-sensitive collisions.


72-103: Accessor methods are straightforward.


105-140: Validation pipeline is clear and ordered.


142-191: Duplicate checks read well and are case-insensitive.


193-227: Required-filter handling is concise.


229-247: Format validation looks correct.


249-276: Limit enforcement via callbacks is fine.


480-553: The original review comment is based on an incorrect assumption and can be closed.

Database::VAR_FLOAT is defined as 'double' (not 'float'), which perfectly matches what PHP's gettype() returns for float values. The current validation logic at lines 525-528 will correctly accept valid float defaults without modification.

case Database::VAR_FLOAT:
    if ($type !== $defaultType) {  // 'double' === 'double' ✓

No fix is required.

Likely an incorrect or invalid review comment.


278-439: Consider adding non-zero guards or documenting that max limits must be provided.

The max* properties (maxStringLength, maxVarcharLength, maxIntLength) default to 0, which renders validation ineffective—validation checks like if ($size > $this->maxStringLength) would skip for any positive size. While the current production code (Database.php) always passes values from adapter methods, the design allows unsafe instantiation without explicit limits. Either add > 0 checks to enforce validation or document that callers must provide non-zero limits.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Database/Validator/Query/Filter.php (1)

257-267: Missing new string types in contains/notContains validation check.

The condition at line 260 only allows contains/notContains queries on VAR_STRING attributes (for non-array types), but the new string types (VAR_VARCHAR, VAR_TEXT, VAR_MEDIUMTEXT, VAR_LONGTEXT) are not included. This would incorrectly reject contains queries on these text-like attributes.

🐛 Proposed fix
         if (
             !$array &&
             in_array($method, [Query::TYPE_CONTAINS, Query::TYPE_NOT_CONTAINS]) &&
             $attributeSchema['type'] !== Database::VAR_STRING &&
+            $attributeSchema['type'] !== Database::VAR_VARCHAR &&
+            $attributeSchema['type'] !== Database::VAR_TEXT &&
+            $attributeSchema['type'] !== Database::VAR_MEDIUMTEXT &&
+            $attributeSchema['type'] !== Database::VAR_LONGTEXT &&
             $attributeSchema['type'] !== Database::VAR_OBJECT &&
             !in_array($attributeSchema['type'], Database::SPATIAL_TYPES)
         ) {

Alternatively, consider defining a STRING_TYPES constant in Database.php (similar to SPATIAL_TYPES) to centralize string-like type checks:

         if (
             !$array &&
             in_array($method, [Query::TYPE_CONTAINS, Query::TYPE_NOT_CONTAINS]) &&
-            $attributeSchema['type'] !== Database::VAR_STRING &&
+            !in_array($attributeSchema['type'], Database::STRING_TYPES, true) &&
             $attributeSchema['type'] !== Database::VAR_OBJECT &&
             !in_array($attributeSchema['type'], Database::SPATIAL_TYPES)
         ) {
🤖 Fix all issues with AI agents
In `@src/Database/Adapter/MariaDB.php`:
- Around line 1681-1686: The VARCHAR branch in the case Database::VAR_VARCHAR in
MariaDB.php currently only checks upper bounds; add an explicit lower-bound
check to ensure $size is > 0 and throw a DatabaseException if not (similar
format to the existing exception, e.g., "VARCHAR size X is invalid; must be > 0.
Use TEXT, MEDIUMTEXT, or LONGTEXT instead."), keeping the existing
getMaxVarcharLength() check intact and returning "VARCHAR({$size})" only after
both validations pass.

In `@tests/e2e/Adapter/Scopes/AttributeTests.php`:
- Around line 2242-2374: The testStringTypeAttributes method creates the
'stringTypes' collection but never removes it, causing test pollution; wrap the
test body in a try/finally (or add cleanup at the end) and call
$database->deleteCollection('stringTypes') in the finally block (or after
assertions) to ensure the collection is removed even on failures—locate the code
inside testStringTypeAttributes and add the cleanup around the existing
createCollection / createDocument / assertions using the
Database::deleteCollection (or $database->deleteCollection) call.
🧹 Nitpick comments (2)
src/Database/Adapter/Mongo.php (1)

2701-2710: Avoid duplicated limits for VARCHAR.
Consider delegating to getLimitForString() to keep limits in sync.

♻️ Proposed refactor
     public function getMaxVarcharLength(): int
     {
-        return 2147483647;
+        return $this->getLimitForString();
     }
src/Database/Validator/Attribute.php (1)

538-559: Missing handling for VAR_ID in default value validation.

The supportedTypes list in the default case includes VAR_RELATIONSHIP but not VAR_ID. Additionally, neither type has a switch case. If a default value is ever set on these attribute types, the error message would be confusing (especially for VAR_RELATIONSHIP which would say "Unknown attribute type" while listing it as supported).

Consider adding explicit cases or ensuring the supportedTypes list is consistent with what's actually handled.

♻️ Suggested handling
+            case Database::VAR_ID:
+            case Database::VAR_RELATIONSHIP:
+                if ($defaultType !== 'string') {
+                    $this->message = 'Default value ' . $default . ' does not match given type ' . $type;
+                    throw new DatabaseException($this->message);
+                }
+                break;
             default:
                 $supportedTypes = [
                     Database::VAR_STRING,
                     Database::VAR_VARCHAR,
                     Database::VAR_TEXT,
                     Database::VAR_MEDIUMTEXT,
                     Database::VAR_LONGTEXT,
                     Database::VAR_INTEGER,
                     Database::VAR_FLOAT,
                     Database::VAR_BOOLEAN,
                     Database::VAR_DATETIME,
-                    Database::VAR_RELATIONSHIP
+                    Database::VAR_RELATIONSHIP,
+                    Database::VAR_ID
                 ];
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 329eb9e and aeebd69.

📒 Files selected for processing (6)
  • src/Database/Adapter/MariaDB.php
  • src/Database/Adapter/Mongo.php
  • src/Database/Validator/Attribute.php
  • src/Database/Validator/Query/Filter.php
  • tests/e2e/Adapter/Scopes/AttributeTests.php
  • tests/unit/Validator/AttributeTest.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/Validator/AttributeTest.php
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-10-03T02:04:17.803Z
Learnt from: abnegate
Repo: utopia-php/database PR: 721
File: tests/e2e/Adapter/Scopes/DocumentTests.php:6418-6439
Timestamp: 2025-10-03T02:04:17.803Z
Learning: In tests/e2e/Adapter/Scopes/DocumentTests::testSchemalessDocumentInvalidInteralAttributeValidation (PHP), when the adapter reports getSupportForAttributes() === false (schemaless), the test should not expect exceptions from createDocuments for “invalid” internal attributes; remove try/catch and ensure the test passes without exceptions, keeping at least one assertion.

Applied to files:

  • tests/e2e/Adapter/Scopes/AttributeTests.php
  • src/Database/Validator/Attribute.php
📚 Learning: 2025-10-16T09:37:33.531Z
Learnt from: fogelito
Repo: utopia-php/database PR: 733
File: src/Database/Adapter/MariaDB.php:1801-1806
Timestamp: 2025-10-16T09:37:33.531Z
Learning: In the MariaDB adapter (src/Database/Adapter/MariaDB.php), only duplicate `_uid` violations should throw `DuplicateException`. All other unique constraint violations, including `PRIMARY` key collisions on the internal `_id` field, should throw `UniqueException`. This is the intended design to distinguish between user-facing document duplicates and internal/user-defined unique constraint violations.

Applied to files:

  • tests/e2e/Adapter/Scopes/AttributeTests.php
  • src/Database/Adapter/MariaDB.php
📚 Learning: 2025-10-03T01:50:11.943Z
Learnt from: abnegate
Repo: utopia-php/database PR: 721
File: tests/e2e/Adapter/Scopes/AttributeTests.php:1329-1334
Timestamp: 2025-10-03T01:50:11.943Z
Learning: MongoDB has a 1024kb (1,048,576 bytes) limit for index entries. The MongoDB adapter's getMaxIndexLength() method should return this limit rather than 0.

Applied to files:

  • src/Database/Adapter/Mongo.php
📚 Learning: 2025-10-29T12:27:57.071Z
Learnt from: ArnabChatterjee20k
Repo: utopia-php/database PR: 747
File: src/Database/Adapter/Mongo.php:1449-1453
Timestamp: 2025-10-29T12:27:57.071Z
Learning: In src/Database/Adapter/Mongo.php, when getSupportForAttributes() returns false (schemaless mode), the updateDocument method intentionally uses a raw document without $set operator for replacement-style updates, as confirmed by the repository maintainer ArnabChatterjee20k.

Applied to files:

  • src/Database/Adapter/Mongo.php
📚 Learning: 2025-07-30T19:17:53.630Z
Learnt from: ArnabChatterjee20k
Repo: utopia-php/database PR: 642
File: src/Database/Validator/PartialStructure.php:43-52
Timestamp: 2025-07-30T19:17:53.630Z
Learning: In PartialStructure validator, when filtering for required attributes validation using the $requiredAttributes parameter, $this->attributes should be used instead of the merged $attributes array because this validation is specifically for internal attributes like $createdAt and $updatedAt that are defined in the base Structure class, not collection-specific attributes.

Applied to files:

  • src/Database/Validator/Attribute.php
🧬 Code graph analysis (4)
src/Database/Validator/Query/Filter.php (1)
src/Database/Database.php (1)
  • Database (40-9363)
tests/e2e/Adapter/Scopes/AttributeTests.php (2)
src/Database/Database.php (3)
  • Database (40-9363)
  • createAttribute (2014-2084)
  • create (1507-1530)
src/Database/Adapter/SQL.php (1)
  • createAttribute (246-260)
src/Database/Adapter/Mongo.php (2)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Adapter/SQL.php (1)
  • getMaxVarcharLength (2224-2227)
src/Database/Adapter/MariaDB.php (3)
src/Database/Database.php (1)
  • Database (40-9363)
src/Database/Adapter/Mongo.php (1)
  • getMaxVarcharLength (2707-2710)
src/Database/Adapter/SQL.php (1)
  • getMaxVarcharLength (2224-2227)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Adapter Tests (Schemaless/MongoDB)
  • GitHub Check: Adapter Tests (SharedTables/Postgres)
  • GitHub Check: Adapter Tests (SharedTables/SQLite)
  • GitHub Check: Adapter Tests (SharedTables/MySQL)
  • GitHub Check: Adapter Tests (Mirror)
  • GitHub Check: Adapter Tests (Pool)
  • GitHub Check: Adapter Tests (SharedTables/MongoDB)
  • GitHub Check: Adapter Tests (MongoDB)
  • GitHub Check: Adapter Tests (SharedTables/MariaDB)
  • GitHub Check: Adapter Tests (Postgres)
  • GitHub Check: Adapter Tests (MariaDB)
  • GitHub Check: Adapter Tests (SQLite)
  • GitHub Check: Adapter Tests (MySQL)
  • GitHub Check: Unit Test
🔇 Additional comments (10)
src/Database/Adapter/MariaDB.php (1)

1719-1719: Unknown-type message updated for new string variants.

src/Database/Adapter/Mongo.php (1)

2068-2073: Type mapping for new string variants looks good.

tests/e2e/Adapter/Scopes/AttributeTests.php (2)

55-66: Invalid-default matrix now covers new string types.


87-175: Create/delete coverage updated consistently for new string types.
Counts and index coverage appear aligned with the new attributes.

src/Database/Validator/Attribute.php (5)

44-70: Well-structured constructor with comprehensive configuration options.

The constructor properly indexes attributes by lowercased key for case-insensitive lookups, which aligns with the duplicate checking logic. The promoted properties pattern keeps the code clean.


115-140: Clean validation orchestration.

The isValid method provides a clear sequence of validation steps with early returns on failure. The order is logical: duplicates → filters → format → limits → type → defaults.


304-330: New string type size limits are correctly implemented.

The size limits match the MySQL storage limits:

  • VARCHAR: uses configurable maxVarcharLength
  • TEXT: 65,535 bytes (2^16 - 1)
  • MEDIUMTEXT: 16,777,215 bytes (2^24 - 1)
  • LONGTEXT: 4,294,967,295 bytes (2^32 - 1)

451-476: Array default validation for non-array attributes is now properly handled.

The fix at lines 467-471 correctly rejects array defaults for non-array attributes while appropriately excluding VAR_VECTOR and spatial types which use arrays internally for their data representation.


506-516: Correct grouping of string-like types for default validation.

All new string types (VARCHAR, TEXT, MEDIUMTEXT, LONGTEXT) are properly grouped with VAR_STRING to validate that default values are strings.

src/Database/Validator/Query/Filter.php (1)

144-150: Correct addition of new string types to the validation switch.

All new string-like types are appropriately routed to the Text validator, consistent with how VAR_STRING is handled.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

abnegate and others added 2 commits January 16, 2026 21:35
Object types use arrays internally (like vectors and spatial types),
so they should be allowed to have array default values.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add the abstract method to the base Adapter class and implement
it in the Pool adapter to fix PHPStan errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Throws DatabaseException when VARCHAR size is <= 0, ensuring both lower
and upper bounds are validated before returning the VARCHAR type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@abnegate abnegate merged commit b5c16ca into main Jan 16, 2026
18 checks passed
@abnegate abnegate deleted the feat-string-types branch January 16, 2026 12:35
@abnegate abnegate restored the feat-string-types branch January 16, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants