Skip to content

Add cached find support#899

Closed
premtsd-code wants to merge 4 commits into
mainfrom
codex/clean-find-cache
Closed

Add cached find support#899
premtsd-code wants to merge 4 commits into
mainfrom
codex/clean-find-cache

Conversation

@premtsd-code

@premtsd-code premtsd-code commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add explicit TTL-backed cached find support with targeted and collection-wide purge helpers
  • include deterministic find cache keys for query, schema, database, filter, and relationship dimensions
  • cache empty result sets with a versioned payload and refetch when cached TTL-indexed documents have expired

Tests

  • composer format
  • composer lint
  • vendor\bin\phpunit --configuration phpunit.xml tests\unit\FindCacheTest.php
  • vendor\bin\phpunit --configuration phpunit.xml tests\unit\CacheKeyTest.php
  • vendor\bin\phpstan analyse --level 7 src\Database\Database.php tests\unit\FindCacheTest.php tests\unit\CacheKeyTest.php --memory-limit 2G

Notes

  • local adapter e2e requires the repo service environment because the test harness connects to the redis host

Summary by CodeRabbit

Release Notes

  • New Features
    • Database queries can now be cached with configurable time-to-live (TTL) for improved performance
    • Added ability to manually refresh and clear cached query results
    • Cached results automatically validate data expiry and fetch fresh data when needed

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Adds a TTL-backed findCached() method to Database that caches find() results keyed by query shape, with per-document expiry detection, optional touch-on-hit, and authorization gating. New purgeCachedFinds()/purgeCachedFind() methods handle cache invalidation; purgeCachedCollection() is updated to invoke them. getCachedFindKeys() and getCacheKeys() are extended with deterministic key builders.

Changes

findCached() Implementation and Validation

Layer / File(s) Summary
Cache-key generation and serialization utilities
src/Database/Database.php
getCachedFindKeys() and private helpers (query serialization, value normalization, schema hash, getActiveFilterSignatures()) build stable cache keys. getCacheKeys() is updated to call getActiveFilterSignatures() instead of inline logic.
Purge helpers and purgeCachedCollection update
src/Database/Database.php
purgeCachedCollection() now calls purgeCachedFinds(). New public methods purgeCachedFinds() and purgeCachedFind() invalidate all or a specific cached find entry for a collection.
findCached() core implementation
src/Database/Database.php
findCached() gates on TTL, authorization state, and query shape; decodes and validates cached payloads per document TTL expiry; purges and refetches on expiry; touches cache on hits when enabled; emits EVENT_DOCUMENT_FIND on cache-hit returns.
Unit test doubles
tests/unit/FindCacheTest.php
HashMemoryCache is a TTL-aware in-memory cache adapter with setCachedDocumentAttribute mutation. TouchSpyCache extends it with a touch counter. TtlMemoryAdapter overrides getSupportForTTLIndexes() to return true.
FindCacheTest unit tests
tests/unit/FindCacheTest.php
Covers stale-until-purged semantics, TTL=0 bypass, default TTL, empty result caching, auth/random-order delegation, malformed query handling, EVENT_DOCUMENT_FIND on cache hit, key-scoped purge, touch-on-hit, and expired document refetch/touch suppression.
CacheKeyTest extensions for getCachedFindKeys()
tests/unit/CacheKeyTest.php
createDatabase() gains an optional database name parameter. New tests assert getCachedFindKeys() key differentiation across query predicates, caller key, database name, schema, relationship mode, and cursor document values.
E2e adapter tests and supportsCachedFind() flag
tests/e2e/Adapter/Base.php, tests/e2e/Adapter/RedisTest.php, tests/e2e/Adapter/Scopes/DocumentTests.php
Base adds supportsCachedFind() returning true; RedisTest overrides it to false. DocumentTests trait adds testFindCachedReturnsStaleResultUntilPurged() verifying stale cache semantics and purge-driven refresh.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant findCached as Database::findCached
  participant Cache
  participant find as Database::find

  Caller->>findCached: findCached(collection, queries, ttl, key, touchOnHit)

  alt ttl=0 or authorization active or random order or malformed queries
    findCached->>find: find(collection, queries)
    find-->>Caller: documents
  else cache path
    findCached->>findCached: getCachedFindKeys(collection, queries, key)
    findCached->>Cache: load(indexKey, entryKey, ttl)
    alt cache hit
      Cache-->>findCached: serialized payload
      findCached->>findCached: decode documents, check isTtlExpired() per document
      alt any document expired
        findCached->>Cache: purge(indexKey, entryKey)
        findCached->>find: find(collection, queries)
        find-->>findCached: fresh documents
        findCached->>Cache: save(indexKey, entryKey, payload)
        findCached-->>Caller: fresh documents
      else all valid
        findCached->>Cache: touch(indexKey, entryKey) if touchOnHit
        findCached-->>Caller: cached documents + EVENT_DOCUMENT_FIND
      end
    else cache miss
      findCached->>find: find(collection, queries)
      find-->>findCached: documents
      findCached->>Cache: save(indexKey, entryKey, payload)
      findCached-->>Caller: documents
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • utopia-php/database#828: Both PRs modify filter-signature logic in Database::getCacheKeys() and extend cached find key generation that depends on those filter signatures.
  • utopia-php/database#887: Both PRs modify purgeCachedCollection() to extend cache invalidation scope, one adding tombstone markers and this one adding purge of cached find entries.

Suggested reviewers

  • fogelito

Poem

🐇 Hippity-hoppity, cache keys align,
A findCached burrow, so cleverly designed!
TTL guards each cozy cached hole,
Purge when it's stale — that's the bunny's goal.
On hit, a soft touch; on miss, dig anew,
Fresh carrots for all — the cache sees it through! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add cached find support' clearly and accurately summarizes the main change in the PR: introducing a new cached find feature to the database library.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/clean-find-cache

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.

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

  • Adds TTL-backed cached find support through a new findCached() flow.
  • Adds targeted and collection-wide helpers for purging cached find results.
  • Extends deterministic cache key coverage for query, database, schema, filter, and relationship dimensions.
  • Adds unit and e2e coverage for cache key generation, purge behavior, cached result handling, and TTL-index expiry.

Confidence Score: 5/5

The cached find changes appear safe to merge based on the reviewed code and accompanying targeted tests.

The implementation is covered by focused unit and adapter tests for cache keys, purge behavior, empty result caching, TTL-backed refresh, and relationship/filter dimensions.

T-Rex T-Rex Logs

What T-Rex did

  • The base checkout completed and the run harness was prepared, after which php -v failed with exit code 127.
  • The head checkout completed and the same harness remained available, after which php -v failed again with exit code 127.
  • An apt-get install attempt for PHP was made, but apt failed with permission denied on /var/lib/apt/lists/partial.
  • The validation container lacks the PHP CLI, blocking PHP reflection and runtime attempts as shown by /bin/sh: php: not found.
  • The after artifact revealed grep anchors for getListCacheKey and getCachedFindKeys and included dimensions, aiding cache-key traceability.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (4): Last reviewed commit: "Add list cache key helper" | Re-trigger Greptile

Comment thread src/Database/Database.php Outdated
Comment thread src/Database/Database.php
Comment thread src/Database/Database.php
Comment thread src/Database/Database.php Outdated
Comment thread src/Database/Database.php Outdated
Comment thread src/Database/Database.php
Comment thread src/Database/Database.php
Comment on lines +9683 to +9684
if ($key !== null) {
return [$findIndexKey, $collectionKey . ':' . $key];

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.

P1 Custom keys drop dimensions

The caller-owned $key branch drops the payload dimensions that were just added for database, schema hash, relationship mode, and active filters. When the same namespace, collection, and stable key such as rules_v1 are reused across setDatabase() scopes or after a schema/filter/relationship-mode change, both calls read and write the same {$collectionKey}:{$key} entry. That can return stale results with the wrong shape or filter semantics until TTL expiry or purge. Keep the readable caller key if needed, but include the non-query dimensions in the final cache entry key.

@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: 5

🧹 Nitpick comments (1)
tests/unit/FindCacheTest.php (1)

346-371: ⚖️ Poor tradeoff

Consider simplifying setCachedDocumentAttribute() complexity.

This method has nested conditionals and handles multiple payload formats. While functional, consider extracting helper methods to improve readability.

💡 Example refactoring approach
+    private function extractDocuments(mixed $payload): ?array
+    {
+        if (!\is_array($payload)) {
+            return null;
+        }
+        return \is_array($payload['documents'] ?? null) ? $payload['documents'] : $payload;
+    }
+
+    private function updateDocumentInPayload(array $payload, array $documents): array
+    {
+        if (\array_key_exists('documents', $payload)) {
+            $payload['documents'] = $documents;
+            return $payload;
+        }
+        return $documents;
+    }
+
     public function setCachedDocumentAttribute(string $key, string $hash, string $documentId, string $attribute, mixed $value): void
     {
         $usesEntryKey = isset($this->store[$hash][$hash]);
         $cacheKey = $usesEntryKey ? $hash : $key;
         $cacheHash = $hash;
         $payload = $this->store[$cacheKey][$cacheHash]['data'] ?? [];
-        $documents = \is_array($payload) && \is_array($payload['documents'] ?? null) ? $payload['documents'] : $payload;
-        if (!\is_array($documents)) {
+        $documents = $this->extractDocuments($payload);
+        if ($documents === null) {
             return;
         }
 
         foreach ($documents as $index => $document) {
             if (!\is_array($document) || ($document['$id'] ?? '') !== $documentId) {
                 continue;
             }
 
             $documents[$index][$attribute] = $value;
-            if (\is_array($payload) && \array_key_exists('documents', $payload)) {
-                $payload['documents'] = $documents;
-                $this->store[$cacheKey][$cacheHash]['data'] = $payload;
-            } else {
-                $this->store[$cacheKey][$cacheHash]['data'] = $documents;
-            }
+            $this->store[$cacheKey][$cacheHash]['data'] = $this->updateDocumentInPayload($payload, $documents);
             return;
         }
     }
🤖 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 `@tests/unit/FindCacheTest.php` around lines 346 - 371, The
`setCachedDocumentAttribute()` method has high complexity due to nested
conditionals and handling multiple payload formats. Refactor this method by
extracting helper methods such as one for extracting the documents array from
the payload (to handle both array and object formats), one for finding the
target document by ID, and one for updating the store with the modified payload.
This will improve readability and make the logic flow more clear while reducing
nesting levels.
🤖 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 9670-9687: The cache key generation at line 9684-9685 when $key is
not null drops important cache dimensions by returning only the collectionKey
with the caller key appended, ignoring the database, schema, relationships, and
filters in the payload. This causes the same caller key to potentially return
wrong cached results across different scopes. Fix this by computing a SHA-256
digest of the full $payload (similar to line 9687 for the null key case) and
appending it to the collectionKey along with the caller key, ensuring the cache
key is properly scoped by all relevant dimensions. Also replace the MD5 digest
on line 9687 with SHA-256 for consistency.
- Around line 8749-8756: The cached documents need to be re-cast to ensure
schema values are handled consistently since cache backends may round-trip
values differently than the adapter path. After the document is created with
createDocumentInstance and passes the TTL expiration check in isTtlExpired, call
the casting() method on the document before appending it to the $results array
to match the single-document cache path behavior.
- Around line 8639-8646: The caching mechanism in the find operation does not
properly handle relationships within documents. When loadCachedFind returns
cached results for collections that contain relationships, the nested
relationship values are not recursively hydrated and may return scalars or
arrays instead of Document objects, causing inconsistency with non-cached
results. Modify the logic after loadCachedFind to either bypass the cache
entirely for collections containing relationships by checking if the
collectionDocument has relationships before calling getCachedFindKeys and
loadCachedFind, or alternatively ensure that any cached results are recursively
hydrated to properly reconstruct relationship Document instances before
returning them.

In `@tests/e2e/Adapter/Scopes/DocumentTests.php`:
- Around line 114-117: The test in DocumentTests uses a hardcoded collection
name 'findCached' that is not cleaned up after the test runs, which can cause
flaky behavior in shared test environments where reruns may encounter stale
collections. Replace the hardcoded collection name with a dynamically generated
unique identifier (such as a UUID or timestamp-based name) assigned to the
$collection variable, and add teardown or cleanup logic at the end of the test
to call $database->deleteCollection() to remove the test collection after
assertions are complete, ensuring the test does not leave behind artifacts that
could interfere with subsequent runs.

In `@tests/unit/FindCacheTest.php`:
- Around line 410-413: The getName method in the FindCacheTest.php file has an
unused parameter $key that should be removed. Update the method signature of
getName to remove the ?string $key = null parameter while keeping the return
type as string and the return statement unchanged.

---

Nitpick comments:
In `@tests/unit/FindCacheTest.php`:
- Around line 346-371: The `setCachedDocumentAttribute()` method has high
complexity due to nested conditionals and handling multiple payload formats.
Refactor this method by extracting helper methods such as one for extracting the
documents array from the payload (to handle both array and object formats), one
for finding the target document by ID, and one for updating the store with the
modified payload. This will improve readability and make the logic flow more
clear while reducing nesting levels.
🪄 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: 9841ee36-135f-4a09-9935-3cb3dbeb3388

📥 Commits

Reviewing files that changed from the base of the PR and between fff9f0e and 50c6b39.

📒 Files selected for processing (6)
  • src/Database/Database.php
  • tests/e2e/Adapter/Base.php
  • tests/e2e/Adapter/RedisTest.php
  • tests/e2e/Adapter/Scopes/DocumentTests.php
  • tests/unit/CacheKeyTest.php
  • tests/unit/FindCacheTest.php

Comment thread src/Database/Database.php
Comment on lines +8639 to +8646
$collectionDocument = $this->silent(fn () => $this->getCollection($collection));

if ($collectionDocument->isEmpty()) {
throw new NotFoundException('Collection not found');
}

[$findIndexKey, $findKey] = $this->getCachedFindKeys($collectionDocument->getId(), $queries, $key, $collectionDocument);
$cached = $this->loadCachedFind($findKey, $ttl);

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid caching relationship-populated results.

find() can return nested relationship Document instances, but cached hits only rebuild the top-level document. For collections with relationships, cache hits can return arrays/scalars where find() returns Document objects; either bypass caching there or recursively hydrate relationship values.

Proposed safe bypass for relationship collections
         if ($collectionDocument->isEmpty()) {
             throw new NotFoundException('Collection not found');
         }
 
+        $relationships = \array_filter(
+            $collectionDocument->getAttribute('attributes', []),
+            fn (Document $attribute) => $attribute->getAttribute('type') === self::VAR_RELATIONSHIP
+        );
+
+        if ($this->resolveRelationships && !empty($relationships)) {
+            return $this->find($collectionDocument->getId(), $queries, $forPermission);
+        }
+
         [$findIndexKey, $findKey] = $this->getCachedFindKeys($collectionDocument->getId(), $queries, $key, $collectionDocument);
📝 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
$collectionDocument = $this->silent(fn () => $this->getCollection($collection));
if ($collectionDocument->isEmpty()) {
throw new NotFoundException('Collection not found');
}
[$findIndexKey, $findKey] = $this->getCachedFindKeys($collectionDocument->getId(), $queries, $key, $collectionDocument);
$cached = $this->loadCachedFind($findKey, $ttl);
$collectionDocument = $this->silent(fn () => $this->getCollection($collection));
if ($collectionDocument->isEmpty()) {
throw new NotFoundException('Collection not found');
}
$relationships = \array_filter(
$collectionDocument->getAttribute('attributes', []),
fn (Document $attribute) => $attribute->getAttribute('type') === self::VAR_RELATIONSHIP
);
if ($this->resolveRelationships && !empty($relationships)) {
return $this->find($collectionDocument->getId(), $queries, $forPermission);
}
[$findIndexKey, $findKey] = $this->getCachedFindKeys($collectionDocument->getId(), $queries, $key, $collectionDocument);
$cached = $this->loadCachedFind($findKey, $ttl);
🤖 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 8639 - 8646, The caching mechanism in
the find operation does not properly handle relationships within documents. When
loadCachedFind returns cached results for collections that contain
relationships, the nested relationship values are not recursively hydrated and
may return scalars or arrays instead of Document objects, causing inconsistency
with non-cached results. Modify the logic after loadCachedFind to either bypass
the cache entirely for collections containing relationships by checking if the
collectionDocument has relationships before calling getCachedFindKeys and
loadCachedFind, or alternatively ensure that any cached results are recursively
hydrated to properly reconstruct relationship Document instances before
returning them.

Comment thread src/Database/Database.php
Comment on lines +8749 to +8756
$document = $this->createDocumentInstance($collection->getId(), $document);

if ($this->isTtlExpired($collection, $document)) {
$hasExpiredDocuments = true;
continue;
}

$results[] = $document;

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Re-cast cached documents before returning them.

Cache backends can round-trip schema values differently from the adapter path, e.g. 1.0 as 1. Match the single-document cache path by running casting() after rehydrating each cached find result.

Proposed cached-hit casting fix
             $document = $this->createDocumentInstance($collection->getId(), $document);
+            $document = $this->casting($collection, $document);
 
             if ($this->isTtlExpired($collection, $document)) {
📝 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
$document = $this->createDocumentInstance($collection->getId(), $document);
if ($this->isTtlExpired($collection, $document)) {
$hasExpiredDocuments = true;
continue;
}
$results[] = $document;
$document = $this->createDocumentInstance($collection->getId(), $document);
$document = $this->casting($collection, $document);
if ($this->isTtlExpired($collection, $document)) {
$hasExpiredDocuments = true;
continue;
}
$results[] = $document;
🤖 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 8749 - 8756, The cached documents
need to be re-cast to ensure schema values are handled consistently since cache
backends may round-trip values differently than the adapter path. After the
document is created with createDocumentInstance and passes the TTL expiration
check in isTtlExpired, call the casting() method on the document before
appending it to the $results array to match the single-document cache path
behavior.

Comment thread src/Database/Database.php
Comment on lines +9670 to +9687
$payload = [
'version' => 1,
'database' => $this->getDatabase(),
'schema' => $this->getCachedFindSchemaHash($collection),
'key' => $key,
'queries' => $key === null ? \array_map(
fn (Query $query): array => $this->serializeCachedFindQuery($query),
$queries
) : null,
'relationships' => $this->resolveRelationships,
'filters' => $this->getActiveFilterSignatures(),
];

if ($key !== null) {
return [$findIndexKey, $collectionKey . ':' . $key];
}

return [$findIndexKey, $findIndexKey . ':' . \md5(\json_encode($payload) ?: '')];

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep caller-owned keys scoped by the full cache payload.

Line 9684 drops the database, schema, relationship, and active-filter dimensions whenever $key is provided, so the same caller key can serve the wrong cached result across scopes. Include the caller key in the readable segment, but still append a digest of the full payload; also replace the flagged MD5 digests with SHA-256.

Proposed scoped key digest fix
-        if ($key !== null) {
-            return [$findIndexKey, $collectionKey . ':' . $key];
-        }
-
-        return [$findIndexKey, $findIndexKey . ':' . \md5(\json_encode($payload) ?: '')];
+        $payloadHash = \hash('sha256', \json_encode($payload, \JSON_THROW_ON_ERROR));
+        $keySegment = $key === null ? 'query' : 'key:' . \rawurlencode($key);
+
+        return [$findIndexKey, "{$findIndexKey}:{$keySegment}:{$payloadHash}"];
-        return \md5(
-            \json_encode($collection->getAttribute('attributes', []))
-            . \json_encode($collection->getAttribute('indexes', []))
-        );
+        return \hash('sha256', \json_encode([
+            'attributes' => $collection->getAttribute('attributes', []),
+            'indexes' => $collection->getAttribute('indexes', []),
+        ], \JSON_THROW_ON_ERROR));

Also applies to: 9741-9744

🧰 Tools
🪛 ast-grep (0.43.0)

[error] 9686-9686: Do not use a weak hash algorithm
Context: \md5(\json_encode($payload) ?: '')
Note: [CWE-328] Use of Weak Hash.

(weak-hash-algorithm)

🤖 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 9670 - 9687, The cache key generation
at line 9684-9685 when $key is not null drops important cache dimensions by
returning only the collectionKey with the caller key appended, ignoring the
database, schema, relationships, and filters in the payload. This causes the
same caller key to potentially return wrong cached results across different
scopes. Fix this by computing a SHA-256 digest of the full $payload (similar to
line 9687 for the null key case) and appending it to the collectionKey along
with the caller key, ensuring the cache key is properly scoped by all relevant
dimensions. Also replace the MD5 digest on line 9687 with SHA-256 for
consistency.

Source: Linters/SAST tools

Comment on lines +114 to +117
$collection = 'findCached';

$database->createCollection($collection);
$database->createAttribute($collection, 'name', Database::VAR_STRING, 255, true);

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use an isolated collection name (and/or cleanup) to avoid flaky reruns.

Line 114 uses a fixed collection id ('findCached') and this test never deletes it. In shared/reused e2e environments, reruns can fail on collection/document conflicts or stale leftovers.

Suggested fix
-        $collection = 'findCached';
+        $collection = __FUNCTION__;
 
-        $database->createCollection($collection);
-        $database->createAttribute($collection, 'name', Database::VAR_STRING, 255, true);
+        $database->createCollection($collection);
+        $database->createAttribute($collection, 'name', Database::VAR_STRING, 255, true);
+
+        try {
+            // ... existing test body ...
+        } finally {
+            $database->deleteCollection($collection);
+        }
🤖 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 `@tests/e2e/Adapter/Scopes/DocumentTests.php` around lines 114 - 117, The test
in DocumentTests uses a hardcoded collection name 'findCached' that is not
cleaned up after the test runs, which can cause flaky behavior in shared test
environments where reruns may encounter stale collections. Replace the hardcoded
collection name with a dynamically generated unique identifier (such as a UUID
or timestamp-based name) assigned to the $collection variable, and add teardown
or cleanup logic at the end of the test to call $database->deleteCollection() to
remove the test collection after assertions are complete, ensuring the test does
not leave behind artifacts that could interfere with subsequent runs.

Comment on lines +410 to +413
public function getName(?string $key = null): string
{
return 'hash-memory';
}

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove unused parameter.

The $key parameter is never used in the method body.

🔧 Proposed fix
-    public function getName(?string $key = null): string
+    public function getName(): string
     {
         return 'hash-memory';
     }
📝 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
public function getName(?string $key = null): string
{
return 'hash-memory';
}
public function getName(): string
{
return 'hash-memory';
}
🧰 Tools
🪛 PHPMD (2.15.0)

[warning] 410-410: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)

🤖 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 `@tests/unit/FindCacheTest.php` around lines 410 - 413, The getName method in
the FindCacheTest.php file has an unused parameter $key that should be removed.
Update the method signature of getName to remove the ?string $key = null
parameter while keeping the return type as string and the return statement
unchanged.

Source: Linters/SAST tools

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