Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 093e262

Browse files
Guikingonechr-hertel
authored andcommitted
refactor(store): CacheStoreFactory introduced
1 parent b1863ed commit 093e262

7 files changed

Lines changed: 116 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
0.7
5+
---
6+
7+
* Introduce `StoreFactory`
8+
49
0.4
510
---
611

Store.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,18 @@ public function remove(string|array $ids, array $options = []): void
9191
return;
9292
}
9393

94+
if (!\is_array($existingVectors)) {
95+
throw new InvalidArgumentException('Existing vectors must be an array.');
96+
}
97+
9498
if (\is_string($ids)) {
9599
$ids = [$ids];
96100
}
97101

98-
$filteredVectors = array_filter($existingVectors, static fn (array $document) => !\in_array($document['id'], $ids, true));
102+
$filteredVectors = array_filter(
103+
$existingVectors,
104+
static fn (array $document): bool => !\in_array($document['id'], $ids, true),
105+
);
99106

100107
$cacheItem->set(array_values($filteredVectors));
101108
$this->cache->save($cacheItem);
@@ -187,7 +194,7 @@ private function queryText(TextQuery $query, array $options): iterable
187194
$vectorDocuments = array_values(array_filter($vectorDocuments, $options['filter']));
188195
}
189196

190-
$filteredDocuments = array_filter($vectorDocuments, static function (VectorDocument $doc) use ($query) {
197+
$filteredDocuments = array_filter($vectorDocuments, static function (VectorDocument $doc) use ($query): bool {
191198
$text = strtolower($doc->getMetadata()->getText() ?? '');
192199

193200
foreach ($query->getTexts() as $searchText) {

StoreFactory.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Store\Bridge\Cache;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\AI\Store\Distance\DistanceCalculator;
16+
use Symfony\AI\Store\Distance\DistanceStrategy;
17+
use Symfony\AI\Store\ManagedStoreInterface;
18+
use Symfony\AI\Store\StoreInterface;
19+
use Symfony\Contracts\Cache\CacheInterface;
20+
21+
/**
22+
* @author Guillaume Loulier <[email protected]>
23+
*/
24+
final class StoreFactory
25+
{
26+
public static function create(
27+
CacheInterface&CacheItemPoolInterface $cache,
28+
string $key,
29+
string $strategy = 'cosine',
30+
): ManagedStoreInterface&StoreInterface {
31+
return new Store($cache, new DistanceCalculator(DistanceStrategy::from($strategy)), $key);
32+
}
33+
}

Tests/IntegrationTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Store\Bridge\Cache\Tests;
13+
14+
use PHPUnit\Framework\Attributes\Group;
15+
use Symfony\AI\Store\Bridge\Cache\StoreFactory;
16+
use Symfony\AI\Store\StoreInterface;
17+
use Symfony\AI\Store\Test\AbstractStoreIntegrationTestCase;
18+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
19+
20+
/**
21+
* @author Guillaume Loulier <[email protected]>
22+
*/
23+
#[Group('integration')]
24+
final class IntegrationTest extends AbstractStoreIntegrationTestCase
25+
{
26+
protected static function createStore(): StoreInterface
27+
{
28+
return StoreFactory::create(new ArrayAdapter(), 'foo');
29+
}
30+
}

Tests/StoreFactoryTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Store\Bridge\Cache\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\AI\Store\Bridge\Cache\Store;
16+
use Symfony\AI\Store\Bridge\Cache\StoreFactory;
17+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
18+
19+
final class StoreFactoryTest extends TestCase
20+
{
21+
public function testStoreCanBeCreated()
22+
{
23+
$store = StoreFactory::create(new ArrayAdapter(), 'foo');
24+
$this->assertInstanceOf(Store::class, $store);
25+
}
26+
}

Tests/StoreTest.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
use Symfony\AI\Store\Document\Metadata;
2020
use Symfony\AI\Store\Document\VectorDocument;
2121
use Symfony\AI\Store\Exception\InvalidArgumentException;
22+
use Symfony\AI\Store\Exception\UnsupportedQueryTypeException;
2223
use Symfony\AI\Store\Query\HybridQuery;
24+
use Symfony\AI\Store\Query\QueryInterface;
2325
use Symfony\AI\Store\Query\TextQuery;
2426
use Symfony\AI\Store\Query\VectorQuery;
2527
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -178,7 +180,7 @@ public function testStoreCanSearchWithFilter()
178180
]);
179181

180182
$result = iterator_to_array($store->query(new VectorQuery(new Vector([0.0, 0.1, 0.6])), [
181-
'filter' => static fn (VectorDocument $doc) => 'products' === $doc->getMetadata()['category'],
183+
'filter' => static fn (VectorDocument $doc): bool => 'products' === $doc->getMetadata()['category'],
182184
]));
183185

184186
$this->assertCount(2, $result);
@@ -197,7 +199,7 @@ public function testStoreCanSearchWithFilterAndMaxItems()
197199
]);
198200

199201
$result = iterator_to_array($store->query(new VectorQuery(new Vector([0.0, 0.1, 0.6])), [
200-
'filter' => static fn (VectorDocument $doc) => 'products' === $doc->getMetadata()['category'],
202+
'filter' => static fn (VectorDocument $doc): bool => 'products' === $doc->getMetadata()['category'],
201203
'maxItems' => 2,
202204
]));
203205

@@ -216,7 +218,7 @@ public function testStoreCanSearchWithComplexFilter()
216218
]);
217219

218220
$result = iterator_to_array($store->query(new VectorQuery(new Vector([0.0, 0.1, 0.6])), [
219-
'filter' => static fn (VectorDocument $doc) => $doc->getMetadata()['price'] <= 150 && $doc->getMetadata()['stock'] > 0,
221+
'filter' => static fn (VectorDocument $doc): bool => $doc->getMetadata()['price'] <= 150 && $doc->getMetadata()['stock'] > 0,
220222
]));
221223

222224
$this->assertCount(2, $result);
@@ -232,7 +234,7 @@ public function testStoreCanSearchWithNestedMetadataFilter()
232234
]);
233235

234236
$result = iterator_to_array($store->query(new VectorQuery(new Vector([0.0, 0.1, 0.6])), [
235-
'filter' => static fn (VectorDocument $doc) => 'S' === $doc->getMetadata()['options']['size'],
237+
'filter' => static fn (VectorDocument $doc): bool => 'S' === $doc->getMetadata()['options']['size'],
236238
]));
237239

238240
$this->assertCount(2, $result);
@@ -251,7 +253,7 @@ public function testStoreCanSearchWithInArrayFilter()
251253

252254
$allowedBrands = ['Nike', 'Adidas', 'Puma'];
253255
$result = iterator_to_array($store->query(new VectorQuery(new Vector([0.0, 0.1, 0.6])), [
254-
'filter' => static fn (VectorDocument $doc) => \in_array($doc->getMetadata()['brand'] ?? '', $allowedBrands, true),
256+
'filter' => static fn (VectorDocument $doc): bool => \in_array($doc->getMetadata()['brand'] ?? '', $allowedBrands, true),
255257
]));
256258

257259
$this->assertCount(2, $result);
@@ -394,6 +396,7 @@ public function testStoreCanSearchUsingTextQuery()
394396
$result = iterator_to_array($store->query(new TextQuery('quick brown')));
395397

396398
$this->assertCount(1, $result);
399+
$this->assertNotNull($result[0]->getMetadata()->getText());
397400
$this->assertStringContainsString('quick brown', $result[0]->getMetadata()->getText());
398401
}
399402

@@ -458,7 +461,7 @@ public function testHybridQueryThrowsExceptionForInvalidSemanticRatio()
458461
{
459462
$this->expectException(InvalidArgumentException::class);
460463
$this->expectExceptionMessage('Semantic ratio must be between 0.0 and 1.0');
461-
464+
$this->expectExceptionCode(0);
462465
new HybridQuery(new Vector([0.1, 0.2, 0.3]), 'test', 1.5);
463466
}
464467

@@ -467,12 +470,12 @@ public function testStoreThrowsExceptionForUnsupportedQueryType()
467470
$store = new Store(new ArrayAdapter());
468471

469472
// Create a mock query type that Cache store doesn't support
470-
$unsupportedQuery = new class implements \Symfony\AI\Store\Query\QueryInterface {
473+
$unsupportedQuery = new class implements QueryInterface {
471474
};
472475

473-
$this->expectException(\Symfony\AI\Store\Exception\UnsupportedQueryTypeException::class);
476+
$this->expectException(UnsupportedQueryTypeException::class);
474477
$this->expectExceptionMessageMatches('/not supported/');
475-
478+
$this->expectExceptionCode(0);
476479
$store->query($unsupportedQuery);
477480
}
478481

phpstan.dist.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ includes:
33
- ../../../../../.phpstan/extension.neon
44

55
parameters:
6-
level: 6
6+
level: 8
77
paths:
88
- .
99
- Tests/

0 commit comments

Comments
 (0)