Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/2.5.x' into 2.6.x
Browse files Browse the repository at this point in the history
# Conflicts:
#	Resources/doc/configuration.rst
  • Loading branch information
ostrolucky committed Mar 5, 2022
2 parents 89b7ed6 + 1e0d1d7 commit eca2063
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 31 deletions.
39 changes: 32 additions & 7 deletions ConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;

Expand Down Expand Up @@ -70,15 +71,13 @@ public function createConnection(array $params, ?Configuration $config = null, ?
}

$connection = DriverManager::getConnection($params, $config, $eventManager);
$params = array_merge($connection->getParams(), $overriddenOptions);
$params = $this->addDatabaseSuffix(array_merge($connection->getParams(), $overriddenOptions));
$driver = $connection->getDriver();

if (isset($params['dbname']) && isset($params['dbname_suffix'])) {
$params['dbname'] .= $params['dbname_suffix'];
}
$platform = $driver->getDatabasePlatform();

if (! isset($params['charset'])) {
if ($driver instanceof AbstractMySQLDriver) {
/** @psalm-suppress UndefinedClass AbstractMySQLPlatform exists since DBAL 3.x only */
if ($platform instanceof AbstractMySQLPlatform || $platform instanceof MySqlPlatform) {
$params['charset'] = 'utf8mb4';

/* PARAM_ASCII_STR_ARRAY is defined since doctrine/dbal 3.3
Expand Down Expand Up @@ -166,4 +165,30 @@ private function initializeTypes(): void

$this->initialized = true;
}

/**
* @param array<string, mixed> $params
*
* @return array<string, mixed>
*/
private function addDatabaseSuffix(array $params): array
{
if (isset($params['dbname']) && isset($params['dbname_suffix'])) {
$params['dbname'] .= $params['dbname_suffix'];
}

foreach ($params['replica'] ?? [] as $key => $replicaParams) {
if (! isset($replicaParams['dbname'], $replicaParams['dbname_suffix'])) {
continue;
}

$params['replica'][$key]['dbname'] .= $replicaParams['dbname_suffix'];
}

if (isset($params['primary']['dbname'], $params['primary']['dbname_suffix'])) {
$params['primary']['dbname'] .= $params['primary']['dbname_suffix'];
}

return $params;
}
}
36 changes: 21 additions & 15 deletions Resources/doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ Configuration Reference
port: ~
user: root
password: ~
charset: "UTF8"
# RDBMS specific; Refer to the manual of your RDBMS for more information
charset: ~
dbname_suffix: ~
# SQLite specific
Expand Down Expand Up @@ -132,9 +135,9 @@ Configuration Reference
default_table_options:
# Affects schema-tool. If absent, DBAL chooses defaults
# based on the platform. Examples here are for MySQL.
# charset: utf8
# collate: utf8_unicode_ci # When using doctrine/dbal 2.x
# collation: utf8_unicode_ci # When using doctrine/dbal 3.x
# charset: utf8mb4
# collate: utf8mb4_unicode_ci # When using doctrine/dbal 2.x
# collation: utf8mb4_unicode_ci # When using doctrine/dbal 3.x
# engine: InnoDB
replicas:
Expand All @@ -146,6 +149,7 @@ Configuration Reference
user: root
password: ~
charset: ~
dbname_suffix: ~
path: ~
memory: ~
Expand Down Expand Up @@ -444,7 +448,7 @@ Configuration Reference
port="null"
user="root"
password="null"
charset="UTF8"
charset="null"
path=""
memory=""
unix-socket=""
Expand Down Expand Up @@ -486,9 +490,9 @@ Configuration Reference
<doctrine:mapping-type name="enum">string</doctrine:mapping-type>
<!-- example -->
<doctrine:default-table-option name="charset">utf8</doctrine:default-table-option>
<doctrine:default-table-option name="charset">utf8mb4</doctrine:default-table-option>
<!-- when using doctrine/dbal 2.x -->
<doctrine:default-table-option name="collate">utf8_unicode_ci</doctrine:default-table-option>
<doctrine:default-table-option name="collate">utf8mb4_unicode_ci</doctrine:default-table-option>
<!-- when using doctrine/dbal 3.x -->
<doctrine:default-table-option name="collation">utf8_unicode_ci</doctrine:default-table-option>
<doctrine:default-table-option name="engine">InnoDB</doctrine:default-table-option>
Expand Down Expand Up @@ -517,6 +521,7 @@ Configuration Reference
user="root"
password="null"
charset=""
dbname_suffix=""
path=""
memory=""
unix-socket=""
Expand Down Expand Up @@ -963,7 +968,7 @@ can configure. The following block shows all possible configuration keys:
sslkey: postgresql-key.pem # PostgreSQL specific (LIBPQ-CONNECT-SSLKEY)
sslcrl: postgresql.crl # PostgreSQL specific (LIBPQ-CONNECT-SSLCRL)
wrapper_class: MyDoctrineDbalConnectionWrapper
charset: UTF8
charset: ~ # RDBMS-specific. Refer to the manual of your RDBMS for more information.
logging: "%kernel.debug%"
platform_service: MyOwnDatabasePlatformService
auto_commit: false
Expand All @@ -974,10 +979,11 @@ can configure. The following block shows all possible configuration keys:
custom: Acme\HelloBundle\MyCustomType
default_table_options:
# Affects schema-tool. If absent, DBAL chooses defaults
# based on the platform.
charset: utf8
collate: utf8_unicode_ci # when using doctrine/dbal 2.x
collation: utf8_unicode_ci # when using doctrine/dbal 3.x
# based on the platform. These defaults might be
# sub-optimal for backward compatibility reasons.
charset: utf8mb4
collate: utf8mb4_unicode_ci # when using doctrine/dbal 2.x
collation: utf8mb4_unicode_ci # when using doctrine/dbal 3.x
engine: InnoDB
.. code-block:: xml
Expand Down Expand Up @@ -1053,17 +1059,17 @@ can configure. The following block shows all possible configuration keys:
sslkey="postgresql-key.pem"
sslcrl="postgresql.crl"
wrapper-class="MyDoctrineDbalConnectionWrapper"
charset="UTF8"
charset=""
logging="%kernel.debug%"
platform-service="MyOwnDatabasePlatformService"
auto-commit="false"
schema-filter="^sf2_"
>
<doctrine:option key="foo">bar</doctrine:option>
<doctrine:mapping-type name="enum">string</doctrine:mapping-type>
<doctrine:default-table-option name="charset">utf8</doctrine:default-table-option>
<doctrine:default-table-option name="charset">utf8mb4</doctrine:default-table-option>
<!-- when using doctrine/dbal 2.x -->
<doctrine:default-table-option name="collate">utf8_unicode_ci</doctrine:default-table-option>
<doctrine:default-table-option name="collate">utf8mb4_unicode_ci</doctrine:default-table-option>
<!-- when using doctrine/dbal 3.x -->
<doctrine:default-table-option name="collation">utf8_unicode_ci</doctrine:default-table-option>
<doctrine:default-table-option name="engine">InnoDB</doctrine:default-table-option>
Expand Down
39 changes: 30 additions & 9 deletions Tests/ConnectionFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use Exception;
use Throwable;

use function array_intersect_key;
use function class_exists;
use function defined;
use function strpos;

// Compatibility with DBAL < 3
class_exists(\Doctrine\DBAL\Platforms\MySqlPlatform::class);
Expand Down Expand Up @@ -50,19 +49,16 @@ public function testContainer(): void

try {
$factory->createConnection($params, $config, $eventManager, $mappingTypes);
} catch (Throwable $e) {
$this->assertTrue(strpos($e->getMessage(), 'can circumvent this by setting') > 0);

throw $e;
} finally {
FakeDriver::$exception = null;
}
}

public function testDefaultCharset(): void
public function testDefaultCharsetNonMySql(): void
{
$factory = new ConnectionFactory([]);
$params = [
FakeDriver::$platform = new SqlitePlatform();
$factory = new ConnectionFactory([]);
$params = [
'driverClass' => FakeDriver::class,
'wrapperClass' => FakeConnection::class,
];
Expand Down Expand Up @@ -173,6 +169,31 @@ public function testDbnameSuffix(): void

$this->assertSame('main_test', $connection->getParams()['dbname']);
}

public function testDbnameSuffixForReplicas(): void
{
$connection = (new ConnectionFactory([]))->createConnection([
'driver' => 'pdo_mysql',
'primary' => [
'url' => 'mysql://root:password@database:3306/primary?serverVersion=mariadb-10.5.8',
'dbname_suffix' => '_test',
],
'replica' => [
'replica1' => [
'url' => 'mysql://root:password@database:3306/replica?serverVersion=mariadb-10.5.8',
'dbname_suffix' => '_test',
],
],
]);

$parsedParams = $connection->getParams();
$this->assertArrayHasKey('primary', $parsedParams);
$this->assertArrayHasKey('replica', $parsedParams);
$this->assertArrayHasKey('replica1', $parsedParams['replica']);

$this->assertSame('primary_test', $parsedParams['primary']['dbname']);
$this->assertSame('replica_test', $parsedParams['replica']['replica1']['dbname']);
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,13 @@
<file name="Tests/ConnectionFactoryTest.php"/>
</errorLevel>
</InvalidArrayOffset>
<UndefinedDocblockClass>
<errorLevel type="suppress">
<!-- https://github.com/symfony/symfony/issues/45609 -->
<referencedClass name="UnitEnum" />
<directory name="DependencyInjection"/>
<directory name="Tests/DependencyInjection"/>
</errorLevel>
</UndefinedDocblockClass>
</issueHandlers>
</psalm>

0 comments on commit eca2063

Please sign in to comment.