Skip to content

Commit

Permalink
[Cache] Fix DBAL deprecations
Browse files Browse the repository at this point in the history
  • Loading branch information
MatTheCat authored and nicolas-grekas committed May 31, 2023
1 parent 3bc1a40 commit bec5302
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 20 deletions.
62 changes: 47 additions & 15 deletions src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php
Expand Up @@ -11,13 +11,17 @@

namespace Symfony\Component\Cache\Adapter;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\DBAL\Exception\TableNotFoundException;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Tools\DsnParser;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
Expand Down Expand Up @@ -68,7 +72,28 @@ public function __construct($connOrDsn, string $namespace = '', int $defaultLife
if (!class_exists(DriverManager::class)) {
throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $connOrDsn));
}
$this->conn = DriverManager::getConnection(['url' => $connOrDsn]);
if (class_exists(DsnParser::class)) {
$params = (new DsnParser([
'db2' => 'ibm_db2',
'mssql' => 'pdo_sqlsrv',
'mysql' => 'pdo_mysql',
'mysql2' => 'pdo_mysql',
'postgres' => 'pdo_pgsql',
'postgresql' => 'pdo_pgsql',
'pgsql' => 'pdo_pgsql',
'sqlite' => 'pdo_sqlite',
'sqlite3' => 'pdo_sqlite',
]))->parse($connOrDsn);
} else {
$params = ['url' => $connOrDsn];
}

$config = new Configuration();
if (class_exists(DefaultSchemaManagerFactory::class)) {
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
}

$this->conn = DriverManager::getConnection($params, $config);
} else {
throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be "%s" or string, "%s" given.', __METHOD__, Connection::class, get_debug_type($connOrDsn)));
}
Expand Down Expand Up @@ -156,7 +181,7 @@ protected function doFetch(array $ids): iterable
$ids,
], [
ParameterType::INTEGER,
Connection::PARAM_STR_ARRAY,
class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY,
])->iterateNumeric();

foreach ($result as $row) {
Expand All @@ -174,7 +199,7 @@ protected function doFetch(array $ids): iterable
$expired,
], [
ParameterType::INTEGER,
Connection::PARAM_STR_ARRAY,
class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY,
]);
}
}
Expand Down Expand Up @@ -226,7 +251,7 @@ protected function doDelete(array $ids): bool
{
$sql = "DELETE FROM $this->table WHERE $this->idCol IN (?)";
try {
$this->conn->executeStatement($sql, [array_values($ids)], [Connection::PARAM_STR_ARRAY]);
$this->conn->executeStatement($sql, [array_values($ids)], [class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY]);
} catch (TableNotFoundException $e) {
}

Expand Down Expand Up @@ -285,35 +310,42 @@ protected function doSave(array $values, int $lifetime)
$stmt = $this->conn->prepare($sql);
}

// $id and $data are defined later in the loop. Binding is done by reference, values are read on execution.
if ('sqlsrv' === $platformName || 'oci' === $platformName) {
$stmt->bindParam(1, $id);
$stmt->bindParam(2, $id);
$stmt->bindParam(3, $data, ParameterType::LARGE_OBJECT);
$bind = static function ($id, $data) use ($stmt) {
$stmt->bindValue(1, $id);
$stmt->bindValue(2, $id);
$stmt->bindValue(3, $data, ParameterType::LARGE_OBJECT);
$stmt->bindValue(6, $data, ParameterType::LARGE_OBJECT);
};
$stmt->bindValue(4, $lifetime, ParameterType::INTEGER);
$stmt->bindValue(5, $now, ParameterType::INTEGER);
$stmt->bindParam(6, $data, ParameterType::LARGE_OBJECT);
$stmt->bindValue(7, $lifetime, ParameterType::INTEGER);
$stmt->bindValue(8, $now, ParameterType::INTEGER);
} elseif (null !== $platformName) {
$stmt->bindParam(1, $id);
$stmt->bindParam(2, $data, ParameterType::LARGE_OBJECT);
$bind = static function ($id, $data) use ($stmt) {
$stmt->bindValue(1, $id);
$stmt->bindValue(2, $data, ParameterType::LARGE_OBJECT);
};
$stmt->bindValue(3, $lifetime, ParameterType::INTEGER);
$stmt->bindValue(4, $now, ParameterType::INTEGER);
} else {
$stmt->bindParam(1, $data, ParameterType::LARGE_OBJECT);
$stmt->bindValue(2, $lifetime, ParameterType::INTEGER);
$stmt->bindValue(3, $now, ParameterType::INTEGER);
$stmt->bindParam(4, $id);

$insertStmt = $this->conn->prepare($insertSql);
$insertStmt->bindParam(1, $id);
$insertStmt->bindParam(2, $data, ParameterType::LARGE_OBJECT);
$insertStmt->bindValue(3, $lifetime, ParameterType::INTEGER);
$insertStmt->bindValue(4, $now, ParameterType::INTEGER);

$bind = static function ($id, $data) use ($stmt, $insertStmt) {
$stmt->bindValue(1, $data, ParameterType::LARGE_OBJECT);
$stmt->bindValue(4, $id);
$insertStmt->bindValue(1, $id);
$insertStmt->bindValue(2, $data, ParameterType::LARGE_OBJECT);
};
}

foreach ($values as $id => $data) {
$bind($id, $data);
try {
$rowCount = $stmt->executeStatement();
} catch (TableNotFoundException $e) {
Expand Down
Expand Up @@ -16,6 +16,7 @@
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
use Doctrine\DBAL\Schema\Schema;
use PHPUnit\Framework\SkippedTestSuiteError;
use Psr\Cache\CacheItemPoolInterface;
Expand Down Expand Up @@ -45,12 +46,12 @@ public static function tearDownAfterClass(): void

public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
{
return new DoctrineDbalAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime);
return new DoctrineDbalAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $this->getDbalConfig()), '', $defaultLifetime);
}

public function testConfigureSchemaDecoratedDbalDriver()
{
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $this->getDbalConfig());
if (!interface_exists(Middleware::class)) {
$this->markTestSkipped('doctrine/dbal v2 does not support custom drivers using middleware');
}
Expand All @@ -60,7 +61,7 @@ public function testConfigureSchemaDecoratedDbalDriver()
->method('wrap')
->willReturn(new DriverWrapper($connection->getDriver()));

$config = new Configuration();
$config = $this->getDbalConfig();
$config->setMiddlewares([$middleware]);

$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $config);
Expand All @@ -75,7 +76,7 @@ public function testConfigureSchemaDecoratedDbalDriver()

public function testConfigureSchema()
{
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $this->getDbalConfig());
$schema = new Schema();

$adapter = new DoctrineDbalAdapter($connection);
Expand All @@ -95,7 +96,7 @@ public function testConfigureSchemaDifferentDbalConnection()

public function testConfigureSchemaTableExists()
{
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $this->getDbalConfig());
$schema = new Schema();
$schema->createTable('cache_items');

Expand Down Expand Up @@ -155,4 +156,12 @@ private function createConnectionMock()

return $connection;
}

private function getDbalConfig()
{
$config = new Configuration();
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());

return $config;
}
}

0 comments on commit bec5302

Please sign in to comment.