From 30df7a43d58f5eb98520076fabce7ea89c5707e1 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 18 Nov 2025 20:11:02 +0200 Subject: [PATCH] Refactor caching logic in XList to use JSON encoding for query serialization and update cache header keys to lowercase in tests --- .../Databases/Collections/Documents/XList.php | 19 +++++++++++++----- .../Databases/Legacy/DatabasesBase.php | 20 +++++++++---------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php index 0bb1748fb4..1d97b01b1c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php @@ -153,7 +153,7 @@ class XList extends Action $dbForProject->getNamespace(), $dbForProject->getTenant(), $collectionId, - \md5(\implode($serializedQueries)) + \md5(\json_encode($serializedQueries)) ); $documentsCacheKey = $cacheKeyBase . ':documents'; @@ -162,12 +162,21 @@ class XList extends Action $documentsCacheHit = $totalDocumentsCacheHit = false; $cachedDocuments = $dbForProject->cache->load($documentsCacheKey, $ttl); - if ($cachedDocuments !== null && $cachedDocuments !== false) { - $documents = $cachedDocuments; + if ($cachedDocuments !== null && + $cachedDocuments !== false && + \is_array($cachedDocuments)) { + $documents = \array_map(function ($doc){ + return new Document($doc); + }, $cachedDocuments); $documentsCacheHit = true; } else { $documents = $dbForProject->find($collectionTableId, $queries); - $dbForProject->cache->save($documentsCacheKey, $documents, $ttl); + + // Convert Document objects to arrays for caching + $documentsArray = \array_map(function ($doc) { + return $doc->getArrayCopy(); + }, $documents); + $dbForProject->cache->save($documentsCacheKey, $documentsArray); } $response->addHeader('X-Appwrite-Cache-Documents', $documentsCacheHit ? 'hit' : 'miss'); @@ -180,7 +189,7 @@ class XList extends Action $totalDocumentsCacheHit = true; } else { $total = $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT); - $dbForProject->cache->save($totalCacheKey, $total, $ttl); + $dbForProject->cache->save($totalCacheKey, $total); } } else { $total = 0; diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php index 7c75d20aba..45356604de 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php @@ -2406,10 +2406,10 @@ trait DatabasesBase $this->assertArrayHasKey('$id', $documents1['body']['documents'][0]); // First request should be MISS - $this->assertArrayHasKey('X-Appwrite-Cache-Documents', $documents1['headers']); - $this->assertEquals('miss', $documents1['headers']['X-Appwrite-Cache-Documents']); - $this->assertArrayHasKey('X-Appwrite-Cache-Documents-Total', $documents1['headers']); - $this->assertEquals('miss', $documents1['headers']['X-Appwrite-Cache-Documents-Total']); + $this->assertArrayHasKey('x-appwrite-cache-documents', $documents1['headers']); + $this->assertEquals('miss', $documents1['headers']['x-appwrite-cache-documents']); + $this->assertArrayHasKey('x-appwrite-cache-documents-total', $documents1['headers']); + $this->assertEquals('miss', $documents1['headers']['x-appwrite-cache-documents-total']); // Should return cached results $documents2 = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([ @@ -2433,10 +2433,10 @@ trait DatabasesBase $this->assertEquals($documents1['body']['documents'][0]['releaseYear'], $documents2['body']['documents'][0]['releaseYear']); // Second request should hit cache - $this->assertArrayHasKey('X-Appwrite-Cache-Documents', $documents2['headers']); - $this->assertEquals('hit', $documents2['headers']['X-Appwrite-Cache-Documents']); - $this->assertArrayHasKey('X-Appwrite-Cache-Documents-Total', $documents2['headers']); - $this->assertEquals('hit', $documents2['headers']['X-Appwrite-Cache-Documents-Total']); + $this->assertArrayHasKey('x-appwrite-cache-documents', $documents2['headers']); + $this->assertEquals('hit', $documents2['headers']['x-appwrite-cache-documents']); + $this->assertArrayHasKey('x-appwrite-cache-documents-total', $documents2['headers']); + $this->assertEquals('hit', $documents2['headers']['x-appwrite-cache-documents-total']); // useCache=false - should still work and no cache headers $documents3 = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([ @@ -2455,8 +2455,8 @@ trait DatabasesBase $this->assertEquals(1944, $documents3['body']['documents'][0]['releaseYear']); // Verify cache headers are not present when useCache=false - $this->assertArrayNotHasKey('X-Appwrite-Cache-Documents', $documents3['headers']); - $this->assertArrayNotHasKey('X-Appwrite-Cache-Documents-Total', $documents3['headers']); + $this->assertArrayNotHasKey('x-appwrite-cache-documents', $documents3['headers']); + $this->assertArrayNotHasKey('x-appwrite-cache-documents-total', $documents3['headers']); // Test with total=false $documents4 = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([