Commit a8663d87 authored by Benni Mack's avatar Benni Mack Committed by Georg Ringer
Browse files

[TASK] DBAL: Extend custom drivers from abstract drivers

TYPO3 Core has its own implementation of driver classes
for database abstraction by effectively overriding e.g.
the PDO Statement class with TYPO3's Statment class
to ensure that resources are strings to be completely
transparent with Database abstraction.

Doctrine DBAL 3.0 will force Drivers to either
switch to composition or extend from the Abstract Driver classes.

This change switches TYPO3's native implementation
to extend from Abstract Driver classes, ensuring
forward-compatibility with Doctrine DBAL 3.0
for TYPO3 v11 with Drivers.

Resolves: #93076
Releases: master
Change-Id: I32b886fe13bc7b5c759c1d127b31fe6d3ba94141
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67115


Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
parent 9dbd2767
...@@ -17,8 +17,8 @@ declare(strict_types=1); ...@@ -17,8 +17,8 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver; namespace TYPO3\CMS\Core\Database\Driver;
use Doctrine\DBAL\Driver\PDO\Connection as DoctrineDbalPDOConnection;
use Doctrine\DBAL\Driver\PDO\Exception as PDOException; use Doctrine\DBAL\Driver\PDO\Exception as PDOException;
use Doctrine\DBAL\Driver\PDOConnection as DoctrineDbalPDOConnection;
use PDO; use PDO;
/** /**
......
...@@ -17,7 +17,7 @@ declare(strict_types=1); ...@@ -17,7 +17,7 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver\PDOMySql; namespace TYPO3\CMS\Core\Database\Driver\PDOMySql;
use Doctrine\DBAL\Driver\PDOMySql\Driver as DoctrinePDOMySqlDriver; use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Exception as DBALException;
use PDOException; use PDOException;
use TYPO3\CMS\Core\Database\Driver\PDOConnection; use TYPO3\CMS\Core\Database\Driver\PDOConnection;
...@@ -26,7 +26,7 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection; ...@@ -26,7 +26,7 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection;
* This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3. * This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3.
* All private methods have to be checked on every release of doctrine/dbal. * All private methods have to be checked on every release of doctrine/dbal.
*/ */
class Driver extends DoctrinePDOMySqlDriver class Driver extends AbstractMySQLDriver
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -51,4 +51,47 @@ class Driver extends DoctrinePDOMySqlDriver ...@@ -51,4 +51,47 @@ class Driver extends DoctrinePDOMySqlDriver
return $conn; return $conn;
} }
/**
* Constructs the MySql PDO DSN.
*
* @param mixed[] $params
*
* @return string The DSN.
*/
protected function constructPdoDsn(array $params)
{
$dsn = 'mysql:';
if (isset($params['host']) && $params['host'] !== '') {
$dsn .= 'host=' . $params['host'] . ';';
}
if (isset($params['port'])) {
$dsn .= 'port=' . $params['port'] . ';';
}
if (isset($params['dbname'])) {
$dsn .= 'dbname=' . $params['dbname'] . ';';
}
if (isset($params['unix_socket'])) {
$dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
}
if (isset($params['charset'])) {
$dsn .= 'charset=' . $params['charset'] . ';';
}
return $dsn;
}
/**
* {@inheritdoc}
*
* @deprecated
*/
public function getName()
{
return 'pdo_mysql';
}
} }
...@@ -17,7 +17,7 @@ declare(strict_types=1); ...@@ -17,7 +17,7 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver\PDOPgSql; namespace TYPO3\CMS\Core\Database\Driver\PDOPgSql;
use Doctrine\DBAL\Driver\PDOPgSql\Driver as DoctrineDbalPDOPgSqlDriver; use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Exception as DBALException;
use PDO; use PDO;
use PDOException; use PDOException;
...@@ -27,7 +27,7 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection; ...@@ -27,7 +27,7 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection;
* This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3. * This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3.
* All private methods have to be checked on every release of doctrine/dbal. * All private methods have to be checked on every release of doctrine/dbal.
*/ */
class Driver extends DoctrineDbalPDOPgSqlDriver class Driver extends AbstractPostgreSQLDriver
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -66,7 +66,11 @@ class Driver extends DoctrineDbalPDOPgSqlDriver ...@@ -66,7 +66,11 @@ class Driver extends DoctrineDbalPDOPgSqlDriver
} }
/** /**
* {@inheritdoc} * Constructs the Postgres PDO DSN.
*
* @param mixed[] $params
*
* @return string The DSN.
*/ */
private function _constructPdoDsn(array $params) private function _constructPdoDsn(array $params)
{ {
...@@ -117,4 +121,14 @@ class Driver extends DoctrineDbalPDOPgSqlDriver ...@@ -117,4 +121,14 @@ class Driver extends DoctrineDbalPDOPgSqlDriver
return $dsn; return $dsn;
} }
/**
* {@inheritdoc}
*
* @deprecated
*/
public function getName()
{
return 'pdo_pgsql';
}
} }
...@@ -17,8 +17,9 @@ declare(strict_types=1); ...@@ -17,8 +17,9 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver\PDOSqlite; namespace TYPO3\CMS\Core\Database\Driver\PDOSqlite;
use Doctrine\DBAL\Driver\PDOSqlite\Driver as DoctrinePDOSqliteDriver; use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Exception as DBALException;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use PDOException; use PDOException;
use TYPO3\CMS\Core\Database\Driver\PDOConnection; use TYPO3\CMS\Core\Database\Driver\PDOConnection;
...@@ -26,8 +27,17 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection; ...@@ -26,8 +27,17 @@ use TYPO3\CMS\Core\Database\Driver\PDOConnection;
* This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3. * This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3.
* All private methods have to be checked on every release of doctrine/dbal. * All private methods have to be checked on every release of doctrine/dbal.
*/ */
class Driver extends DoctrinePDOSqliteDriver class Driver extends AbstractSQLiteDriver
{ {
/**
* @var mixed[]
*/
protected $_userDefinedFunctions = [
'sqrt' => ['callback' => [SqlitePlatform::class, 'udfSqrt'], 'numArgs' => 1],
'mod' => ['callback' => [SqlitePlatform::class, 'udfMod'], 'numArgs' => 2],
'locate' => ['callback' => [SqlitePlatform::class, 'udfLocate'], 'numArgs' => -1],
];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -58,4 +68,33 @@ class Driver extends DoctrinePDOSqliteDriver ...@@ -58,4 +68,33 @@ class Driver extends DoctrinePDOSqliteDriver
return $pdo; return $pdo;
} }
/**
* Constructs the Sqlite PDO DSN.
*
* @param mixed[] $params
*
* @return string The DSN.
*/
protected function _constructPdoDsn(array $params)
{
$dsn = 'sqlite:';
if (isset($params['path'])) {
$dsn .= $params['path'];
} elseif (isset($params['memory'])) {
$dsn .= ':memory:';
}
return $dsn;
}
/**
* {@inheritdoc}
*
* @deprecated
*/
public function getName()
{
return 'pdo_sqlite';
}
} }
...@@ -17,15 +17,18 @@ declare(strict_types=1); ...@@ -17,15 +17,18 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver\PDOSqlsrv; namespace TYPO3\CMS\Core\Database\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\Result;
use PDO; use PDO;
/** /**
* This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3. * This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3.
* All private methods have to be checked on every release of doctrine/dbal. * All private methods have to be checked on every release of doctrine/dbal.
*/ */
class Connection extends \Doctrine\DBAL\Driver\PDOSqlsrv\Connection class Connection extends \Doctrine\DBAL\Driver\PDO\Connection
{ {
/** /**
* @internal The connection can be only instantiated by its driver.
*
* {@inheritdoc} * {@inheritdoc}
*/ */
public function __construct($dsn, $user = null, $password = null, ?array $options = null) public function __construct($dsn, $user = null, $password = null, ?array $options = null)
...@@ -33,4 +36,23 @@ class Connection extends \Doctrine\DBAL\Driver\PDOSqlsrv\Connection ...@@ -33,4 +36,23 @@ class Connection extends \Doctrine\DBAL\Driver\PDOSqlsrv\Connection
parent::__construct($dsn, $user, $password, $options); parent::__construct($dsn, $user, $password, $options);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]);
} }
/**
* {@inheritDoc}
*/
public function lastInsertId($name = null)
{
if ($name === null) {
return parent::lastInsertId($name);
}
$stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
$stmt->execute([$name]);
if ($stmt instanceof Result) {
return $stmt->fetchOne();
}
return $stmt->fetchColumn();
}
} }
...@@ -17,11 +17,14 @@ declare(strict_types=1); ...@@ -17,11 +17,14 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Database\Driver\PDOSqlsrv; namespace TYPO3\CMS\Core\Database\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
/** /**
* This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3. * This is a full "clone" of the class of package doctrine/dbal. Scope is to use the PDOConnection of TYPO3.
* All private methods have to be checked on every release of doctrine/dbal. * All private methods have to be checked on every release of doctrine/dbal.
*/ */
class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver class Driver extends AbstractSQLServerDriver
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -39,7 +42,12 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver ...@@ -39,7 +42,12 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
} }
/** /**
* {@inheritdoc} * Constructs the Sqlsrv PDO DSN.
*
* @param mixed[] $params
* @param string[] $connectionOptions
*
* @return string The DSN.
*/ */
private function _constructPdoDsn(array $params, array $connectionOptions) private function _constructPdoDsn(array $params, array $connectionOptions)
{ {
...@@ -47,10 +55,12 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver ...@@ -47,10 +55,12 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
if (isset($params['host'])) { if (isset($params['host'])) {
$dsn .= $params['host']; $dsn .= $params['host'];
}
if (isset($params['port']) && ! empty($params['port'])) { if (isset($params['port'])) {
$dsn .= ',' . $params['port']; $dsn .= ',' . $params['port'];
}
} elseif (isset($params['port'])) {
throw PortWithoutHost::new();
} }
if (isset($params['dbname'])) { if (isset($params['dbname'])) {
...@@ -64,9 +74,6 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver ...@@ -64,9 +74,6 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
return $dsn . $this->getConnectionOptionsDsn($connectionOptions); return $dsn . $this->getConnectionOptionsDsn($connectionOptions);
} }
/**
* {@inheritdoc}
*/
private function splitOptions(array $options): array private function splitOptions(array $options): array
{ {
$driverOptions = []; $driverOptions = [];
...@@ -84,7 +91,9 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver ...@@ -84,7 +91,9 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
} }
/** /**
* {@inheritdoc} * Converts a connection options array to the DSN
*
* @param string[] $connectionOptions
*/ */
private function getConnectionOptionsDsn(array $connectionOptions): string private function getConnectionOptionsDsn(array $connectionOptions): string
{ {
...@@ -99,9 +108,11 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver ...@@ -99,9 +108,11 @@ class Driver extends \Doctrine\DBAL\Driver\PDOSqlsrv\Driver
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated
*/ */
public function getName() public function getName()
{ {
return parent::getName(); return 'pdo_sqlsrv';
} }
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment