Skip to content

Conversation

@abnegate
Copy link
Member

@abnegate abnegate commented Oct 30, 2025

Summary by CodeRabbit

  • New Features

    • Added a seed option to the operators benchmark task to pre-populate collections and display seeded document counts in results.
  • Improvements

    • Operator handling revamped to detect and validate operators inline, improving update/refetch behavior.
    • Operator validation now provides clearer, more descriptive error messages and wider validation coverage.
    • Structure validation updated to support operator-aware validation during updates.
  • Tests

    • Expanded unit tests for operator and structure validation covering many edge cases.
  • Chores

    • CI workflow images updated for analysis and linting steps.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

Walkthrough

Adds a CLI --seed parameter and seeding workflow to the operators benchmark; refactors operator handling to detect and validate operators on-the-fly during updates; passes historical/old document context into Structure/PartialStructure validators; improves operator parsing/error messages; and adds unit tests and CI workflow image updates.

Changes

Cohort / File(s) Summary
Benchmark CLI & seeding
bin/tasks/operators.php
Added --seed CLI param and extended task action signature to accept $seed; threaded $seed through setupTestEnvironment and displayResults; added seedDocuments() helper to batch-insert seed documents; added seed-related logging and results column.
Database operator handling
src/Database/Database.php
Replaced precomputed operator extraction with on-the-fly operator detection (hasOperators checks); refactored update/upsert flows to drive refetch/validation based on detected operators; adjusted casting behavior to avoid re-adding operator values; call sites updated to pass historical $old where appropriate.
Validator constructor context
src/Database/Validator/Structure.php, src/Database/Database.php
Extended Structure constructor to accept optional ?Document $currentDocument and updated instantiations (including PartialStructure) to pass historical/old document context or null placeholder in bulk paths.
Operator validator parsing/error handling
src/Database/Validator/Operator.php
Operator::isValid() now attempts to parse non-operator values via DatabaseOperator::parse() and surfaces parsing exception messages in the validator description on failure.
Tests
tests/unit/Validator/OperatorTest.php, tests/unit/Validator/StructureTest.php
Added comprehensive Operator validator tests (parsing, numeric/array/string/date ops, edge cases) and Structure tests ensuring operators are skipped during normal validation and required-field behavior.
CI workflow images
.github/workflows/codeql-analysis.yml, .github/workflows/linter.yml
Switched Docker image used in workflows to phpswoole/swoole:5.1.8-php8.3-alpine and added working directory flag -w /app in docker invocation; commands unchanged.
Minor static-analysis tweak
src/Database/Connection.php
Removed a PHPStan ignore directive before a lost-connection detection call; runtime behavior unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (operators task)
    participant Task as Task Action
    participant Env as setupTestEnvironment
    participant DB as Database
    participant Seed as seedDocuments
    participant Results as displayResults

    CLI->>Task: parse args (adapter, iterations, seed, name)
    Task->>Env: setupTestEnvironment(database, name, seed)
    Env->>Seed: if seed > 0 -> seedDocuments(database, seed)
    Seed-->>Env: seeded count, time
    Task->>DB: run benchmark iterations
    DB-->>Task: results
    Task->>Results: displayResults(results, adapter, iterations, seed)
    Results-->>CLI: log results table (includes Seeded documents)
Loading
sequenceDiagram
    participant DB as Database
    participant Struct as Structure
    participant OpVal as OperatorValidator
    participant OpFactory as DatabaseOperator

    DB->>Struct: validate attribute value(s) (may include operators)
    Struct->>OpFactory: detect/parse value as Operator
    alt value is Operator
        OpFactory-->>Struct: Operator instance
        Struct->>OpVal: construct with currentDocument
        Struct->>OpVal: isValid(operator)
        alt valid
            OpVal-->>Struct: OK (skip standard validation)
        else invalid
            OpVal-->>Struct: error -> Structure returns false
        end
    else not Operator
        Struct->>Struct: perform standard attribute-type validation
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • Call-site updates in src/Database/Database.php passing $old into Structure/PartialStructure.
    • Operator detection/refetch logic to ensure behavior matches previous explicit extraction flows.
    • Operator::isValid() parsing path and the exact error descriptions produced.
    • New unit tests coverage and CI workflow image changes.

Possibly related PRs

  • Add operators base #713 — Modifies the same CLI operators task functions (setupTestEnvironment, displayResults, action signatures) and is directly related to the seed plumbing.
  • Feat mongodb #721 — Alters Database/validator call sites and update/refetch flows; overlaps with passing historical document context.
  • Pass old to update on next, rename to upsert #685 — Introduces/propagates historical "old" document context into update/upsert flows in src/Database/Database.php, similar call-site changes.

Suggested reviewers

  • fogelito

Poem

🐰 I seeded fields beneath the sun,
Operators danced, one by one,
Old docs whispered rules to new,
Parsers hummed and tests ran through,
Tiny rabbit cheers: "Good run!"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.78% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The PR title "Fix validation" is vague and generic without clearly specifying what validation is being fixed or improved. While the changeset does include validation-related changes—particularly refactoring operator validation flow in Structure.php and updating Operator.php—the title fails to capture the full scope of the PR, which also includes significant additions like a seed capability for benchmark tests, test suite expansions, and CI/CD workflow updates. The use of "Fix" is ambiguous and could refer to bug fixes, refactoring, or improvements without clarifying which. Consider revising the title to be more specific and descriptive, such as "Refactor operator validation with on-the-fly detection" or "Add operator-based validation and seeding for benchmarks" to more clearly communicate the primary changes to reviewers scanning the commit history. The current title doesn't convey meaningful information about what specific validation changes are being implemented or the breadth of the modifications in this PR.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-operators

📜 Recent 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 78854fb and 08a86fa.

📒 Files selected for processing (3)
  • .github/workflows/codeql-analysis.yml (1 hunks)
  • .github/workflows/linter.yml (1 hunks)
  • src/Database/Connection.php (0 hunks)
💤 Files with no reviewable changes (1)
  • src/Database/Connection.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/linter.yml
⏰ 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). (10)
  • GitHub Check: Adapter Tests (SharedTables/MySQL)
  • GitHub Check: Adapter Tests (SharedTables/MariaDB)
  • GitHub Check: Adapter Tests (SharedTables/Postgres)
  • GitHub Check: Adapter Tests (Pool)
  • GitHub Check: Adapter Tests (SharedTables/SQLite)
  • GitHub Check: Adapter Tests (SQLite)
  • GitHub Check: Adapter Tests (MySQL)
  • GitHub Check: Adapter Tests (Mirror)
  • GitHub Check: Adapter Tests (Postgres)
  • GitHub Check: Adapter Tests (MariaDB)
🔇 Additional comments (1)
.github/workflows/codeql-analysis.yml (1)

19-20: Verify that the Docker image contains CodeQL dependencies.

The phpswoole/swoole:5.1.8-php8.3-alpine image is a PHP application runtime, not a CodeQL analysis environment. Using this image for CodeQL analysis may lack necessary CodeQL tooling and static analysis dependencies. Ensure that this image has all required CodeQL components, or revert to a proper CodeQL runner image.

If you're standardizing on this image for a specific reason (e.g., matching a linter workflow), consider documenting that intent or verifying that CodeQL analysis still runs correctly. You can validate this by checking:

  • Whether the image includes php and necessary static analysis tools
  • Whether prior CodeQL runs succeeded with this image

Alternatively, consider splitting CodeQL analysis into a dedicated job with an appropriate base image.


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: 1

Caution

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

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

30-30: Fix linter: remove unused import.

use Utopia\Database\Validator\Operator as OperatorValidator; is unused after the refactor and triggers the PSR-12 no_unused_imports failure. Remove it.

-use Utopia\Database\Validator\Operator as OperatorValidator;
🧹 Nitpick comments (3)
src/Database/Database.php (2)

4955-4955: Merge overlay is fine; ensure $id can’t be mutated.

array_merge($old, $new) is correct, but consider explicitly unsetting/ignoring $id from user input to prevent accidental id mutation on write.

Does your adapter ignore $id updates? If not, add:

- $document = \array_merge($old->getArrayCopy(), $document->getArrayCopy());
+ $incoming = $document->getArrayCopy();
+ unset($incoming['$id']);
+ $document = \array_merge($old->getArrayCopy(), $incoming);

5123-5134: Refetch-on-operator is correct; consider deduping detection.

The refetch logic is solid. To avoid duplicating operator scans in multiple paths, extract a small helper (e.g., private function hasOperators(Document|array $data): bool) and reuse.

bin/tasks/operators.php (1)

195-248: LGTM! Well-implemented seeding function with good batching and progress feedback.

The function effectively seeds documents in batches, provides progress updates, and uses realistic test data. The deterministic ID scheme (seed_0, seed_1, etc.) is good for reproducibility.

Optional nitpick (Line 203): The (int) cast is redundant since ceil() returns a float that will be implicitly converted to int in the for loop context:

-    $batches = (int) ceil($count / $batchSize);
+    $batches = ceil($count / $batchSize);
📜 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 dce1c4f and c31f611.

📒 Files selected for processing (6)
  • bin/tasks/operators.php (7 hunks)
  • src/Database/Database.php (8 hunks)
  • src/Database/Validator/Operator.php (1 hunks)
  • src/Database/Validator/Structure.php (3 hunks)
  • tests/unit/Validator/OperatorTest.php (1 hunks)
  • tests/unit/Validator/StructureTest.php (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-30T19:17:53.630Z
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#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/StructureTest.php
  • src/Database/Validator/Structure.php
  • src/Database/Database.php
📚 Learning: 2025-10-03T02:04:17.803Z
Learnt from: abnegate
PR: utopia-php/database#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/StructureTest.php
  • src/Database/Database.php
📚 Learning: 2025-10-29T12:27:57.071Z
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#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/Database.php
🧬 Code graph analysis (6)
tests/unit/Validator/OperatorTest.php (3)
src/Database/Database.php (1)
  • Database (38-8506)
src/Database/Validator/Operator.php (3)
  • Operator (10-387)
  • isValid (60-89)
  • getDescription (46-49)
src/Database/Operator.php (16)
  • increment (409-416)
  • decrement (425-432)
  • multiply (510-517)
  • divide (527-537)
  • modulo (589-595)
  • arrayAppend (441-444)
  • arrayUnique (619-622)
  • arrayIntersect (630-633)
  • arrayDiff (641-644)
  • arrayFilter (653-656)
  • stringConcat (486-489)
  • stringReplace (498-501)
  • toggle (544-547)
  • dateAddDays (556-559)
  • dateSubDays (567-570)
  • dateSetNow (577-580)
tests/unit/Validator/StructureTest.php (2)
src/Database/Validator/Operator.php (3)
  • Operator (10-387)
  • isValid (60-89)
  • getDescription (46-49)
src/Database/Validator/Structure.php (3)
  • Structure (20-460)
  • isValid (211-245)
  • getDescription (197-200)
src/Database/Validator/Operator.php (1)
src/Database/Operator.php (1)
  • parse (311-324)
src/Database/Validator/Structure.php (3)
src/Database/Validator/Operator.php (3)
  • Operator (10-387)
  • isValid (60-89)
  • getDescription (46-49)
src/Database/Document.php (2)
  • Document (12-470)
  • setAttribute (244-261)
src/Database/Operator.php (1)
  • isOperator (664-667)
src/Database/Database.php (3)
src/Database/Document.php (2)
  • getArrayCopy (423-458)
  • isEmpty (396-399)
src/Database/Validator/Operator.php (1)
  • Operator (10-387)
src/Database/Operator.php (2)
  • Operator (14-698)
  • isOperator (664-667)
bin/tasks/operators.php (3)
src/Database/Database.php (2)
  • Database (38-8506)
  • createDocuments (4485-4588)
src/Database/Adapter/SQL.php (1)
  • createDocuments (2411-2544)
src/Database/Adapter/Mongo.php (1)
  • createDocuments (1343-1382)
🪛 GitHub Actions: Linter
src/Database/Database.php

[error] 1-1: Pint lint failure: PSR-12 no_unused_imports detected in src/Database/Database.php.

🪛 PHPMD (2.15.0)
tests/unit/Validator/OperatorTest.php

147-147: Avoid unused local variables such as '$validator'. (undefined)

(UnusedLocalVariable)


153-153: Avoid unused local variables such as '$operator'. (undefined)

(UnusedLocalVariable)


158-158: Avoid unused local variables such as '$validator'. (undefined)

(UnusedLocalVariable)


164-164: Avoid unused local variables such as '$operator'. (undefined)

(UnusedLocalVariable)

⏰ 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 (10)
src/Database/Database.php (5)

4979-4984: Good: early operator detection to decide update.

Scanning for Operator::isOperator($value) to set $shouldUpdate is clear and efficient.


5103-5105: Passing old document into Structure validator.

LGTM, but confirm the constructor signature was updated to accept $old and that all call sites match.

Run your test suite touching Structure/PartialStructure to ensure no signature mismatch.


5254-5261: PartialStructure with historical context (null in bulk).

Looks good. Null old-doc is reasonable for bulk updates; just confirm PartialStructure safely handles null and doesn’t apply old-dependent checks.

Also applies to: 5263-5265


6028-6033: Structure validator with $old in upsert path.

Good improvement; enables validations that depend on prior state.


5350-5356: Review comment is incorrect.

The concern assumes castingBefore() modifies or removes Operator objects. This is unfounded:

  • castingBefore() in Mongo.php only processes attributes defined in the collection schema (via getAttribute('attributes', [])). Operator instances passed in $updates are not schema-defined attributes and pass through unmodified.
  • castingBefore() in SQL.php is a no-op.
  • Type conversions only apply to specific schema types (e.g., VAR_DATETIME → UTCDateTime). Operator instances don't match any conversion and remain intact.
  • Operator::isOperator() simply checks instanceof, which succeeds whether the detection happens before or after casting.

The operator detection after castingBefore() works correctly—there is no false negative risk.

Likely an incorrect or invalid review comment.

bin/tasks/operators.php (5)

11-15: LGTM! Clear documentation with helpful examples.

The documentation effectively explains the new seed capability and provides practical usage examples for different adapters and seed values.


44-46: LGTM! CLI parameter properly integrated.

The seed parameter is well-defined with appropriate validation, sensible default (0 = no seeding), and the action signature is correctly updated to accept it.


141-141: LGTM! Function signature appropriately extended.

The signature change is clean and the conditional seeding logic (lines 187-190) appropriately skips seeding when $seed is 0.


916-924: LGTM! Results display consistently updated.

The function signature and display output are appropriately extended to show the seeded document count, providing complete benchmark context.


44-248: Excellent integration of seed capability for benchmark testing.

The seed feature is comprehensively implemented with:

  • Clear documentation and usage examples
  • Appropriate CLI parameter with sensible defaults
  • Efficient batching strategy for large datasets
  • Consistent updates across all function signatures and call sites
  • Good user feedback via progress logging

This enhancement enables testing operator performance under varying data conditions, which is valuable for realistic benchmarking scenarios.

Comment on lines +311 to +319
if (Operator::isOperator($value)) {
// Set the attribute name on the operator for validation
$value->setAttribute($key);

$operatorValidator = new OperatorValidator($this->collection, $this->currentDocument);
if (!$operatorValidator->isValid($value)) {
$this->message = $operatorValidator->getDescription();
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Handle array-backed attribute metadata before invoking OperatorValidator

OperatorValidator still builds its attribute map by calling getAttribute()/getId() on each entry returned from $collection->getAttribute('attributes'). In many code paths (including this test fixture) the collection metadata is hydrated from plain arrays, so as soon as we hit this new branch we instantiate OperatorValidator with array entries and trigger a fatal Call to a member function getAttribute() on array. That turns operator-based updates into hard crashes instead of validation errors. Please normalise the collection attributes to Document instances (or update OperatorValidator to accept arrays) before constructing it here so this code path works for both array- and Document-backed metadata.

🤖 Prompt for AI Agents
In src/Database/Validator/Structure.php around lines 311 to 319, the new branch
that constructs OperatorValidator assumes collection attribute metadata are
Document objects and crashes when attributes are plain arrays; before creating
OperatorValidator, normalize the collection's 'attributes' entries into Document
instances (or otherwise convert array entries to the same object type
OperatorValidator expects) so getAttribute()/getId() calls are safe — detect
array entries and wrap/convert them into Document objects (preserving original
keys/values and any IDs) and then instantiate OperatorValidator with the
normalized collection metadata; alternatively, if preferred, adjust
OperatorValidator to accept arrays, but the simplest fix here is to coerce the
collection attributes to Document instances prior to constructing
OperatorValidator.

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

🧹 Nitpick comments (1)
src/Database/Database.php (1)

5253-5260: PartialStructure on updates: ensure operator-aware validation.

Validating $updates is right, but if Operator instances are present, PartialStructure/Structure must tolerate them (skip value-type checks for operator payloads). Please confirm or guard.

If not operator-aware, consider short-circuiting when operators exist:

@@
-        $validator = new PartialStructure(
+        $containsOps = !empty(\Utopia\Database\Operator::extractOperators($updates->getArrayCopy())['operators']);
+        $validator = new PartialStructure(
             $collection,
             $this->adapter->getIdAttributeType(),
             $this->adapter->getMinDateTime(),
             $this->adapter->getMaxDateTime(),
             $this->adapter->getSupportForAttributes(),
             null // No old document available in bulk updates
         );
-        if (!$validator->isValid($updates)) {
+        if (!$containsOps && !$validator->isValid($updates)) {
             throw new StructureException($validator->getDescription());
         }

Also applies to: 5262-5264

📜 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 c31f611 and 78854fb.

📒 Files selected for processing (3)
  • .github/workflows/codeql-analysis.yml (1 hunks)
  • .github/workflows/linter.yml (1 hunks)
  • src/Database/Database.php (8 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-29T12:27:57.071Z
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#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/Database.php
📚 Learning: 2025-07-30T19:17:53.630Z
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#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/Database.php
📚 Learning: 2025-10-03T02:04:17.803Z
Learnt from: abnegate
PR: utopia-php/database#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:

  • src/Database/Database.php
🧬 Code graph analysis (1)
src/Database/Database.php (3)
src/Database/Validator/Operator.php (2)
  • Operator (10-387)
  • isValid (60-89)
src/Database/Operator.php (2)
  • Operator (14-698)
  • isOperator (664-667)
src/Database/Validator/PartialStructure.php (2)
  • PartialStructure (8-62)
  • isValid (19-61)
⏰ 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/MongoDB)
  • GitHub Check: Adapter Tests (SharedTables/SQLite)
  • GitHub Check: Adapter Tests (SharedTables/MySQL)
  • GitHub Check: Adapter Tests (Mirror)
  • GitHub Check: Adapter Tests (SharedTables/MariaDB)
  • GitHub Check: Adapter Tests (Pool)
  • GitHub Check: Adapter Tests (SharedTables/Postgres)
  • GitHub Check: Adapter Tests (SQLite)
  • GitHub Check: Adapter Tests (MariaDB)
  • GitHub Check: Adapter Tests (Postgres)
  • GitHub Check: Adapter Tests (MySQL)
  • GitHub Check: Adapter Tests (MongoDB)
  • GitHub Check: Unit Test
🔇 Additional comments (5)
.github/workflows/linter.yml (1)

19-20: Verify necessity and compatibility of the swoole Docker image for linting.

The Docker image has been changed to phpswoole/swoole:5.1.8-php8.3-alpine, which is a specialized async networking framework. This choice seems unusual for a database library's linter and CodeQL CI job unless the project explicitly uses swoole as a runtime dependency.

Please clarify:

  1. Why is a swoole-specific image needed for linting and code analysis?
  2. Does this project depend on or use swoole?
  3. If this is a dependency, are there any compatibility concerns with this specific version (5.1.8) and PHP 8.3?

If swoole is not required for linting, consider reverting to a standard PHP 8.3 Alpine image (e.g., php:8.3-alpine) to reduce unnecessary image complexity and potential supply chain risk.

.github/workflows/codeql-analysis.yml (1)

19-20: Verify necessity and compatibility of the swoole Docker image for CodeQL analysis.

The Docker image has been changed to phpswoole/swoole:5.1.8-php8.3-alpine, mirroring the change in linter.yml. The same concerns apply: a swoole-specific image seems unusual for code analysis of a database library unless the project explicitly depends on swoole as a runtime requirement.

Please verify the same points as raised for linter.yml:

  1. Does the project require or use swoole?
  2. Are there compatibility concerns with swoole 5.1.8 and PHP 8.3?

If swoole is not a runtime dependency, consider using a standard PHP 8.3 Alpine image instead to keep CI images minimal and focused.

src/Database/Database.php (3)

4954-4954: Shallow merge behavior: confirm intent for nulls and unknown keys.

array_merge keeps new nulls (good for clearing), and preserves unknown user keys until validation. Just confirm this matches desired semantics for updates (especially with schemaless adapters).


5102-5103: Good: pass old document context into Structure.

This enables validators to reason about transitions (e.g., bounds, immutability).


5299-5299: Side effect via reference: safe but ensure adapter honors $skipPermissionsUpdate only.

Passing and mutating $batch by reference is fine; validate that no other transient fields (like $skipPermissionsUpdate) leak past castingAfter/cleanup.

@abnegate abnegate merged commit b6541a9 into main Oct 30, 2025
18 checks passed
@abnegate abnegate deleted the feat-operators branch October 30, 2025 13:10
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.

2 participants