diff --git a/ConnectionFactory.php b/ConnectionFactory.php index fc3911aa1..c0fd16761 100644 --- a/ConnectionFactory.php +++ b/ConnectionFactory.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Types\Type; use function array_merge; +use function defined; use function is_subclass_of; use function trigger_deprecation; @@ -79,8 +80,19 @@ public function createConnection(array $params, ?Configuration $config = null, ? if ($driver instanceof AbstractMySQLDriver) { $params['charset'] = 'utf8mb4'; - if (! isset($params['defaultTableOptions']['collate'])) { - $params['defaultTableOptions']['collate'] = 'utf8mb4_unicode_ci'; + /* PARAM_ASCII_STR_ARRAY is defined since doctrine/dbal 3.3 + doctrine/dbal 3.3.2 adds support for the option "collation" + Checking for that constant will no longer be necessary + after dropping support for doctrine/dbal 2, since this + package requires doctrine/dbal 3.3.2 or higher. */ + if (isset($params['defaultTableOptions']['collate']) && defined('Doctrine\DBAL\Connection::PARAM_ASCII_STR_ARRAY')) { + $params['defaultTableOptions']['collation'] = $params['defaultTableOptions']['collate']; + unset($params['defaultTableOptions']['collate']); + } + + $collationOption = defined('Doctrine\DBAL\Connection::PARAM_ASCII_STR_ARRAY') ? 'collation' : 'collate'; + if (! isset($params['defaultTableOptions'][$collationOption])) { + $params['defaultTableOptions'][$collationOption] = 'utf8mb4_unicode_ci'; } } else { $params['charset'] = 'utf8'; diff --git a/Tests/ConnectionFactoryTest.php b/Tests/ConnectionFactoryTest.php index af75a1db2..116a63de1 100644 --- a/Tests/ConnectionFactoryTest.php +++ b/Tests/ConnectionFactoryTest.php @@ -19,6 +19,7 @@ use function array_intersect_key; use function class_exists; +use function defined; use function strpos; // Compatibility with DBAL < 3 @@ -81,6 +82,56 @@ public function testDefaultCharsetMySql(): void $this->assertSame('utf8mb4', $connection->getParams()['charset']); } + public function testDefaultCollateMySql(): void + { + if (defined('Doctrine\DBAL\Connection::PARAM_ASCII_STR_ARRAY')) { + self::markTestSkipped('This test is only relevant for DBAL < 3.3'); + } + + $factory = new ConnectionFactory([]); + $connection = $factory->createConnection(['driver' => 'pdo_mysql']); + + $this->assertSame( + 'utf8mb4_unicode_ci', + $connection->getParams()['defaultTableOptions']['collate'] + ); + } + + public function testDefaultCollationMySql(): void + { + if (! defined('Doctrine\DBAL\Connection::PARAM_ASCII_STR_ARRAY')) { + self::markTestSkipped('This test is only relevant for DBAL >= 3.3'); + } + + $factory = new ConnectionFactory([]); + $connection = $factory->createConnection(['driver' => 'pdo_mysql']); + + $this->assertSame( + 'utf8mb4_unicode_ci', + $connection->getParams()['defaultTableOptions']['collation'] + ); + } + + public function testCollateMapsToCollationForMySql(): void + { + if (! defined('Doctrine\DBAL\Connection::PARAM_ASCII_STR_ARRAY')) { + self::markTestSkipped('This test is only relevant for DBAL >= 3.3'); + } + + $factory = new ConnectionFactory([]); + $connection = $factory->createConnection([ + 'driver' => 'pdo_mysql', + 'defaultTableOptions' => ['collate' => 'my_collation'], + ]); + + $tableOptions = $connection->getParams()['defaultTableOptions']; + $this->assertArrayNotHasKey('collate', $tableOptions); + $this->assertSame( + 'my_collation', + $tableOptions['collation'] + ); + } + /** @group legacy */ public function testConnectionOverrideOptions(): void { diff --git a/composer.json b/composer.json index ea3904703..8c127965f 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "php": "^7.1 || ^8.0", "doctrine/annotations": "^1", "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^2.13.1|^3.1", + "doctrine/dbal": "^2.13.1|^3.3.2", "doctrine/persistence": "^2.2", "doctrine/sql-formatter": "^1.0.1", "symfony/cache": "^4.3.3|^5.0|^6.0", diff --git a/psalm.xml.dist b/psalm.xml.dist index 8d686af10..536ff0ce0 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -39,5 +39,11 @@ + + + + + +