bug #32641 [Messenger] Retrieve table default options from the SchemaManager (vincenttouzet)

This PR was squashed before being merged into the 4.3 branch (closes #32641).

Discussion
----------

[Messenger] Retrieve table default options from the SchemaManager

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #32321    <!-- #-prefixed issue number(s), if any -->
| License       | MIT

This PR modify the Connection of the Doctrine Transport. It is now possible to specify a `SchemaConfig` that will be used when generating tables.

If Doctrine is configured as the following :
```yml
# config/packages/doctrine.yaml
doctrine:
    dbal:
        default_table_options:
            charset: 'utf8mb4'
            collate: 'utf8mb4_unicode_ci'
```

Then those options are used to create the table.

ping @weaverryan 😉

Commits
-------

93d0dc825e [Messenger] Retrieve table default options from the SchemaManager
This commit is contained in:
Tobias Schultze 2019-07-28 16:12:58 +02:00
commit 6003608d2c
6 changed files with 39 additions and 41 deletions

View File

@ -15,6 +15,8 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\SchemaConfig;
use Doctrine\DBAL\Schema\Synchronizer\SchemaSynchronizer; use Doctrine\DBAL\Schema\Synchronizer\SchemaSynchronizer;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage; use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
@ -102,25 +104,26 @@ class ConnectionTest extends TestCase
private function getDBALConnectionMock() private function getDBALConnectionMock()
{ {
$driverConnection = $this->getMockBuilder(\Doctrine\DBAL\Connection::class) $driverConnection = $this->createMock(\Doctrine\DBAL\Connection::class);
->disableOriginalConstructor() $platform = $this->createMock(AbstractPlatform::class);
->getMock();
$platform = $this->getMockBuilder(AbstractPlatform::class)
->getMock();
$platform->method('getWriteLockSQL')->willReturn('FOR UPDATE'); $platform->method('getWriteLockSQL')->willReturn('FOR UPDATE');
$configuration = $this->getMockBuilder(\Doctrine\DBAL\Configuration::class) $configuration = $this->createMock(\Doctrine\DBAL\Configuration::class);
->getMock();
$driverConnection->method('getDatabasePlatform')->willReturn($platform); $driverConnection->method('getDatabasePlatform')->willReturn($platform);
$driverConnection->method('getConfiguration')->willReturn($configuration); $driverConnection->method('getConfiguration')->willReturn($configuration);
$schemaManager = $this->createMock(AbstractSchemaManager::class);
$schemaConfig = $this->createMock(SchemaConfig::class);
$schemaConfig->method('getMaxIdentifierLength')->willReturn(63);
$schemaConfig->method('getDefaultTableOptions')->willReturn([]);
$schemaManager->method('createSchemaConfig')->willReturn($schemaConfig);
$driverConnection->method('getSchemaManager')->willReturn($schemaManager);
return $driverConnection; return $driverConnection;
} }
private function getQueryBuilderMock() private function getQueryBuilderMock()
{ {
$queryBuilder = $this->getMockBuilder(QueryBuilder::class) $queryBuilder = $this->createMock(QueryBuilder::class);
->disableOriginalConstructor()
->getMock();
$queryBuilder->method('select')->willReturn($queryBuilder); $queryBuilder->method('select')->willReturn($queryBuilder);
$queryBuilder->method('update')->willReturn($queryBuilder); $queryBuilder->method('update')->willReturn($queryBuilder);
@ -138,9 +141,7 @@ class ConnectionTest extends TestCase
private function getStatementMock($expectedResult) private function getStatementMock($expectedResult)
{ {
$stmt = $this->getMockBuilder(Statement::class) $stmt = $this->createMock(Statement::class);
->disableOriginalConstructor()
->getMock();
$stmt->expects($this->once()) $stmt->expects($this->once())
->method('fetch') ->method('fetch')
->willReturn($expectedResult); ->willReturn($expectedResult);
@ -150,8 +151,7 @@ class ConnectionTest extends TestCase
private function getSchemaSynchronizerMock() private function getSchemaSynchronizerMock()
{ {
return $this->getMockBuilder(SchemaSynchronizer::class) return $this->createMock(SchemaSynchronizer::class);
->getMock();
} }
/** /**
@ -307,9 +307,7 @@ class ConnectionTest extends TestCase
'headers' => json_encode(['type' => DummyMessage::class]), 'headers' => json_encode(['type' => DummyMessage::class]),
]; ];
$stmt = $this->getMockBuilder(Statement::class) $stmt = $this->createMock(Statement::class);
->disableOriginalConstructor()
->getMock();
$stmt->expects($this->once()) $stmt->expects($this->once())
->method('fetchAll') ->method('fetchAll')
->willReturn([$message1, $message2]); ->willReturn([$message1, $message2]);

View File

@ -32,7 +32,7 @@ class DoctrineReceiverTest extends TestCase
$serializer = $this->createSerializer(); $serializer = $this->createSerializer();
$doctrineEnvelope = $this->createDoctrineEnvelope(); $doctrineEnvelope = $this->createDoctrineEnvelope();
$connection = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $connection = $this->createMock(Connection::class);
$connection->method('get')->willReturn($doctrineEnvelope); $connection->method('get')->willReturn($doctrineEnvelope);
$receiver = new DoctrineReceiver($connection, $serializer); $receiver = new DoctrineReceiver($connection, $serializer);
@ -62,7 +62,7 @@ class DoctrineReceiverTest extends TestCase
$serializer->method('decode')->willThrowException(new MessageDecodingFailedException()); $serializer->method('decode')->willThrowException(new MessageDecodingFailedException());
$doctrineEnvelop = $this->createDoctrineEnvelope(); $doctrineEnvelop = $this->createDoctrineEnvelope();
$connection = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $connection = $this->createMock(Connection::class);
$connection->method('get')->willReturn($doctrineEnvelop); $connection->method('get')->willReturn($doctrineEnvelop);
$connection->expects($this->once())->method('reject'); $connection->expects($this->once())->method('reject');

View File

@ -27,12 +27,10 @@ class DoctrineSenderTest extends TestCase
$envelope = new Envelope(new DummyMessage('Oy')); $envelope = new Envelope(new DummyMessage('Oy'));
$encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]]; $encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]];
$connection = $this->getMockBuilder(Connection::class) $connection = $this->createMock(Connection::class);
->disableOriginalConstructor()
->getMock();
$connection->expects($this->once())->method('send')->with($encoded['body'], $encoded['headers'])->willReturn(15); $connection->expects($this->once())->method('send')->with($encoded['body'], $encoded['headers'])->willReturn(15);
$serializer = $this->getMockBuilder(SerializerInterface::class)->getMock(); $serializer = $this->createMock(SerializerInterface::class);
$serializer->method('encode')->with($envelope)->willReturnOnConsecutiveCalls($encoded); $serializer->method('encode')->with($envelope)->willReturnOnConsecutiveCalls($encoded);
$sender = new DoctrineSender($connection, $serializer); $sender = new DoctrineSender($connection, $serializer);
@ -49,12 +47,10 @@ class DoctrineSenderTest extends TestCase
$envelope = (new Envelope(new DummyMessage('Oy')))->with(new DelayStamp(500)); $envelope = (new Envelope(new DummyMessage('Oy')))->with(new DelayStamp(500));
$encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]]; $encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]];
$connection = $this->getMockBuilder(Connection::class) $connection = $this->createMock(Connection::class);
->disableOriginalConstructor()
->getMock();
$connection->expects($this->once())->method('send')->with($encoded['body'], $encoded['headers'], 500); $connection->expects($this->once())->method('send')->with($encoded['body'], $encoded['headers'], 500);
$serializer = $this->getMockBuilder(SerializerInterface::class)->getMock(); $serializer = $this->createMock(SerializerInterface::class);
$serializer->method('encode')->with($envelope)->willReturnOnConsecutiveCalls($encoded); $serializer->method('encode')->with($envelope)->willReturnOnConsecutiveCalls($encoded);
$sender = new DoctrineSender($connection, $serializer); $sender = new DoctrineSender($connection, $serializer);

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\Messenger\Tests\Transport\Doctrine; namespace Symfony\Component\Messenger\Tests\Transport\Doctrine;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\SchemaConfig;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Doctrine\RegistryInterface; use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Messenger\Transport\Doctrine\Connection; use Symfony\Component\Messenger\Transport\Doctrine\Connection;
@ -23,7 +25,7 @@ class DoctrineTransportFactoryTest extends TestCase
public function testSupports() public function testSupports()
{ {
$factory = new DoctrineTransportFactory( $factory = new DoctrineTransportFactory(
$this->getMockBuilder(RegistryInterface::class)->getMock() $this->createMock(RegistryInterface::class)
); );
$this->assertTrue($factory->supports('doctrine://default', [])); $this->assertTrue($factory->supports('doctrine://default', []));
@ -32,19 +34,21 @@ class DoctrineTransportFactoryTest extends TestCase
public function testCreateTransport() public function testCreateTransport()
{ {
$connection = $this->getMockBuilder(\Doctrine\DBAL\Connection::class) $driverConnection = $this->createMock(\Doctrine\DBAL\Connection::class);
->disableOriginalConstructor() $schemaManager = $this->createMock(AbstractSchemaManager::class);
->getMock(); $schemaConfig = $this->createMock(SchemaConfig::class);
$registry = $this->getMockBuilder(RegistryInterface::class)->getMock(); $schemaManager->method('createSchemaConfig')->willReturn($schemaConfig);
$driverConnection->method('getSchemaManager')->willReturn($schemaManager);
$registry = $this->createMock(RegistryInterface::class);
$registry->expects($this->once()) $registry->expects($this->once())
->method('getConnection') ->method('getConnection')
->willReturn($connection); ->willReturn($driverConnection);
$factory = new DoctrineTransportFactory($registry); $factory = new DoctrineTransportFactory($registry);
$serializer = $this->createMock(SerializerInterface::class); $serializer = $this->createMock(SerializerInterface::class);
$this->assertEquals( $this->assertEquals(
new DoctrineTransport(new Connection(Connection::buildConfiguration('doctrine://default'), $connection), $serializer), new DoctrineTransport(new Connection(Connection::buildConfiguration('doctrine://default'), $driverConnection), $serializer),
$factory->createTransport('doctrine://default', [], $serializer) $factory->createTransport('doctrine://default', [], $serializer)
); );
} }
@ -55,7 +59,7 @@ class DoctrineTransportFactoryTest extends TestCase
*/ */
public function testCreateTransportMustThrowAnExceptionIfManagerIsNotFound() public function testCreateTransportMustThrowAnExceptionIfManagerIsNotFound()
{ {
$registry = $this->getMockBuilder(RegistryInterface::class)->getMock(); $registry = $this->createMock(RegistryInterface::class);
$registry->expects($this->once()) $registry->expects($this->once())
->method('getConnection') ->method('getConnection')
->willReturnCallback(function () { ->willReturnCallback(function () {

View File

@ -31,8 +31,8 @@ class DoctrineTransportTest extends TestCase
public function testReceivesMessages() public function testReceivesMessages()
{ {
$transport = $this->getTransport( $transport = $this->getTransport(
$serializer = $this->getMockBuilder(SerializerInterface::class)->getMock(), $serializer = $this->createMock(SerializerInterface::class),
$connection = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock() $connection = $this->createMock(Connection::class)
); );
$decodedMessage = new DummyMessage('Decoded.'); $decodedMessage = new DummyMessage('Decoded.');
@ -52,8 +52,8 @@ class DoctrineTransportTest extends TestCase
private function getTransport(SerializerInterface $serializer = null, Connection $connection = null) private function getTransport(SerializerInterface $serializer = null, Connection $connection = null)
{ {
$serializer = $serializer ?: $this->getMockBuilder(SerializerInterface::class)->getMock(); $serializer = $serializer ?: $this->createMock(SerializerInterface::class);
$connection = $connection ?: $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $connection = $connection ?: $this->createMock(Connection::class);
return new DoctrineTransport($connection, $serializer); return new DoctrineTransport($connection, $serializer);
} }

View File

@ -304,7 +304,7 @@ class Connection
private function getSchema(): Schema private function getSchema(): Schema
{ {
$schema = new Schema(); $schema = new Schema([], [], $this->driverConnection->getSchemaManager()->createSchemaConfig());
$table = $schema->createTable($this->configuration['table_name']); $table = $schema->createTable($this->configuration['table_name']);
$table->addColumn('id', Type::BIGINT) $table->addColumn('id', Type::BIGINT)
->setAutoincrement(true) ->setAutoincrement(true)