diff --git a/src/chat/src/Bridge/Doctrine/DoctrineDbalMessageStore.php b/src/chat/src/Bridge/Doctrine/DoctrineDbalMessageStore.php index 6a2ef80fb..340b3b2ec 100644 --- a/src/chat/src/Bridge/Doctrine/DoctrineDbalMessageStore.php +++ b/src/chat/src/Bridge/Doctrine/DoctrineDbalMessageStore.php @@ -15,6 +15,7 @@ use Doctrine\DBAL\Connection as DBALConnection; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Result; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Name\Identifier; use Doctrine\DBAL\Schema\Name\UnqualifiedName; use Doctrine\DBAL\Schema\PrimaryKeyConstraint; @@ -52,13 +53,25 @@ public function setup(array $options = []): void throw new InvalidArgumentException('No supported options.'); } - $schema = $this->dbalConnection->createSchemaManager()->introspectSchema(); + $schemaManager = $this->dbalConnection->createSchemaManager(); + $schema = $schemaManager->introspectSchema(); if ($schema->hasTable($this->tableName)) { return; } - $this->addTableToSchema($schema); + if (class_exists(ComparatorConfig::class)) { + $comparator = $schemaManager->createComparator(new ComparatorConfig(false, false)); + } else { + // Backwards compatibility for doctrine/dbal 3.x + $comparator = $schemaManager->createComparator(); + } + + $migrations = $this->dbalConnection->getDatabasePlatform()->getAlterSchemaSQL($comparator->compareSchemas($schema, $this->addTableToSchema($schema))); + + foreach ($migrations as $sql) { + $this->dbalConnection->executeQuery($sql); + } } public function drop(): void @@ -113,8 +126,10 @@ public function load(): MessageBag return new MessageBag(...array_merge(...$messages)); } - private function addTableToSchema(Schema $schema): void + private function addTableToSchema(Schema $currentSchema): Schema { + $schema = clone $currentSchema; + $table = $schema->createTable($this->tableName); $table->addOption('_symfony_ai_chat_table_name', $this->tableName); $idColumn = $table->addColumn('id', Types::BIGINT) @@ -141,8 +156,6 @@ private function addTableToSchema(Schema $schema): void } } - foreach ($schema->toSql($this->dbalConnection->getDatabasePlatform()) as $sql) { - $this->dbalConnection->executeQuery($sql); - } + return $schema; } } diff --git a/src/chat/tests/Bridge/Doctrine/DoctrineDbalMessageStoreTest.php b/src/chat/tests/Bridge/Doctrine/DoctrineDbalMessageStoreTest.php index b6b9c01cf..020fb41b7 100644 --- a/src/chat/tests/Bridge/Doctrine/DoctrineDbalMessageStoreTest.php +++ b/src/chat/tests/Bridge/Doctrine/DoctrineDbalMessageStoreTest.php @@ -17,7 +17,9 @@ use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\SchemaDiff; use Doctrine\DBAL\Schema\Table; use PHPUnit\Framework\TestCase; use Symfony\AI\Chat\Bridge\Doctrine\DoctrineDbalMessageStore; @@ -76,15 +78,23 @@ public function testMessageStoreTableCanBeSetup() $schema = $this->createMock(Schema::class); $schema->expects($this->once())->method('hasTable')->willReturn(false); $schema->expects($this->once())->method('createTable')->with('foo')->willReturn($table); - $schema->expects($this->once())->method('toSql')->with($platform)->willReturn([]); $sqliteSchemaManager = $this->createMock(AbstractSchemaManager::class); $sqliteSchemaManager->expects($this->once())->method('introspectSchema')->willReturn($schema); + $comparator = $this->createMock(Comparator::class); + $sqliteSchemaManager->expects($this->once())->method('createComparator')->willReturn($comparator); + $connection = $this->createMock(Connection::class); $connection->expects($this->once())->method('createSchemaManager')->willReturn($sqliteSchemaManager); $connection->expects($this->exactly(2))->method('getDatabasePlatform')->willReturn($platform); + $schemaDiff = $this->createMock(SchemaDiff::class); + + $comparator->expects($this->once())->method('compareSchemas')->willReturn($schemaDiff); + $platform->expects($this->once())->method('getAlterSchemaSQL')->willReturn(['SQL STATEMENT']); + $connection->expects($this->once())->method('executeQuery')->with('SQL STATEMENT'); + $messageStore = new DoctrineDbalMessageStore('foo', $connection); $messageStore->setup(); }