Skip to content

Commit

Permalink
[TASK] DBAL: Extend custom drivers from abstract drivers
Browse files Browse the repository at this point in the history
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: TYPO3com <noreply@typo3.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
  • Loading branch information
bmack authored and georgringer committed Dec 14, 2020
1 parent 9dbd276 commit a8663d8
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 19 deletions.
Expand Up @@ -17,8 +17,8 @@

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\PDOConnection as DoctrineDbalPDOConnection;
use PDO;

/**
Expand Down
47 changes: 45 additions & 2 deletions typo3/sysext/core/Classes/Database/Driver/PDOMySql/Driver.php
Expand Up @@ -17,7 +17,7 @@

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 PDOException;
use TYPO3\CMS\Core\Database\Driver\PDOConnection;
Expand All @@ -26,7 +26,7 @@
* 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.
*/
class Driver extends DoctrinePDOMySqlDriver
class Driver extends AbstractMySQLDriver
{
/**
* {@inheritdoc}
Expand All @@ -51,4 +51,47 @@ public function connect(array $params, $username = null, $password = null, array

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';
}
}
20 changes: 17 additions & 3 deletions typo3/sysext/core/Classes/Database/Driver/PDOPgSql/Driver.php
Expand Up @@ -17,7 +17,7 @@

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 PDO;
use PDOException;
Expand All @@ -27,7 +27,7 @@
* 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.
*/
class Driver extends DoctrineDbalPDOPgSqlDriver
class Driver extends AbstractPostgreSQLDriver
{
/**
* {@inheritdoc}
Expand Down Expand Up @@ -66,7 +66,11 @@ public function connect(array $params, $username = null, $password = null, array
}

/**
* {@inheritdoc}
* Constructs the Postgres PDO DSN.
*
* @param mixed[] $params
*
* @return string The DSN.
*/
private function _constructPdoDsn(array $params)
{
Expand Down Expand Up @@ -117,4 +121,14 @@ private function _constructPdoDsn(array $params)

return $dsn;
}

/**
* {@inheritdoc}
*
* @deprecated
*/
public function getName()
{
return 'pdo_pgsql';
}
}
43 changes: 41 additions & 2 deletions typo3/sysext/core/Classes/Database/Driver/PDOSqlite/Driver.php
Expand Up @@ -17,17 +17,27 @@

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\Platforms\SqlitePlatform;
use PDOException;
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.
* 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}
*/
Expand Down Expand Up @@ -58,4 +68,33 @@ public function connect(array $params, $username = null, $password = null, array

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';
}
}
Expand Up @@ -17,20 +17,42 @@

namespace TYPO3\CMS\Core\Database\Driver\PDOSqlsrv;

use Doctrine\DBAL\Driver\Result;
use PDO;

/**
* 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.
*/
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}
*/
public function __construct($dsn, $user = null, $password = null, ?array $options = null)
{
parent::__construct($dsn, $user, $password, $options);
$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();
}
}
31 changes: 21 additions & 10 deletions typo3/sysext/core/Classes/Database/Driver/PDOSqlsrv/Driver.php
Expand Up @@ -17,11 +17,14 @@

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.
* 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}
Expand All @@ -39,18 +42,25 @@ public function connect(array $params, $username = null, $password = null, array
}

/**
* {@inheritdoc}
* Constructs the Sqlsrv PDO DSN.
*
* @param mixed[] $params
* @param string[] $connectionOptions
*
* @return string The DSN.
*/
private function _constructPdoDsn(array $params, array $connectionOptions)
{
$dsn = 'sqlsrv:server=';

if (isset($params['host'])) {
$dsn .= $params['host'];
}

if (isset($params['port']) && ! empty($params['port'])) {
$dsn .= ',' . $params['port'];
if (isset($params['port'])) {
$dsn .= ',' . $params['port'];
}
} elseif (isset($params['port'])) {
throw PortWithoutHost::new();
}

if (isset($params['dbname'])) {
Expand All @@ -64,9 +74,6 @@ private function _constructPdoDsn(array $params, array $connectionOptions)
return $dsn . $this->getConnectionOptionsDsn($connectionOptions);
}

/**
* {@inheritdoc}
*/
private function splitOptions(array $options): array
{
$driverOptions = [];
Expand All @@ -84,7 +91,9 @@ private function splitOptions(array $options): array
}

/**
* {@inheritdoc}
* Converts a connection options array to the DSN
*
* @param string[] $connectionOptions
*/
private function getConnectionOptionsDsn(array $connectionOptions): string
{
Expand All @@ -99,9 +108,11 @@ private function getConnectionOptionsDsn(array $connectionOptions): string

/**
* {@inheritdoc}
*
* @deprecated
*/
public function getName()
{
return parent::getName();
return 'pdo_sqlsrv';
}
}

0 comments on commit a8663d8

Please sign in to comment.