mirror of
https://github.com/symfony/ai.git
synced 2026-03-23 23:42:18 +01:00
Implement remove() method for Supabase
This commit is contained in:
@@ -16,7 +16,6 @@ use Symfony\AI\Store\Document\Metadata;
|
||||
use Symfony\AI\Store\Document\VectorDocument;
|
||||
use Symfony\AI\Store\Exception\InvalidArgumentException;
|
||||
use Symfony\AI\Store\Exception\RuntimeException;
|
||||
use Symfony\AI\Store\Exception\UnsupportedFeatureException;
|
||||
use Symfony\AI\Store\StoreInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
@@ -95,7 +94,37 @@ final class Store implements StoreInterface
|
||||
|
||||
public function remove(string|array $ids, array $options = []): void
|
||||
{
|
||||
throw new UnsupportedFeatureException('Method not implemented yet.');
|
||||
if (\is_string($ids)) {
|
||||
$ids = [$ids];
|
||||
}
|
||||
|
||||
if (0 === \count($ids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Supabase REST API supports batch deletes using the 'in' filter
|
||||
// We'll chunk the ids to avoid potential URL length limits
|
||||
$chunkSize = 200;
|
||||
|
||||
foreach (array_chunk($ids, $chunkSize) as $chunk) {
|
||||
$idsString = implode(',', array_map(static fn ($id) => '"'.str_replace('"', '""', $id).'"', $chunk));
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
'DELETE',
|
||||
\sprintf('%s/rest/v1/%s?id=in.(%s)', $this->url, $this->table, $idsString),
|
||||
[
|
||||
'headers' => [
|
||||
'apikey' => $this->apiKey,
|
||||
'Authorization' => 'Bearer '.$this->apiKey,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
throw new RuntimeException('Supabase delete failed: '.$response->getContent(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -218,6 +218,77 @@ class StoreTest extends TestCase
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testRemoveSingleDocument()
|
||||
{
|
||||
$httpClient = new MockHttpClient(new MockResponse('', ['http_code' => 204]));
|
||||
$store = $this->createStore($httpClient);
|
||||
$documentId = 'doc-id-123';
|
||||
|
||||
$store->remove($documentId);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testRemoveMultipleDocuments()
|
||||
{
|
||||
$httpClient = new MockHttpClient(new MockResponse('', ['http_code' => 204]));
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->remove(['doc-id-1', 'doc-id-2', 'doc-id-3']);
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testRemoveEmptyArrayDoesNothing()
|
||||
{
|
||||
$httpClient = new MockHttpClient();
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->remove([]);
|
||||
|
||||
$this->assertSame(0, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testRemoveThrowsExceptionOnHttpError()
|
||||
{
|
||||
$httpClient = new MockHttpClient(new MockResponse('Delete failed', ['http_code' => 400]));
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('Supabase delete failed: Delete failed');
|
||||
$store->remove('doc-id-123');
|
||||
}
|
||||
|
||||
public function testRemoveChunksLargeNumberOfIds()
|
||||
{
|
||||
$httpClient = new MockHttpClient([
|
||||
new MockResponse('', ['http_code' => 204]),
|
||||
new MockResponse('', ['http_code' => 204]),
|
||||
new MockResponse('', ['http_code' => 204]),
|
||||
]);
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$ids = [];
|
||||
for ($i = 0; $i < 401; ++$i) {
|
||||
$ids[] = 'doc-id-'.$i;
|
||||
}
|
||||
|
||||
$store->remove($ids);
|
||||
|
||||
// Should make 3 API calls with chunks of: 200 + 200 + 1
|
||||
$this->assertSame(3, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testRemoveWithSpecialCharactersInId()
|
||||
{
|
||||
$httpClient = new MockHttpClient(new MockResponse('', ['http_code' => 204]));
|
||||
$store = $this->createStore($httpClient);
|
||||
|
||||
$store->remove('id-with-"quotes"');
|
||||
|
||||
$this->assertSame(1, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
private function createStore(MockHttpClient $httpClient, ?int $vectorDimension = 2): SupabaseStore
|
||||
{
|
||||
return new SupabaseStore(
|
||||
|
||||
Reference in New Issue
Block a user