Skip to content

Commit

Permalink
Allow dbal ^4.0 (#19)
Browse files Browse the repository at this point in the history
Add ^4.0 to composer and test all cases #18.

The following changes have been made so that all dbal versions
can be supported:
* Choose database platform based on name or instance depending on
method existence.
* Move logging for tests to wrapper class, as DebugStack was removed
in 4.0 and middlewares have only existed since 3.2.
  • Loading branch information
marein authored Feb 19, 2024
1 parent 5865f66 commit 176e8fa
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 73 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ jobs:
operating-system: [ubuntu-latest]
php-version: ['8.0', '8.1', '8.2', '8.3']
symfony-version: ['^5.2', '^6.0', '^7.0']
doctrine-dbal-version: ['^2.12', '^3.0']
doctrine-dbal-version: ['^2.12', '^3.0', '^4.0']
doctrine-bundle-version: ['^2.2']
doctrine-migrations-bundle-version: ['^3.0']
exclude:
- php-version: '8.0'
symfony-version: '^7.0'
- php-version: '8.1'
symfony-version: '^7.0'
- php-version: '8.0'
doctrine-dbal-version: '^4.0'
- symfony-version: '^7.0'
doctrine-dbal-version: '^2.12'
name: >-
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"require": {
"php": "^8.0",
"doctrine/dbal": "^2.12 || ^3.0",
"doctrine/dbal": "^2.12 || ^3.0 || ^4.0",
"doctrine/doctrine-bundle": "^2.2",
"doctrine/doctrine-migrations-bundle": "^3.0",
"symfony/config": "^5.2 || ^6.0 || ^7.0",
Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ parameters:
message: '#^Cannot cast array<string>|bool|string|null to string\.$#'
path: src/EventListener/LockMigrationsListener.php
count: 1
-
message: '#^Class Doctrine\\DBAL\\Platforms\\.*Platform not found\.$#'
12 changes: 4 additions & 8 deletions src/EventListener/LockMigrationsListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,10 @@

final class LockMigrationsListener
{
private Platforms $platforms;

private string $lockNamePrefix;

public function __construct(Platforms $platforms, string $lockNamePrefix)
{
$this->platforms = $platforms;
$this->lockNamePrefix = $lockNamePrefix;
public function __construct(
private Platforms $platforms,
private string $lockNamePrefix
) {
}

/**
Expand Down
8 changes: 3 additions & 5 deletions src/Platform/MysqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@

final class MysqlPlatform implements Platform
{
private Connection $connection;

public function __construct(Connection $connection)
{
$this->connection = $connection;
public function __construct(
private Connection $connection
) {
}

public function acquireLock(string $name): void
Expand Down
40 changes: 17 additions & 23 deletions src/Platform/Platforms.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,9 @@

final class Platforms
{
private Registry $doctrine;

/**
* @var array<string, callable>
*/
private array $platformFactories;

/**
* @var callable
*/
private $fallbackPlatformFactory;

public function __construct(Registry $doctrine)
{
$this->doctrine = $doctrine;
$this->platformFactories = [
'mysql' => fn(Connection $connection) => new MysqlPlatform($connection),
'postgresql' => fn(Connection $connection) => new PostgresqlPlatform($connection)
];
$this->fallbackPlatformFactory = fn(Connection $connection) => new NullPlatform();
public function __construct(
private Registry $doctrine
) {
}

/**
Expand All @@ -40,12 +23,23 @@ public function fromConnectionName(string $name): Platform
$connection = $this->getConnection($name);

try {
$platformName = $connection->getDatabasePlatform()->getName();

return ($this->platformFactories[$platformName] ?? $this->fallbackPlatformFactory)($connection);
$databasePlatform = $connection->getDatabasePlatform();
} catch (Exception $e) {
throw new PlatformException($e->getMessage(), $e->getCode(), $e);
}

$databasePlatformName = '';
if (method_exists($databasePlatform, 'getName')) {
$databasePlatformName = $databasePlatform->getName();
}

return match (true) {
$databasePlatform instanceof \Doctrine\DBAL\Platforms\MySQLPlatform,
$databasePlatformName === 'mysql' => new MysqlPlatform($connection),
$databasePlatform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform,
$databasePlatformName === 'postgresql' => new PostgresqlPlatform($connection),
default => new NullPlatform()
};
}

private function getConnection(string $connectionName): Connection
Expand Down
8 changes: 3 additions & 5 deletions src/Platform/PostgresqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@

final class PostgresqlPlatform implements Platform
{
private Connection $connection;

public function __construct(Connection $connection)
{
$this->connection = $connection;
public function __construct(
private Connection $connection
) {
}

public function acquireLock(string $name): void
Expand Down
21 changes: 0 additions & 21 deletions tests/Integration/ConnectionTestDouble.php

This file was deleted.

34 changes: 34 additions & 0 deletions tests/Integration/Dbal2Connection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Marein\LockDoctrineMigrationsBundle\Tests\Integration;

use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Throwable;

final class Dbal2Connection extends Connection
{
public array $loggedQueries = [];

public function connect()
{
try {
parent::connect();
} catch (Throwable $e) {
sleep(1);
$this->connect();
}
}

public function executeQuery($sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null)
{
$this->loggedQueries[] = [
'sql' => $sql,
'params' => $params
];

return parent::executeQuery($sql, $params, $types, $qcp);
}
}
35 changes: 35 additions & 0 deletions tests/Integration/Dbal3Connection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Marein\LockDoctrineMigrationsBundle\Tests\Integration;

use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Result;
use Throwable;

final class Dbal3Connection extends Connection
{
public array $loggedQueries = [];

public function connect()
{
try {
parent::connect();
} catch (Throwable $e) {
sleep(1);
$this->connect();
}
}

public function executeQuery(string $sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): Result
{
$this->loggedQueries[] = [
'sql' => $sql,
'params' => $params
];

return parent::executeQuery($sql, $params, $types, $qcp);
}
}
36 changes: 36 additions & 0 deletions tests/Integration/Dbal4Connection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Marein\LockDoctrineMigrationsBundle\Tests\Integration;

use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Result;
use Throwable;

final class Dbal4Connection extends Connection
{
public array $loggedQueries = [];

public function connect(): DriverConnection
{
try {
return parent::connect();
} catch (Throwable $e) {
sleep(1);
return $this->connect();
}
}

public function executeQuery(string $sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): Result
{
$this->loggedQueries[] = [
'sql' => $sql,
'params' => $params
];

return parent::executeQuery($sql, $params, $types, $qcp);
}
}
10 changes: 3 additions & 7 deletions tests/Integration/DoctrineMigrationMigrateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Marein\LockDoctrineMigrationsBundle\Tests\Integration;

use Doctrine\DBAL\Logging\DebugStack;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\ApplicationTester;
Expand All @@ -27,12 +26,9 @@ public function itShouldLock(array $bundleConfiguration, string $connectionName,
$application = new Application($kernel);
$application->setAutoExit(false);

$sqlLogger = new DebugStack();
$kernel
$connection = $kernel
->getContainer()
->get('doctrine.dbal.' . $connectionName . '_connection')
->getConfiguration()
->setSQLLogger($sqlLogger);
->get('doctrine.dbal.' . $connectionName . '_connection');

$applicationTester = new ApplicationTester($application);

Expand All @@ -54,7 +50,7 @@ public function itShouldLock(array $bundleConfiguration, string $connectionName,

$actualQueryCalls = array_map(
fn(array $queryCall): array => [$queryCall['sql'], $queryCall['params']],
$sqlLogger->queries
$connection->loggedQueries
);

foreach ($expectedQueryCalls as $expectedQueryCall) {
Expand Down
16 changes: 14 additions & 2 deletions tests/Integration/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Marein\LockDoctrineMigrationsBundle\Tests\Integration;

use Composer\InstalledVersions;
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
use Doctrine\Migrations\Configuration\Connection\ConnectionRegistryConnection;
Expand Down Expand Up @@ -70,11 +71,11 @@ protected function configureContainer(ContainerConfigurator $containerConfigurat
'connections' => [
'mysql' => [
'url' => 'mysql://root:password@127.0.0.1:3306/db',
'wrapper_class' => ConnectionTestDouble::class
'wrapper_class' => $this->getDoctrineConnectionWrapperClass()
],
'pgsql' => [
'url' => 'pgsql://postgres:password@127.0.0.1:5432/db',
'wrapper_class' => ConnectionTestDouble::class
'wrapper_class' => $this->getDoctrineConnectionWrapperClass()
]
]
]
Expand All @@ -99,4 +100,15 @@ protected function configureContainer(ContainerConfigurator $containerConfigurat
->factory([ConnectionRegistryConnection::class, 'withSimpleDefault'])
->args([new Reference('doctrine')]);
}

private function getDoctrineConnectionWrapperClass(): string
{
preg_match('/^(\d+)\./', (string)InstalledVersions::getVersion('doctrine/dbal'), $matches);

return match ($matches[1] ?? null) {
'2' => Dbal2Connection::class,
'3' => Dbal3Connection::class,
default => Dbal4Connection::class
};
}
}

0 comments on commit 176e8fa

Please sign in to comment.