diff --git a/Tests/Transport/ConnectionTest.php b/Tests/Transport/ConnectionTest.php index cb0d3e7..13be9a3 100644 --- a/Tests/Transport/ConnectionTest.php +++ b/Tests/Transport/ConnectionTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Bridge\Doctrine\Tests\Transport; use Doctrine\DBAL\Abstraction\Result as AbstractionResult; +use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Connection as DBALConnection; use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\Result as DriverResult; @@ -25,7 +26,9 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\SchemaConfig; +use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Statement; +use Doctrine\DBAL\Types\Types; use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Bridge\Doctrine\Tests\Fixtures\DummyMessage; use Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection; @@ -406,6 +409,56 @@ public function providePlatformSql(): iterable ]; } + /** + * @dataProvider setupIndicesProvider + */ + public function testSetupIndices(string $platformClass, array $expectedIndices) + { + $driverConnection = $this->createMock(DBALConnection::class); + $driverConnection->method('getConfiguration')->willReturn(new Configuration()); + + $schemaManager = $this->createMock(AbstractSchemaManager::class); + $schema = new Schema(); + $expectedTable = $schema->createTable('messenger_messages'); + $expectedTable->addColumn('id', Types::BIGINT); + $expectedTable->setPrimaryKey(['id']); + // Make sure columns for indices exists so addIndex() will not throw + foreach (array_unique(array_merge(...$expectedIndices)) as $columnName) { + $expectedTable->addColumn($columnName, Types::STRING); + } + foreach ($expectedIndices as $indexColumns) { + $expectedTable->addIndex($indexColumns); + } + $schemaManager->method('createSchema')->willReturn($schema); + $driverConnection->method('getSchemaManager')->willReturn($schemaManager); + + $platformMock = $this->createMock($platformClass); + $platformMock + ->expects(self::once()) + ->method('getAlterTableSQL') + ->with(self::callback(static function (TableDiff $tableDiff): bool { + return 0 === \count($tableDiff->addedIndexes) && 0 === \count($tableDiff->changedIndexes) && 0 === \count($tableDiff->removedIndexes); + })) + ->willReturn([]); + $driverConnection->method('getDatabasePlatform')->willReturn($platformMock); + + $connection = new Connection([], $driverConnection); + $connection->setup(); + } + + public function setupIndicesProvider(): iterable + { + yield 'MySQL' => [ + MySQL57Platform::class, + [['delivered_at']], + ]; + + yield 'Other platforms' => [ + AbstractPlatform::class, + [['queue_name'], ['available_at'], ['delivered_at']], + ]; + } + public function testConfigureSchema() { $driverConnection = $this->getDBALConnectionMock(); diff --git a/Transport/Connection.php b/Transport/Connection.php index c4b398a..43974a5 100644 --- a/Transport/Connection.php +++ b/Transport/Connection.php @@ -17,6 +17,7 @@ use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Platforms\MySqlPlatform; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Comparator; @@ -404,7 +405,6 @@ private function addTableToSchema(Schema $schema): void $table->addColumn('headers', Types::TEXT) ->setNotnull(true); $table->addColumn('queue_name', Types::STRING) - ->setLength(190) // MySQL 5.6 only supports 191 characters on an indexed column in utf8mb4 mode ->setNotnull(true); $table->addColumn('created_at', Types::DATETIME_MUTABLE) ->setNotnull(true); @@ -413,8 +413,11 @@ private function addTableToSchema(Schema $schema): void $table->addColumn('delivered_at', Types::DATETIME_MUTABLE) ->setNotnull(false); $table->setPrimaryKey(['id']); - $table->addIndex(['queue_name']); - $table->addIndex(['available_at']); + // No indices on queue_name and available_at on MySQL to prevent deadlock issues when running multiple consumers. + if (!$this->driverConnection->getDatabasePlatform() instanceof MySqlPlatform) { + $table->addIndex(['queue_name']); + $table->addIndex(['available_at']); + } $table->addIndex(['delivered_at']); }