diff --git a/src/Database/Database.php b/src/Database/Database.php index 74e75d883..36fc33551 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -8611,7 +8611,7 @@ public function purgeCachedQueries(string $collection, ?string $namespace = null * @throws AuthorizationException * @throws Exception */ - public function withCache( + private function withCache( string $key, callable $callback, ?string $hash = '', diff --git a/tests/unit/QueryCacheTest.php b/tests/unit/QueryCacheTest.php index 8103a0dd2..b8449eede 100644 --- a/tests/unit/QueryCacheTest.php +++ b/tests/unit/QueryCacheTest.php @@ -29,6 +29,23 @@ private function createDatabase(Adapter $cache, array $filters = [], ?DatabaseMe return $database; } + /** + * @template T + * @param callable(): T $callback + * @return T + */ + private function withCache( + Database $database, + string $key, + callable $callback, + ?string $hash = '', + ): mixed { + $method = new \ReflectionMethod(Database::class, 'withCache'); + + /** @var T */ + return $method->invoke($database, $key, $callback, $hash); + } + /** * @param array $queries * @return array @@ -49,7 +66,8 @@ private function findWithCache( $cacheKey = $database->getQueryCacheKey($collectionDocument->getId(), $namespace); $cacheHash = $database->getQueryCacheField($collectionDocument, $queries); - return $database->withCache( + return $this->withCache( + $database, key: $cacheKey, callback: fn (): array => $database->find($collection, $queries), hash: $cacheHash, @@ -63,7 +81,8 @@ public function testWithCacheUsesCallbackOnMissAndCachesResult(): void $callbackCalls = 0; - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): array { $callbackCalls++; @@ -74,7 +93,8 @@ function () use (&$callbackCalls): array { $this->assertSame(['value' => 'fresh'], $value); $this->assertSame(1, $callbackCalls); - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): array { $callbackCalls++; @@ -93,7 +113,8 @@ public function testWithCacheCachesEmptyValues(): void $callbackCalls = 0; - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): array { $callbackCalls++; @@ -103,7 +124,8 @@ function () use (&$callbackCalls): array { $this->assertSame([], $value); - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): array { $callbackCalls++; @@ -122,7 +144,8 @@ public function testWithCacheCachesNullValues(): void $callbackCalls = 0; - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): mixed { $callbackCalls++; @@ -132,7 +155,8 @@ function () use (&$callbackCalls): mixed { $this->assertNull($value); - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): string { $callbackCalls++; @@ -152,7 +176,8 @@ public function testWithCacheSeparatesPayloadsByHashField(): void $firstCalls = 0; $secondCalls = 0; - $first = $database->withCache( + $first = $this->withCache( + $database, 'key', function () use (&$firstCalls): array { $firstCalls++; @@ -161,7 +186,8 @@ function () use (&$firstCalls): array { 'first-field', ); - $second = $database->withCache( + $second = $this->withCache( + $database, 'key', function () use (&$secondCalls): array { $secondCalls++; @@ -170,7 +196,8 @@ function () use (&$secondCalls): array { 'second-field', ); - $cachedFirst = $database->withCache( + $cachedFirst = $this->withCache( + $database, 'key', function () use (&$firstCalls): array { $firstCalls++; @@ -194,7 +221,8 @@ public function testWithCacheDoesNotCacheFalseValues(): void $callbackCalls = 0; - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): bool { $callbackCalls++; @@ -205,7 +233,8 @@ function () use (&$callbackCalls): bool { $this->assertFalse($value); $this->assertSame([], $cache->list('key')); - $value = $database->withCache( + $value = $this->withCache( + $database, 'key', function () use (&$callbackCalls): string { $callbackCalls++; @@ -224,7 +253,8 @@ public function testWithCacheBypassesCacheForNullHash(): void $callbackCalls = 0; - $first = $database->withCache( + $first = $this->withCache( + $database, key: 'key', callback: function () use (&$callbackCalls): string { $callbackCalls++; @@ -232,7 +262,8 @@ public function testWithCacheBypassesCacheForNullHash(): void }, hash: null, ); - $second = $database->withCache( + $second = $this->withCache( + $database, key: 'key', callback: function () use (&$callbackCalls): string { $callbackCalls++; @@ -254,14 +285,16 @@ public function testWithCacheDoesNotCacheCollectionlessDocuments(): void $callbackCalls = 0; - $first = $database->withCache( + $first = $this->withCache( + $database, key: 'key', callback: function () use (&$callbackCalls): Document { $callbackCalls++; return new Document(['$id' => 'first']); }, ); - $second = $database->withCache( + $second = $this->withCache( + $database, key: 'key', callback: function () use (&$callbackCalls): Document { $callbackCalls++; @@ -290,14 +323,16 @@ public function testWithCacheDoesNotCacheMixedDocumentArrays(): void $callbackCalls = 0; - $first = $database->withCache( + $first = $this->withCache( + $database, key: 'key', callback: function () use ($database, &$callbackCalls): array { $callbackCalls++; return ['prefix', $database->getDocument('wafRules', 'rule-a')]; }, ); - $second = $database->withCache( + $second = $this->withCache( + $database, key: 'key', callback: function () use ($database, &$callbackCalls): array { $callbackCalls++; @@ -329,7 +364,8 @@ public function testWithCacheCachesSingleDocument(): void $key = $database->getQueryCacheKey($collection->getId(), '_39'); $hash = $database->getQueryCacheField($collection, field: 'document'); - $first = $database->withCache( + $first = $this->withCache( + $database, key: $key, callback: function () use ($database, &$callbackCalls): Document { $callbackCalls++; @@ -337,7 +373,8 @@ public function testWithCacheCachesSingleDocument(): void }, hash: $hash, ); - $second = $database->withCache( + $second = $this->withCache( + $database, key: $key, callback: function () use ($database, &$callbackCalls): Document { $callbackCalls++; @@ -364,7 +401,8 @@ public function testWithCacheCachesStaticQueryValues(): void $key = $database->getQueryCacheKey($collection->getId(), '_39'); $hash = $database->getQueryCacheField($collection, field: 'count'); - $first = $database->withCache( + $first = $this->withCache( + $database, key: $key, callback: function () use (&$callbackCalls): int { $callbackCalls++; @@ -372,7 +410,8 @@ public function testWithCacheCachesStaticQueryValues(): void }, hash: $hash, ); - $second = $database->withCache( + $second = $this->withCache( + $database, key: $key, callback: function () use (&$callbackCalls): int { $callbackCalls++; @@ -694,7 +733,8 @@ public function testQueryCacheFiltersDocumentSecurityPayloadsOnHit(): void ], $hash); $callbackCalls = 0; - $documents = $database->withCache( + $documents = $this->withCache( + $database, key: $key, callback: function () use (&$callbackCalls): array { $callbackCalls++; diff --git a/tests/unit/WithCacheLeaseTest.php b/tests/unit/WithCacheLeaseTest.php index 8eafd3540..91bd9926a 100644 --- a/tests/unit/WithCacheLeaseTest.php +++ b/tests/unit/WithCacheLeaseTest.php @@ -42,6 +42,22 @@ protected function setUp(): void $this->key = $this->database->getQueryCacheKey('projects'); } + /** + * @template T + * @param callable(): T $callback + * @return T + */ + private function withCache( + string $key, + callable $callback, + ?string $hash = '', + ): mixed { + $method = new \ReflectionMethod(Database::class, 'withCache'); + + /** @var T */ + return $method->invoke($this->database, $key, $callback, $hash); + } + public function testStaleListWriteAfterConcurrentPurgeIsRejected(): void { $hash = 'list-hash'; @@ -52,7 +68,7 @@ public function testStaleListWriteAfterConcurrentPurgeIsRejected(): void // concurrent writer purges the query key after the read started but // before the result is cached. Without a lease the stale list below // would land in the cache after the purge. - $result = $this->database->withCache($this->key, function () use ($hash, $document) { + $result = $this->withCache($this->key, function () use ($hash, $document) { $this->cacheAdapter->purge($this->key, $hash); return [$document]; @@ -71,7 +87,7 @@ public function testListWriteLandsWhenNoConcurrentPurge(): void $document = $this->database->getDocument('projects', 'project'); - $result = $this->database->withCache($this->key, fn () => [$document], $hash); + $result = $this->withCache($this->key, fn () => [$document], $hash); $this->assertCount(1, $result); $this->assertNotFalse(