Skip to content

Conversation

@abnegate
Copy link
Member

@abnegate abnegate commented Aug 14, 2025

Summary by CodeRabbit

  • New Features
    • Granular control to skip specific filters during read/write operations.
    • Enabled array index support on MySQL, improving query capabilities and potential performance.
  • Bug Fixes
    • Correctly enforces and propagates min/max limits in increase/decrease operations.
    • More precise error handling for invalid increment/decrement values and limit violations.
  • Tests
    • Strengthened end-to-end tests to validate limit-related errors with explicit exception checks.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 14, 2025

Walkthrough

Enables array index support in MySQL adapter, introduces selective filter skipping via an updated skipFilters API with per-filter control, adjusts error types for invalid increase/decrease values, refines min/max propagation, and updates an e2e test to assert specific Limit exceptions.

Changes

Cohort / File(s) Summary
Adapter index-array support
src/Database/Adapter/MySQL.php
getSupportForIndexArray() now returns true; cast index support follows accordingly.
Database filter control and bounds handling
src/Database/Database.php
Adds per-filter skip via skipFilters(callable, ?array); introduces protected disabledFilters; decodeAttribute respects disabled filters; increase/decrease throw InvalidArgumentException on non-positive values; strict null checks and min/max propagation to adapter.
E2E limit tests
tests/e2e/Adapter/Scopes/DocumentTests.php
Tests updated to assert LimitException via try/catch in decrease limit scenarios; adds Limit alias import.

Sequence Diagram(s)

sequenceDiagram
  actor Client
  participant DB as Database
  participant Adapter

  Client->>DB: skipFilters(callback, filters?)
  activate DB
  DB->>DB: Save current filter state
  DB->>DB: Disable all or specified filters
  DB->>DB: Execute callback()
  DB-->>Client: callback result
  DB->>DB: Restore previous filter state
  deactivate DB
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • fogelito
  • Meldiron

Poem

I nibbled through filters, just a few—
Hop, skip, and only those I choose.
Arrays indexed, carrots aligned,
Min and max keep tidy time.
If limits snap, I thump—beware!
Then bounce back—state restored with care. 🥕🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 0.71.x

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Nitpick comments (4)
tests/e2e/Adapter/Scopes/DocumentTests.php (1)

1045-1069: Tighten assertions by catching the exact type and verifying the error message

Catching Exception and then asserting type works, but a typed catch is stricter and easier to read. Also assert a stable part of the message to ensure the correct limit is surfaced.

Apply this diff:

         try {
             $database->decreaseDocumentAttribute(
                 'increase_decrease',
                 $document->getId(),
                 'decrease',
                 10,
                 99
             );
             $this->fail('Failed to throw exception');
-        } catch (Exception $e) {
-            $this->assertInstanceOf(LimitException::class, $e);
+        } catch (LimitException $e) {
+            $this->assertStringContainsString('Attribute value exceeds minimum limit', $e->getMessage());
+            $this->assertStringContainsString('99', $e->getMessage());
         }
 
         try {
             $database->decreaseDocumentAttribute(
                 'increase_decrease',
                 $document->getId(),
                 'decrease',
                 1000,
                 0
             );
             $this->fail('Failed to throw exception');
-        } catch (Exception $e) {
-            $this->assertInstanceOf(LimitException::class, $e);
+        } catch (LimitException $e) {
+            $this->assertStringContainsString('Attribute value exceeds minimum limit', $e->getMessage());
+            $this->assertStringContainsString('0', $e->getMessage());
         }
src/Database/Database.php (3)

347-351: Normalize disabledFilters typing and simplify the check

Currently, disabledFilters is declared as nullable but never set to null, while decodeAttribute guards for null before checking the map. Align the type with usage and simplify the check.

Apply these diffs:

-    /**
-     * @var array<string, bool>|null
-     */
-    protected ?array $disabledFilters = [];
+    /**
+     * @var array<string, bool>
+     */
+    protected array $disabledFilters = [];
-        if (!\is_null($this->disabledFilters) && isset($this->disabledFilters[$filter])) {
-            return $value;
-        }
+        if (isset($this->disabledFilters[$filter])) {
+            return $value;
+        }

Also applies to: 6594-6597


817-821: Clarify skipFilters docblock to reflect selective filter skipping

The method now supports per-filter disabling, but the description still implies global skipping only. Consider clarifying that:

  • Passing null disables all filters (previous behavior).
  • Passing a list disables only those named filters.
  • The per-filter control applies to decoding (encode path still applies all filters).

Example docblock text:

/**
 * Skip filters
 *
 * Execute a callback with filters disabled.
 * - If $filters is null, all filters are disabled (global).
 * - If $filters is a list of filter names, only those filters are disabled (during decoding).
 *
 * @template T
 * @param callable(): T $callback
 * @param array<string>|null $filters List of filters to disable; null disables all filters
 * @return T
 */

5257-5258: Exception type change: update docs and consumers to use InvalidArgumentException

Same note as increase: add @throws \InvalidArgumentException to the docblock and verify downstream handlers.

I can help search for affected call sites (see the script in the previous comment).

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33f35f5 and 20998e2.

📒 Files selected for processing (3)
  • src/Database/Adapter/MySQL.php (1 hunks)
  • src/Database/Database.php (7 hunks)
  • tests/e2e/Adapter/Scopes/DocumentTests.php (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/e2e/Adapter/Scopes/DocumentTests.php (2)
src/Database/Database.php (2)
  • Database (35-6825)
  • decreaseDocumentAttribute (5249-5332)
src/Database/Exception.php (1)
  • Exception (7-21)
src/Database/Database.php (3)
src/Database/Adapter.php (1)
  • filter (1112-1121)
src/Database/Document.php (1)
  • getAttribute (212-219)
src/Database/Query.php (1)
  • getAttribute (120-123)
⏰ 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 (3)
tests/e2e/Adapter/Scopes/DocumentTests.php (1)

14-14: LGTM: Specific exception alias improves clarity

Importing Limit as LimitException makes the intent explicit and keeps assertions readable.

src/Database/Database.php (2)

5204-5206: LGTM: Strict null-check on max and early guard

The stricter null-check and early LimitException provide clearer semantics and reduce adapter churn. Passing max to the adapter as a guard is a good atomicity hook.


5303-5305: LGTM: Strict null-check on min and early guard

The stricter null-check and early LimitException for decreases mirrors the increase path and looks correct.

@abnegate abnegate merged commit e194da3 into main Aug 15, 2025
15 checks passed
@abnegate abnegate deleted the 0.71.x branch August 15, 2025 07:11
@abnegate abnegate restored the 0.71.x branch August 18, 2025 06:56
@coderabbitai coderabbitai bot mentioned this pull request Oct 17, 2025
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