Skip to content

Commit 4da5599

Browse files
committed
ref
1 parent 403d388 commit 4da5599

File tree

8 files changed

+107
-62
lines changed

8 files changed

+107
-62
lines changed

examples/chat/persistent-chat-doctrine.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use Doctrine\DBAL\DriverManager;
1313
use Doctrine\DBAL\Tools\DsnParser;
1414
use Symfony\AI\Agent\Agent;
15-
use Symfony\AI\Chat\Bridge\Doctrine\OrmMessageStore;
15+
use Symfony\AI\Chat\Bridge\Doctrine\DoctrineDbalMessageStore;
1616
use Symfony\AI\Chat\Chat;
1717
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
1818
use Symfony\AI\Platform\Message\Message;
@@ -22,9 +22,9 @@
2222

2323
$platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client());
2424

25-
$doctrine = DriverManager::getConnection((new DsnParser())->parse('pdo-sqlite:///:memory:'));
25+
$connection = DriverManager::getConnection((new DsnParser())->parse('pdo-sqlite:///:memory:'));
2626

27-
$store = new OrmMessageStore('symfony', $doctrine);
27+
$store = new DoctrineDbalMessageStore('symfony', $connection);
2828
$store->setup();
2929

3030
$agent = new Agent($platform, 'gpt-4o-mini');

examples/commands/message-stores.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use Doctrine\DBAL\DriverManager;
1515
use Doctrine\DBAL\Tools\DsnParser;
16-
use Symfony\AI\Chat\Bridge\Doctrine\OrmMessageStore;
16+
use Symfony\AI\Chat\Bridge\Doctrine\DoctrineDbalMessageStore;
1717
use Symfony\AI\Chat\Bridge\HttpFoundation\SessionStore;
1818
use Symfony\AI\Chat\Bridge\Local\CacheStore;
1919
use Symfony\AI\Chat\Bridge\Local\InMemoryStore;
@@ -39,7 +39,7 @@
3939

4040
$factories = [
4141
'cache' => static fn (): CacheStore => new CacheStore(new ArrayAdapter(), cacheKey: 'symfony'),
42-
'doctrine' => static fn (): OrmMessageStore => new OrmMessageStore(
42+
'doctrine' => static fn (): DoctrineDbalMessageStore => new DoctrineDbalMessageStore(
4343
'symfony',
4444
DriverManager::getConnection((new DsnParser())->parse('pdo-sqlite:///:memory:')),
4545
),

src/ai-bundle/config/options.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@
788788
->end()
789789
->arrayNode('doctrine')
790790
->children()
791-
->arrayNode('orm')
791+
->arrayNode('dbal')
792792
->useAttributeAsKey('name')
793793
->arrayPrototype()
794794
->children()

src/ai-bundle/src/AiBundle.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
use Symfony\AI\AiBundle\Profiler\TraceablePlatform;
3737
use Symfony\AI\AiBundle\Profiler\TraceableToolbox;
3838
use Symfony\AI\AiBundle\Security\Attribute\IsGrantedTool;
39-
use Symfony\AI\Chat\Bridge\Doctrine\OrmMessageStore;
39+
use Symfony\AI\Chat\Bridge\Doctrine\DoctrineDbalMessageStore;
4040
use Symfony\AI\Chat\Bridge\HttpFoundation\SessionStore;
4141
use Symfony\AI\Chat\Bridge\Local\CacheStore as CacheMessageStore;
4242
use Symfony\AI\Chat\Bridge\Meilisearch\MessageStore as MeilisearchMessageStore;
@@ -1497,8 +1497,8 @@ private function processMessageStoreConfig(string $type, array $messageStores, C
14971497
}
14981498

14991499
if ('doctrine' === $type) {
1500-
foreach ($messageStores['orm'] ?? [] as $name => $ormMessageStore) {
1501-
$definition = new Definition(OrmMessageStore::class);
1500+
foreach ($messageStores['dbal'] ?? [] as $name => $ormMessageStore) {
1501+
$definition = new Definition(DoctrineDbalMessageStore::class);
15021502
$definition
15031503
->setLazy(true)
15041504
->setArguments([
@@ -1510,7 +1510,7 @@ private function processMessageStoreConfig(string $type, array $messageStores, C
15101510
->addTag('proxy', ['interface' => MessageStoreInterface::class])
15111511
->addTag('ai.message_store');
15121512

1513-
$container->setDefinition('ai.message_store.'.$type.'.orm.'.$name, $definition);
1513+
$container->setDefinition('ai.message_store.'.$type.'.dbal.'.$name, $definition);
15141514
$container->registerAliasForArgument('ai.message_store.'.$type.'.'.$name, MessageStoreInterface::class, $name);
15151515
$container->registerAliasForArgument('ai.message_store.'.$type.'.'.$name, MessageStoreInterface::class, $type.'_'.$name);
15161516
}

src/ai-bundle/tests/DependencyInjection/AiBundleTest.php

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,7 +2857,7 @@ public function testDoctrineOrmMessageStoreCanBeConfiguredWithCustomKey()
28572857
'ai' => [
28582858
'message_store' => [
28592859
'doctrine' => [
2860-
'orm' => [
2860+
'dbal' => [
28612861
'default' => [
28622862
'connection' => 'default',
28632863
],
@@ -2867,18 +2867,18 @@ public function testDoctrineOrmMessageStoreCanBeConfiguredWithCustomKey()
28672867
],
28682868
]);
28692869

2870-
$doctrineOrmDefaultMessageStoreDefinition = $container->getDefinition('ai.message_store.doctrine.orm.default');
2870+
$doctrineDbalDefaultMessageStoreDefinition = $container->getDefinition('ai.message_store.doctrine.dbal.default');
28712871

2872-
$this->assertSame('default', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(0));
2873-
$this->assertSame('default', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(1));
2874-
$this->assertInstanceOf(Reference::class, $doctrineOrmDefaultMessageStoreDefinition->getArgument(2));
2875-
$this->assertSame('doctrine', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(2));
2876-
$this->assertInstanceOf(Reference::class, $doctrineOrmDefaultMessageStoreDefinition->getArgument(3));
2877-
$this->assertSame('serializer', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(3));
2872+
$this->assertSame('default', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(0));
2873+
$this->assertSame('default', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(1));
2874+
$this->assertInstanceOf(Reference::class, $doctrineDbalDefaultMessageStoreDefinition->getArgument(2));
2875+
$this->assertSame('doctrine', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(2));
2876+
$this->assertInstanceOf(Reference::class, $doctrineDbalDefaultMessageStoreDefinition->getArgument(3));
2877+
$this->assertSame('serializer', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(3));
28782878

2879-
$this->assertTrue($doctrineOrmDefaultMessageStoreDefinition->hasTag('proxy'));
2880-
$this->assertSame([['interface' => MessageStoreInterface::class]], $doctrineOrmDefaultMessageStoreDefinition->getTag('proxy'));
2881-
$this->assertTrue($doctrineOrmDefaultMessageStoreDefinition->hasTag('ai.message_store'));
2879+
$this->assertTrue($doctrineDbalDefaultMessageStoreDefinition->hasTag('proxy'));
2880+
$this->assertSame([['interface' => MessageStoreInterface::class]], $doctrineDbalDefaultMessageStoreDefinition->getTag('proxy'));
2881+
$this->assertTrue($doctrineDbalDefaultMessageStoreDefinition->hasTag('ai.message_store'));
28822882
}
28832883

28842884
public function testDoctrineOrmMessageStoreWithCustomTableNameCanBeConfiguredWithCustomKey()
@@ -2887,7 +2887,7 @@ public function testDoctrineOrmMessageStoreWithCustomTableNameCanBeConfiguredWit
28872887
'ai' => [
28882888
'message_store' => [
28892889
'doctrine' => [
2890-
'orm' => [
2890+
'dbal' => [
28912891
'default' => [
28922892
'connection' => 'default',
28932893
'table_name' => 'foo',
@@ -2898,18 +2898,18 @@ public function testDoctrineOrmMessageStoreWithCustomTableNameCanBeConfiguredWit
28982898
],
28992899
]);
29002900

2901-
$doctrineOrmDefaultMessageStoreDefinition = $container->getDefinition('ai.message_store.doctrine.orm.default');
2901+
$doctrineDbalDefaultMessageStoreDefinition = $container->getDefinition('ai.message_store.doctrine.dbal.default');
29022902

2903-
$this->assertSame('default', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(0));
2904-
$this->assertSame('foo', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(1));
2905-
$this->assertInstanceOf(Reference::class, $doctrineOrmDefaultMessageStoreDefinition->getArgument(2));
2906-
$this->assertSame('doctrine', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(2));
2907-
$this->assertInstanceOf(Reference::class, $doctrineOrmDefaultMessageStoreDefinition->getArgument(3));
2908-
$this->assertSame('serializer', (string) $doctrineOrmDefaultMessageStoreDefinition->getArgument(3));
2903+
$this->assertSame('default', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(0));
2904+
$this->assertSame('foo', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(1));
2905+
$this->assertInstanceOf(Reference::class, $doctrineDbalDefaultMessageStoreDefinition->getArgument(2));
2906+
$this->assertSame('doctrine', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(2));
2907+
$this->assertInstanceOf(Reference::class, $doctrineDbalDefaultMessageStoreDefinition->getArgument(3));
2908+
$this->assertSame('serializer', (string) $doctrineDbalDefaultMessageStoreDefinition->getArgument(3));
29092909

2910-
$this->assertTrue($doctrineOrmDefaultMessageStoreDefinition->hasTag('proxy'));
2911-
$this->assertSame([['interface' => MessageStoreInterface::class]], $doctrineOrmDefaultMessageStoreDefinition->getTag('proxy'));
2912-
$this->assertTrue($doctrineOrmDefaultMessageStoreDefinition->hasTag('ai.message_store'));
2910+
$this->assertTrue($doctrineDbalDefaultMessageStoreDefinition->hasTag('proxy'));
2911+
$this->assertSame([['interface' => MessageStoreInterface::class]], $doctrineDbalDefaultMessageStoreDefinition->getTag('proxy'));
2912+
$this->assertTrue($doctrineDbalDefaultMessageStoreDefinition->hasTag('ai.message_store'));
29132913
}
29142914

29152915
public function testMeilisearchMessageStoreIsConfigured()
@@ -3412,7 +3412,7 @@ private function getFullConfig(): array
34123412
],
34133413
],
34143414
'doctrine' => [
3415-
'orm' => [
3415+
'dbal' => [
34163416
'default' => [
34173417
'connection' => 'default',
34183418
'table_name' => 'foo',

src/chat/composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"require-dev": {
2828
"ext-redis": "*",
2929
"doctrine/dbal": "^3.3 || ^4.0",
30-
"doctrine/persistence": "^1.3|^2|^3",
3130
"phpstan/phpstan": "^2.0",
3231
"phpstan/phpstan-strict-rules": "^2.0",
3332
"phpunit/phpunit": "^11.5.13",

src/chat/src/Bridge/Doctrine/OrmMessageStore.php renamed to src/chat/src/Bridge/Doctrine/DoctrineDbalMessageStore.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
/**
3535
* @author Guillaume Loulier <[email protected]>
3636
*/
37-
final class OrmMessageStore implements ManagedStoreInterface, MessageStoreInterface
37+
final class DoctrineDbalMessageStore implements ManagedStoreInterface, MessageStoreInterface
3838
{
3939
public function __construct(
4040
private readonly string $tableName,

src/chat/tests/Bridge/Doctrine/OrmMessageStoreTest.php renamed to src/chat/tests/Bridge/Doctrine/DoctrineDbalMessageStoreTest.php

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,28 @@
1212
namespace Symfony\AI\Chat\Tests\Bridge\Doctrine;
1313

1414
use Doctrine\DBAL\Connection;
15+
use Doctrine\DBAL\Query\QueryBuilder;
16+
use Doctrine\DBAL\Result;
1517
use Doctrine\DBAL\Schema\Schema;
1618
use Doctrine\DBAL\Schema\SQLiteSchemaManager;
1719
use Doctrine\DBAL\Schema\Table;
18-
use Doctrine\Persistence\ConnectionRegistry;
1920
use PHPUnit\Framework\TestCase;
20-
use Symfony\AI\Chat\Bridge\Doctrine\OrmMessageStore;
21+
use Symfony\AI\Chat\Bridge\Doctrine\DoctrineDbalMessageStore;
2122
use Symfony\AI\Chat\Exception\InvalidArgumentException;
22-
23-
final class OrmMessageStoreTest extends TestCase
23+
use Symfony\AI\Chat\MessageNormalizer;
24+
use Symfony\AI\Platform\Message\Message;
25+
use Symfony\AI\Platform\Message\MessageBag;
26+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
27+
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
28+
use Symfony\Component\Serializer\Serializer;
29+
30+
final class DoctrineDbalMessageStoreTest extends TestCase
2431
{
2532
public function testMessageStoreTableCannotBeSetupWithExtraOptions()
2633
{
2734
$connection = $this->createMock(Connection::class);
2835

29-
$registry = $this->createMock(ConnectionRegistry::class);
30-
$registry->expects($this->once())->method('getConnection')->willReturn($connection);
31-
32-
$messageStore = new OrmMessageStore('foo', 'bar', $registry);
36+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
3337

3438
$this->expectException(InvalidArgumentException::class);
3539
$this->expectExceptionMessage('No supported options.');
@@ -50,77 +54,119 @@ public function testMessageStoreTableCannotBeSetupIfItAlreadyExist()
5054
$connection = $this->createMock(Connection::class);
5155
$connection->expects($this->once())->method('createSchemaManager')->willReturn($sqliteSchemaManager);
5256

53-
$registry = $this->createMock(ConnectionRegistry::class);
54-
$registry->expects($this->once())->method('getConnection')->willReturn($connection);
55-
56-
$messageStore = new OrmMessageStore('foo', 'bar', $registry);
57+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
5758
$messageStore->setup();
5859
}
5960

6061
public function testMessageStoreTableCanBeSetup()
6162
{
6263
$table = $this->createMock(Table::class);
64+
$table->expects($this->once())->method('addOption')
65+
->with('_symfony_ai_chat_table_name', 'foo')
66+
->willReturnSelf();
6367

6468
$schema = $this->createMock(Schema::class);
6569
$schema->expects($this->once())->method('hasTable')->willReturn(false);
66-
$schema->expects($this->once())->method('createTable')->with('bar')->willReturn($table);
70+
$schema->expects($this->once())->method('createTable')->with('foo')->willReturn($table);
6771

6872
$sqliteSchemaManager = $this->createMock(SQLiteSchemaManager::class);
6973
$sqliteSchemaManager->expects($this->once())->method('introspectSchema')->willReturn($schema);
7074

7175
$connection = $this->createMock(Connection::class);
7276
$connection->expects($this->once())->method('createSchemaManager')->willReturn($sqliteSchemaManager);
7377

74-
$registry = $this->createMock(ConnectionRegistry::class);
75-
$registry->expects($this->once())->method('getConnection')->willReturn($connection);
76-
77-
$messageStore = new OrmMessageStore('foo', 'bar', $registry);
78+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
7879
$messageStore->setup();
7980
}
8081

8182
public function testMessageStoreTableCannotBeDroppedIfTableDoesNotExist()
8283
{
84+
$queryBuilder = $this->createMock(QueryBuilder::class);
85+
$queryBuilder->expects($this->never())->method('delete');
86+
8387
$schema = $this->createMock(Schema::class);
8488
$schema->expects($this->once())->method('hasTable')->willReturn(false);
85-
$schema->expects($this->never())->method('dropTable');
8689

8790
$sqliteSchemaManager = $this->createMock(SQLiteSchemaManager::class);
8891
$sqliteSchemaManager->expects($this->once())->method('introspectSchema')->willReturn($schema);
8992

9093
$connection = $this->createMock(Connection::class);
9194
$connection->expects($this->once())->method('createSchemaManager')->willReturn($sqliteSchemaManager);
95+
$connection->expects($this->never())->method('createQueryBuilder');
96+
$connection->expects($this->never())->method('transactional');
9297

93-
$registry = $this->createMock(ConnectionRegistry::class);
94-
$registry->expects($this->once())->method('getConnection')->willReturn($connection);
95-
96-
$messageStore = new OrmMessageStore('foo', 'bar', $registry);
98+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
9799
$messageStore->drop();
98100
}
99101

100102
public function testMessageStoreTableCanBeDropped()
101103
{
104+
$queryBuilder = $this->createMock(QueryBuilder::class);
105+
$queryBuilder->expects($this->once())->method('delete')->with('foo');
106+
102107
$schema = $this->createMock(Schema::class);
103108
$schema->expects($this->once())->method('hasTable')->willReturn(true);
104-
$schema->expects($this->once())->method('dropTable')->with('bar');
105109

106110
$sqliteSchemaManager = $this->createMock(SQLiteSchemaManager::class);
107111
$sqliteSchemaManager->expects($this->once())->method('introspectSchema')->willReturn($schema);
108112

109113
$connection = $this->createMock(Connection::class);
110114
$connection->expects($this->once())->method('createSchemaManager')->willReturn($sqliteSchemaManager);
115+
$connection->expects($this->once())->method('createQueryBuilder')->willReturn($queryBuilder);
116+
$connection->expects($this->once())->method('transactional');
111117

112-
$registry = $this->createMock(ConnectionRegistry::class);
113-
$registry->expects($this->once())->method('getConnection')->willReturn($connection);
114-
115-
$messageStore = new OrmMessageStore('foo', 'bar', $registry);
118+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
116119
$messageStore->drop();
117120
}
118121

119122
public function testMessageBagCanBeSaved()
120123
{
124+
$queryBuilder = $this->createMock(QueryBuilder::class);
125+
$queryBuilder->expects($this->once())->method('insert')->with('foo')->willReturnSelf();
126+
$queryBuilder->expects($this->once())->method('values')->with([
127+
'messages' => '?',
128+
])->willReturnSelf();
129+
130+
$connection = $this->createMock(Connection::class);
131+
$connection->expects($this->once())->method('createQueryBuilder')->willReturn($queryBuilder);
132+
$connection->expects($this->once())->method('transactional');
133+
134+
$messageStore = new DoctrineDbalMessageStore('foo', $connection);
135+
$messageStore->save(new MessageBag(
136+
Message::ofUser('Hello world'),
137+
));
121138
}
122139

123140
public function testMessageBagCanBeLoaded()
124141
{
142+
$serializer = new Serializer([
143+
new ArrayDenormalizer(),
144+
new MessageNormalizer(),
145+
], [new JsonEncoder()]);
146+
147+
$messageBag = new MessageBag(
148+
Message::ofUser('Hello world'),
149+
);
150+
151+
$result = $this->createMock(Result::class);
152+
$result->expects($this->once())->method('fetchAllAssociative')->willReturn([
153+
[
154+
'messages' => $serializer->serialize($messageBag->getMessages(), 'json'),
155+
],
156+
]);
157+
158+
$queryBuilder = $this->createMock(QueryBuilder::class);
159+
$queryBuilder->expects($this->once())->method('select')->with('messages')->willReturnSelf();
160+
$queryBuilder->expects($this->once())->method('from')->with('foo')->willReturnSelf();
161+
162+
$connection = $this->createMock(Connection::class);
163+
$connection->expects($this->once())->method('createQueryBuilder')->willReturn($queryBuilder);
164+
$connection->expects($this->once())->method('transactional')->willReturn($result);
165+
166+
$messageStore = new DoctrineDbalMessageStore('foo', $connection, $serializer);
167+
168+
$messages = $messageStore->load();
169+
170+
$this->assertCount(1, $messages);
125171
}
126172
}

0 commit comments

Comments
 (0)