Skip to content

Refetch documents by $sequence#916

Open
fogelito wants to merge 2 commits into
mainfrom
refetch-documents-by-sequence
Open

Refetch documents by $sequence#916
fogelito wants to merge 2 commits into
mainfrom
refetch-documents-by-sequence

Conversation

@fogelito

@fogelito fogelito commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes
    • Improved document refresh behavior so refreshed items are matched using each document’s sequence value, improving reliability.
    • Refresh now preserves the caller’s selection context to maintain consistent projected fields.
    • Operator-driven refetch for single and batch updates now runs after the transaction commits, reducing timing-related inconsistencies.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Database now refetches operator-computed documents after commit, matches refreshed documents by $sequence, and preserves selection context during both single-document and batch update flows.

Changes

Refetch and replay operator-computed documents

Layer / File(s) Summary
Refetch by sequence with selections
src/Database/Database.php
refetchDocuments() now accepts selection context, builds sequence-based lookups, queries by $sequence, and restores results in input order with fallback to the original document.
Commit-time refetch wiring
src/Database/Database.php
updateDocument() moves operator-computed refetching to after transaction commit, and updateDocuments() forwards grouped selections into refetchDocuments() for batch updates.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: refetching documents by $sequence.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refetch-documents-by-sequence

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.

@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR changes refetchDocuments to match documents by $sequence instead of $id, so that documents whose $id is mutated during an operator-driven update are still matched correctly after the transaction commits. It also forwards the caller's Query::select(...) projections into the refetch find call for bulk updates.

  • refetchDocuments now maps refetched documents by $sequence; the pre-built $sequences array preserves the original ordering regardless of the fetch order returned by the DB.
  • The hasOperators / refetch block is moved outside the withTransaction closure in updateDocument so the re-read sees committed values, matching the semantics already present in updateDocuments.
  • Bulk updateDocuments passes $grouped['selections'] into the refetch so the returned documents respect the caller's field projection.

Confidence Score: 5/5

The change is safe to merge; the core logic is correct and system fields including $sequence are always injected into select queries, so the map-based re-ordering is reliable.

The $sequence-keyed map correctly preserves batch ordering, the projection passthrough is wired only where needed (bulk path), and moving the refetch outside the transaction ensures committed values are read. The observations raised are edge-case concerns rather than bugs in the common path.

src/Database/Database.php — specifically the null-$sequence guard in refetchDocuments and the missing $selections passthrough in the single-document updateDocument refetch path.

Important Files Changed

Filename Overview
src/Database/Database.php Switches refetchDocuments from $id-based to $sequence-based lookup, adds projection ($selections) passthrough for bulk updates, and moves the operator-refetch logic outside the transaction in updateDocument.

Reviews (2): Last reviewed commit: "Refetch" | Re-trigger Greptile

Comment thread src/Database/Database.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)

812-842: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Add an explicit limit to the refetch query. find() falls back to a 25-row limit when no Query::limit() is present, so bulk calls to refetchDocuments() can return stale pre-operator documents for everything past the first 25. Use Query::limit(count($sequences)) here, and chunk the sequence list if needed for adapter limits.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Database/Database.php` around lines 812 - 842, The refetchDocuments()
flow currently calls find() with only a Query::equal('$sequence', $sequences)
filter, so it can silently stop at the default 25-result cap. Update the refetch
query in Database::refetchDocuments() to include
Query::limit(count($sequences)), and if the sequence list can exceed adapter
query limits, split the lookup into chunks and merge the results before
rebuilding the refetchedMap.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/Database/Database.php`:
- Around line 812-842: The refetchDocuments() flow currently calls find() with
only a Query::equal('$sequence', $sequences) filter, so it can silently stop at
the default 25-result cap. Update the refetch query in
Database::refetchDocuments() to include Query::limit(count($sequences)), and if
the sequence list can exceed adapter query limits, split the lookup into chunks
and merge the results before rebuilding the refetchedMap.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 91a5b9c5-ff4c-40bf-97eb-ffa188eb1459

📥 Commits

Reviewing files that changed from the base of the PR and between a090699 and 5803460.

📒 Files selected for processing (1)
  • src/Database/Database.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Database/Database.php`:
- Around line 827-833: The refetch logic in refetchDocuments() is still relying
on the default find() limit, so batches larger than 25 can leave later documents
using stale computed/operator values. Update the query passed to
Database::find() to explicitly bound it to the current batch size (or the number
of requested sequence IDs) using Query::limit(), alongside the existing
Query::equal('$sequence', $sequences) and $selections so every document in the
batch is actually refetched.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b45f00f-1ddd-49aa-b7e4-a4c42b4548ca

📥 Commits

Reviewing files that changed from the base of the PR and between 5803460 and c67b757.

📒 Files selected for processing (1)
  • src/Database/Database.php

Comment thread src/Database/Database.php
Comment on lines +827 to 833
// Fetch fresh copies with computed operator values, preserving the caller's projection
$refetched = $this->getAuthorization()->skip(fn () => $this->silent(
fn () => $this->find($collection->getId(), [Query::equal('$id', $docIds)])
fn () => $this->find(
$collection->getId(),
array_merge([Query::equal('$sequence', $sequences)], $selections)
)
));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Bound the refetch to the batch size

find() defaults to 25 rows, but refetchDocuments() can be called with batches up to INSERT_BATCH_SIZE (1000). Without an explicit Query::limit(), rows past the first 25 fall back to the original $doc via $refetchedMap[$sequences[$index]] ?? $doc, so they keep stale computed/operator values.

Proposed fix
         // Fetch fresh copies with computed operator values, preserving the caller's projection
         $refetched = $this->getAuthorization()->skip(fn () => $this->silent(
             fn () => $this->find(
                 $collection->getId(),
-                array_merge([Query::equal('$sequence', $sequences)], $selections)
+                array_merge([
+                    Query::equal('$sequence', $sequences),
+                    Query::limit(\count($sequences)),
+                ], $selections)
             )
         ));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Fetch fresh copies with computed operator values, preserving the caller's projection
$refetched = $this->getAuthorization()->skip(fn () => $this->silent(
fn () => $this->find($collection->getId(), [Query::equal('$id', $docIds)])
fn () => $this->find(
$collection->getId(),
array_merge([Query::equal('$sequence', $sequences)], $selections)
)
));
// Fetch fresh copies with computed operator values, preserving the caller's projection
$refetched = $this->getAuthorization()->skip(fn () => $this->silent(
fn () => $this->find(
$collection->getId(),
array_merge([
Query::equal('$sequence', $sequences),
Query::limit(\count($sequences)),
], $selections)
)
));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Database/Database.php` around lines 827 - 833, The refetch logic in
refetchDocuments() is still relying on the default find() limit, so batches
larger than 25 can leave later documents using stale computed/operator values.
Update the query passed to Database::find() to explicitly bound it to the
current batch size (or the number of requested sequence IDs) using
Query::limit(), alongside the existing Query::equal('$sequence', $sequences) and
$selections so every document in the batch is actually refetched.

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.

1 participant