From be2e4f5d9fe7cac23ba4959bc3852bbf6d35457b Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Fri, 24 May 2019 19:00:08 -0700 Subject: [PATCH] Enforced parameter and return value types in Driver classes --- UPGRADE.md | 5 ++ lib/Doctrine/DBAL/Connection.php | 4 +- .../Connections/MasterSlaveConnection.php | 4 +- lib/Doctrine/DBAL/Driver.php | 28 ++++---- .../DBAL/Driver/AbstractDB2Driver.php | 8 ++- .../DBAL/Driver/AbstractMySQLDriver.php | 16 +++-- .../DBAL/Driver/AbstractOracleDriver.php | 18 ++--- .../DBAL/Driver/AbstractPostgreSQLDriver.php | 16 +++-- .../DBAL/Driver/AbstractSQLAnywhereDriver.php | 16 +++-- .../DBAL/Driver/AbstractSQLServerDriver.php | 10 +-- .../DBAL/Driver/AbstractSQLiteDriver.php | 14 ++-- .../DBAL/Driver/ExceptionConverterDriver.php | 11 +-- lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php | 57 ++++++++++----- lib/Doctrine/DBAL/Driver/Mysqli/Driver.php | 11 ++- lib/Doctrine/DBAL/Driver/OCI8/Driver.php | 15 ++-- lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php | 11 ++- lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php | 11 ++- lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php | 11 ++- lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php | 11 ++- lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php | 11 ++- .../DBAL/Driver/SQLAnywhere/Driver.php | 72 ++++++++++--------- lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php | 13 ++-- .../DBAL/Sharding/PoolingShardConnection.php | 4 +- .../DBAL/VersionAwarePlatformDriver.php | 4 +- tests/Doctrine/Tests/DBAL/ConnectionTest.php | 4 +- .../Functional/Driver/AbstractDriverTest.php | 4 +- .../Functional/Driver/PDOPgSql/DriverTest.php | 4 +- .../SchemaManagerFunctionalTestCase.php | 4 +- .../Schema/SqliteSchemaManagerTest.php | 4 +- 29 files changed, 247 insertions(+), 154 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 33ee0b5f79b..fd85577aaf5 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,10 @@ # Upgrade to 3.0 +## BC BREAK: Changes in the `Doctrine\DBAL\Driver` API + +1. The `$username` and `$password` arguments of `::connect()` are no longer nullable. Use an empty string to indicate empty username or password. +2. The return value of `::getDatabase()` has been documented as nullable since some of the drivers allow establishing a connection without selecting a database. + ## BC BREAK: `Doctrine\DBAL\Driver::getName()` removed The `Doctrine\DBAL\Driver::getName()` has been removed. diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index e02b4c4b3ee..40164cb1fb2 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -322,8 +322,8 @@ public function connect() : void } $driverOptions = $this->params['driverOptions'] ?? []; - $user = $this->params['user'] ?? null; - $password = $this->params['password'] ?? null; + $user = $this->params['user'] ?? ''; + $password = $this->params['password'] ?? ''; $this->_conn = $this->_driver->connect($this->params, $user, $password, $driverOptions); $this->isConnected = true; diff --git a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php index 3174ed1a17d..9ed48ae6c9c 100644 --- a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php +++ b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php @@ -192,8 +192,8 @@ protected function connectTo($connectionName) $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params); - $user = $connectionParams['user'] ?? null; - $password = $connectionParams['password'] ?? null; + $user = $connectionParams['user'] ?? ''; + $password = $connectionParams['password'] ?? ''; return $this->_driver->connect($connectionParams, $user, $password, $driverOptions); } diff --git a/lib/Doctrine/DBAL/Driver.php b/lib/Doctrine/DBAL/Driver.php index 622dfa12a3c..10ef3488c77 100644 --- a/lib/Doctrine/DBAL/Driver.php +++ b/lib/Doctrine/DBAL/Driver.php @@ -4,6 +4,7 @@ namespace Doctrine\DBAL; +use Doctrine\DBAL\Driver\Connection as DriverConnection; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\AbstractSchemaManager; @@ -16,14 +17,19 @@ interface Driver /** * Attempts to create a connection with the database. * - * @param mixed[] $params All connection parameters passed by the user. - * @param string|null $username The username to use when connecting. - * @param string|null $password The password to use when connecting. - * @param mixed[] $driverOptions The driver options to use when connecting. + * @param mixed[] $params All connection parameters passed by the user. + * @param string $username The username to use when connecting. + * @param string $password The password to use when connecting. + * @param mixed[] $driverOptions The driver options to use when connecting. * - * @return \Doctrine\DBAL\Driver\Connection The database connection. + * @return DriverConnection The database connection. */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []); + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : DriverConnection; /** * Gets the DatabasePlatform instance that provides all the metadata about @@ -31,20 +37,18 @@ public function connect(array $params, $username = null, $password = null, array * * @return AbstractPlatform The database platform. */ - public function getDatabasePlatform(); + public function getDatabasePlatform() : AbstractPlatform; /** * Gets the SchemaManager that can be used to inspect and change the underlying * database schema of the platform this driver connects to. - * - * @return AbstractSchemaManager */ - public function getSchemaManager(Connection $conn); + public function getSchemaManager(Connection $conn) : AbstractSchemaManager; /** * Gets the name of the database connected to for this driver. * - * @return string The name of the database. + * @return string The name of the database or NULL if no database is currently selected. */ - public function getDatabase(Connection $conn); + public function getDatabase(Connection $conn) : ?string; } diff --git a/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php b/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php index f283ed163ea..c98c376f10f 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php @@ -6,7 +6,9 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\DB2Platform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\DB2SchemaManager; /** @@ -17,7 +19,7 @@ abstract class AbstractDB2Driver implements Driver /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -27,7 +29,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new DB2Platform(); } @@ -35,7 +37,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new DB2SchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php index be0074ce0f4..fada4ed9e4a 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php @@ -7,12 +7,16 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\InvalidPlatformVersion; use Doctrine\DBAL\Platforms\MariaDb1027Platform; use Doctrine\DBAL\Platforms\MySQL57Platform; use Doctrine\DBAL\Platforms\MySQL80Platform; use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\MySqlSchemaManager; use Doctrine\DBAL\VersionAwarePlatformDriver; use function preg_match; @@ -30,7 +34,7 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver, * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html * @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html */ - public function convertException($message, DriverException $exception) + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException { switch ($exception->getCode()) { case 1213: @@ -106,7 +110,7 @@ public function convertException($message, DriverException $exception) return new Exception\NotNullConstraintViolationException($message, $exception); } - return new Exception\DriverException($message, $exception); + return new DriverException($message, $exception); } /** @@ -114,7 +118,7 @@ public function convertException($message, DriverException $exception) * * @throws DBALException */ - public function createDatabasePlatformForVersion($version) + public function createDatabasePlatformForVersion(string $version) : AbstractPlatform { $mariadb = stripos($version, 'mariadb') !== false; if ($mariadb && version_compare($this->getMariaDbMysqlVersionNumber($version), '10.2.7', '>=')) { @@ -192,7 +196,7 @@ private function getMariaDbMysqlVersionNumber(string $versionString) : string /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -204,7 +208,7 @@ public function getDatabase(Connection $conn) * * @return MySqlPlatform */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new MySqlPlatform(); } @@ -214,7 +218,7 @@ public function getDatabasePlatform() * * @return MySqlSchemaManager */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new MySqlSchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php b/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php index 00020139565..17e04bbf937 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php @@ -7,8 +7,12 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver\AbstractOracleDriver\EasyConnectString; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\OracleSchemaManager; /** @@ -19,7 +23,7 @@ abstract class AbstractOracleDriver implements Driver, ExceptionConverterDriver /** * {@inheritdoc} */ - public function convertException($message, DriverException $exception) + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException { switch ($exception->getCode()) { case 1: @@ -56,13 +60,13 @@ public function convertException($message, DriverException $exception) return new Exception\ForeignKeyConstraintViolationException($message, $exception); } - return new Exception\DriverException($message, $exception); + return new DriverException($message, $exception); } /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -72,7 +76,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new OraclePlatform(); } @@ -80,7 +84,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new OracleSchemaManager($conn); } @@ -89,10 +93,8 @@ public function getSchemaManager(Connection $conn) * Returns an appropriate Easy Connect String for the given parameters. * * @param mixed[] $params The connection parameters to return the Easy Connect String for. - * - * @return string */ - protected function getEasyConnectString(array $params) + protected function getEasyConnectString(array $params) : string { return (string) EasyConnectString::fromConnectionParameters($params); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php index 726d4cce38e..933837e166c 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php @@ -6,11 +6,15 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\InvalidPlatformVersion; use Doctrine\DBAL\Platforms\PostgreSQL100Platform; use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\PostgreSqlPlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\PostgreSqlSchemaManager; use Doctrine\DBAL\VersionAwarePlatformDriver; use function preg_match; @@ -27,7 +31,7 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri * * @link http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html */ - public function convertException($message, DriverException $exception) + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException { switch ($exception->getSQLState()) { case '40001': @@ -73,13 +77,13 @@ public function convertException($message, DriverException $exception) return new Exception\ConnectionException($message, $exception); } - return new Exception\DriverException($message, $exception); + return new DriverException($message, $exception); } /** * {@inheritdoc} */ - public function createDatabasePlatformForVersion($version) + public function createDatabasePlatformForVersion(string $version) : AbstractPlatform { if (! preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts)) { throw InvalidPlatformVersion::new( @@ -106,7 +110,7 @@ public function createDatabasePlatformForVersion($version) /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -116,7 +120,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new PostgreSqlPlatform(); } @@ -124,7 +128,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new PostgreSqlSchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php index 2acb5777d1d..248c0cfbd2f 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php @@ -6,9 +6,13 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\InvalidPlatformVersion; use Doctrine\DBAL\Platforms\SQLAnywherePlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager; use Doctrine\DBAL\VersionAwarePlatformDriver; use function preg_match; @@ -23,7 +27,7 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr * * @link http://dcx.sybase.com/index.html#sa160/en/saerrors/sqlerror.html */ - public function convertException($message, DriverException $exception) + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException { switch ($exception->getCode()) { case -306: @@ -60,13 +64,13 @@ public function convertException($message, DriverException $exception) return new Exception\TableNotFoundException($message, $exception); } - return new Exception\DriverException($message, $exception); + return new DriverException($message, $exception); } /** * {@inheritdoc} */ - public function createDatabasePlatformForVersion($version) + public function createDatabasePlatformForVersion(string $version) : AbstractPlatform { if (! preg_match( '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', @@ -88,7 +92,7 @@ public function createDatabasePlatformForVersion($version) /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -98,7 +102,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new SQLAnywherePlatform(); } @@ -106,7 +110,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new SQLAnywhereSchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php index 960484d9629..4fd6d1442a4 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php @@ -6,9 +6,11 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\Exception\InvalidPlatformVersion; use Doctrine\DBAL\Platforms\SQLServer2012Platform; use Doctrine\DBAL\Platforms\SQLServerPlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\SQLServerSchemaManager; use Doctrine\DBAL\VersionAwarePlatformDriver; use function preg_match; @@ -22,7 +24,7 @@ abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDr /** * {@inheritdoc} */ - public function createDatabasePlatformForVersion($version) + public function createDatabasePlatformForVersion(string $version) : AbstractPlatform { if (! preg_match( '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', @@ -52,7 +54,7 @@ public function createDatabasePlatformForVersion($version) /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -62,7 +64,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new SQLServerPlatform(); } @@ -70,7 +72,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new SQLServerSchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php index abb7db13153..05fe3b62051 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php @@ -6,8 +6,12 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\SqliteSchemaManager; use function strpos; @@ -21,7 +25,7 @@ abstract class AbstractSQLiteDriver implements Driver, ExceptionConverterDriver * * @link http://www.sqlite.org/c3ref/c_abort.html */ - public function convertException($message, DriverException $exception) + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException { if (strpos($exception->getMessage(), 'database is locked') !== false) { return new Exception\LockWaitTimeoutException($message, $exception); @@ -69,13 +73,13 @@ public function convertException($message, DriverException $exception) return new Exception\ConnectionException($message, $exception); } - return new Exception\DriverException($message, $exception); + return new DriverException($message, $exception); } /** * {@inheritdoc} */ - public function getDatabase(Connection $conn) + public function getDatabase(Connection $conn) : ?string { $params = $conn->getParams(); @@ -85,7 +89,7 @@ public function getDatabase(Connection $conn) /** * {@inheritdoc} */ - public function getDatabasePlatform() + public function getDatabasePlatform() : AbstractPlatform { return new SqlitePlatform(); } @@ -93,7 +97,7 @@ public function getDatabasePlatform() /** * {@inheritdoc} */ - public function getSchemaManager(Connection $conn) + public function getSchemaManager(Connection $conn) : AbstractSchemaManager { return new SqliteSchemaManager($conn); } diff --git a/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php b/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php index 344eca14841..2ce84676064 100644 --- a/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php +++ b/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php @@ -4,6 +4,9 @@ namespace Doctrine\DBAL\Driver; +use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface; +use Doctrine\DBAL\Exception\DriverException; + /** * Contract for a driver that is capable of converting DBAL driver exceptions into standardized DBAL driver exceptions. */ @@ -15,10 +18,10 @@ interface ExceptionConverterDriver * It evaluates the vendor specific error code and SQLSTATE and transforms * it into a unified {@link Doctrine\DBAL\Exception\DriverException} subclass. * - * @param string $message The DBAL exception message to use. - * @param DriverException $exception The DBAL driver exception to convert. + * @param string $message The DBAL exception message to use. + * @param DriverExceptionInterface $exception The DBAL driver exception to convert. * - * @return \Doctrine\DBAL\Exception\DriverException An instance of one of the DriverException subclasses. + * @return DriverException An instance of one of the DriverException subclasses. */ - public function convertException($message, DriverException $exception); + public function convertException(string $message, DriverExceptionInterface $exception) : DriverException; } diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php index 3040a147eac..604a46ad1e9 100644 --- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php +++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -5,6 +5,11 @@ namespace Doctrine\DBAL\Driver\IBMDB2; use Doctrine\DBAL\Driver\AbstractDB2Driver; +use Doctrine\DBAL\Driver\Connection; +use function array_keys; +use function array_map; +use function implode; +use function sprintf; /** * IBM DB2 Driver. @@ -14,28 +19,42 @@ class DB2Driver extends AbstractDB2Driver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { - if (! isset($params['protocol'])) { - $params['protocol'] = 'TCPIP'; - } - + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if ($params['host'] !== 'localhost' && $params['host'] !== '127.0.0.1') { // if the host isn't localhost, use extended connection params - $params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' . - ';DATABASE=' . $params['dbname'] . - ';HOSTNAME=' . $params['host'] . - ';PROTOCOL=' . $params['protocol'] . - ';UID=' . $username . - ';PWD=' . $password . ';'; - if (isset($params['port'])) { - $params['dbname'] .= 'PORT=' . $params['port']; - } - - $username = null; - $password = null; + $params['dbname'] = $this->buildConnectionString($params, $username, $password); + + $username = $password = ''; + } + + return new DB2Connection($params, $username, $password, $driverOptions); + } + + /** + * @param string[] $params + */ + private function buildConnectionString(array $params, string $username, string $password) : string + { + $connectionParams = [ + 'DRIVER' => '{IBM DB2 ODBC DRIVER}', + 'DATABASE' => $params['dbname'], + 'HOSTNAME' => $params['host'], + 'PROTOCOL' => $params['protocol'] ?? 'TCPIP', + 'UID' => $username, + 'PWD' => $password, + ]; + + if (isset($params['port'])) { + $connectionParams['PORT'] = $params['port']; } - return new DB2Connection($params, (string) $username, (string) $password, $driverOptions); + return implode(';', array_map(static function (string $key, string $value) : string { + return sprintf('%s=%s', $key, $value); + }, array_keys($connectionParams), $connectionParams)); } } diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php index df37df4bdd5..882a16d030c 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -6,16 +6,21 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractMySQLDriver; +use Doctrine\DBAL\Driver\Connection; class Driver extends AbstractMySQLDriver { /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { try { - return new MysqliConnection($params, (string) $username, (string) $password, $driverOptions); + return new MysqliConnection($params, $username, $password, $driverOptions); } catch (MysqliException $e) { throw DBALException::driverException($this, $e); } diff --git a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php index fa53b3e175b..bf392885e70 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractOracleDriver; +use Doctrine\DBAL\Driver\Connection; use const OCI_DEFAULT; /** @@ -16,12 +17,16 @@ class Driver extends AbstractOracleDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { try { return new OCI8Connection( - (string) $username, - (string) $password, + $username, + $password, $this->_constructDsn($params), $params['charset'] ?? '', $params['sessionMode'] ?? OCI_DEFAULT, @@ -39,7 +44,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - protected function _constructDsn(array $params) + protected function _constructDsn(array $params) : string { return $this->getEasyConnectString($params); } diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php index 7236c11568b..73ef818b143 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractMySQLDriver; +use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\PDOConnection; use Doctrine\DBAL\Driver\PDOException; use PDO; @@ -18,8 +19,12 @@ class Driver extends AbstractMySQLDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if (! empty($params['persistent'])) { $driverOptions[PDO::ATTR_PERSISTENT] = true; } @@ -45,7 +50,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - protected function constructPdoDsn(array $params) + protected function constructPdoDsn(array $params) : string { $dsn = 'mysql:'; if (isset($params['host']) && $params['host'] !== '') { diff --git a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php index 78b31ab9908..6dfcdb6b428 100644 --- a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractOracleDriver; +use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\PDOConnection; use Doctrine\DBAL\Driver\PDOException; use PDO; @@ -23,8 +24,12 @@ class Driver extends AbstractOracleDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if (! empty($params['persistent'])) { $driverOptions[PDO::ATTR_PERSISTENT] = true; } @@ -48,7 +53,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function constructPdoDsn(array $params) + private function constructPdoDsn(array $params) : string { $dsn = 'oci:dbname=' . $this->getEasyConnectString($params); diff --git a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php index 7c18d962f47..800be0adb19 100644 --- a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver; +use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\PDOConnection; use Doctrine\DBAL\Driver\PDOException; use PDO; @@ -19,8 +20,12 @@ class Driver extends AbstractPostgreSQLDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if (! empty($params['persistent'])) { $driverOptions[PDO::ATTR_PERSISTENT] = true; } @@ -62,7 +67,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function _constructPdoDsn(array $params) + private function _constructPdoDsn(array $params) : string { $dsn = 'pgsql:'; diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php index 61f28dbb44e..89598f0826c 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractSQLiteDriver; +use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\PDOConnection; use Doctrine\DBAL\Driver\PDOException; use Doctrine\DBAL\Platforms\SqlitePlatform; @@ -26,8 +27,12 @@ class Driver extends AbstractSQLiteDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if (isset($driverOptions['userDefinedFunctions'])) { $this->_userDefinedFunctions = array_merge( $this->_userDefinedFunctions, @@ -63,7 +68,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - protected function _constructPdoDsn(array $params) + protected function _constructPdoDsn(array $params) : string { $dsn = 'sqlite:'; if (isset($params['path'])) { diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php index 4e8905dc4bf..4096d5127b6 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Driver\PDOSqlsrv; use Doctrine\DBAL\Driver\AbstractSQLServerDriver; +use Doctrine\DBAL\Driver\Connection as DriverConnection; use PDO; use function is_int; use function sprintf; @@ -17,8 +18,12 @@ class Driver extends AbstractSQLServerDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : DriverConnection { $pdoOptions = $dsnOptions = []; foreach ($driverOptions as $option => $value) { @@ -49,7 +54,7 @@ public function connect(array $params, $username = null, $password = null, array * * @return string The DSN. */ - private function _constructPdoDsn(array $params, array $connectionOptions) + private function _constructPdoDsn(array $params, array $connectionOptions) : string { $dsn = 'sqlsrv:server='; diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php index 8c653fb8fbb..9264e50a39d 100644 --- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php +++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php @@ -6,9 +6,12 @@ use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver; +use Doctrine\DBAL\Driver\Connection; use function array_keys; use function array_map; +use function array_merge; use function implode; +use function sprintf; /** * A Doctrine DBAL driver for the SAP Sybase SQL Anywhere PHP extension. @@ -20,19 +23,15 @@ class Driver extends AbstractSQLAnywhereDriver * * @throws DBALException If there was a problem establishing the connection. */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { try { return new SQLAnywhereConnection( - $this->buildDsn( - $params['host'] ?? null, - $params['port'] ?? null, - $params['server'] ?? null, - $params['dbname'] ?? null, - $username, - $password, - $driverOptions - ), + $this->buildDsn($params, $username, $password, $driverOptions), $params['persistent'] ?? false ); } catch (SQLAnywhereException $e) { @@ -43,37 +42,40 @@ public function connect(array $params, $username = null, $password = null, array /** * Build the connection string for given connection parameters and driver options. * - * @param string $host Host address to connect to. - * @param int $port Port to use for the connection (default to SQL Anywhere standard port 2638). - * @param string $server Database server name on the host to connect to. - * SQL Anywhere allows multiple database server instances on the same host, - * therefore specifying the server instance name to use is mandatory. - * @param string $dbname Name of the database on the server instance to connect to. + * @param mixed[] $params DBAL connection parameters * @param string $username User name to use for connection authentication. * @param string $password Password to use for connection authentication. * @param mixed[] $driverOptions Additional parameters to use for the connection. - * - * @return string */ - private function buildDsn($host, $port, $server, $dbname, $username = null, $password = null, array $driverOptions = []) + private function buildDsn(array $params, string $username, string $password, array $driverOptions = []) : string { - $host = $host ?: 'localhost'; - $port = $port ?: 2638; + $connectionParams = []; + + if (isset($params['host'])) { + $host = $params['host']; - if (! empty($server)) { - $server = ';ServerName=' . $server; + if (isset($params['port'])) { + $host .= sprintf(':%d', $params['port']); + } + + $connectionParams['HOST'] = $host; } - return 'HOST=' . $host . ':' . $port . - $server . - ';DBN=' . $dbname . - ';UID=' . $username . - ';PWD=' . $password . - ';' . implode( - ';', - array_map(static function ($key, $value) { - return $key . '=' . $value; - }, array_keys($driverOptions), $driverOptions) - ); + if (isset($params['server'])) { + $connectionParams['ServerName'] = $params['server']; + } + + if (isset($params['dbname'])) { + $connectionParams['DBN'] = $params['dbname']; + } + + $connectionParams['UID'] = $username; + $connectionParams['PWD'] = $password; + + $connectionParams = array_merge($connectionParams, $driverOptions); + + return implode(';', array_map(static function (string $key, string $value) : string { + return sprintf('%s=%s', $key, $value); + }, array_keys($connectionParams), $connectionParams)); } } diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php index 922a7e14fa6..c786b996c58 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Driver\SQLSrv; use Doctrine\DBAL\Driver\AbstractSQLServerDriver; +use Doctrine\DBAL\Driver\Connection; /** * Driver for ext/sqlsrv. @@ -14,8 +15,12 @@ class Driver extends AbstractSQLServerDriver /** * {@inheritdoc} */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { + public function connect( + array $params, + string $username = '', + string $password = '', + array $driverOptions = [] + ) : Connection { if (! isset($params['host'])) { throw new SQLSrvException('Missing "host" in configuration for sqlsrv driver.'); } @@ -33,11 +38,11 @@ public function connect(array $params, $username = null, $password = null, array $driverOptions['CharacterSet'] = $params['charset']; } - if ($username !== null) { + if ($username !== '') { $driverOptions['UID'] = $username; } - if ($password !== null) { + if ($password !== '') { $driverOptions['PWD'] = $password; } diff --git a/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php b/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php index ad7379a5d78..72744474cac 100644 --- a/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php +++ b/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php @@ -218,8 +218,8 @@ protected function connectTo($shardId) $connectionParams = $this->connectionParameters[$shardId]; - $user = $connectionParams['user'] ?? null; - $password = $connectionParams['password'] ?? null; + $user = $connectionParams['user'] ?? ''; + $password = $connectionParams['password'] ?? ''; return $this->_driver->connect($connectionParams, $user, $password, $driverOptions); } diff --git a/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php b/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php index c61f47d2df0..eabec7b969b 100644 --- a/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php +++ b/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php @@ -22,9 +22,7 @@ interface VersionAwarePlatformDriver * @param string $version The platform/server version string to evaluate. This should be given in the notation * the underlying database vendor uses. * - * @return AbstractPlatform - * * @throws DBALException If the given version string could not be evaluated. */ - public function createDatabasePlatformForVersion($version); + public function createDatabasePlatformForVersion(string $version) : AbstractPlatform; } diff --git a/tests/Doctrine/Tests/DBAL/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/ConnectionTest.php index e4d76735a0a..173406c8cdd 100644 --- a/tests/Doctrine/Tests/DBAL/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/ConnectionTest.php @@ -695,8 +695,8 @@ public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() : v /** @var Driver|VersionAwarePlatformDriver|MockObject $driverMock */ $driverMock = $this->createMock([Driver::class, VersionAwarePlatformDriver::class]); - /** @var ServerInfoAwareConnection|MockObject $driverConnectionMock */ - $driverConnectionMock = $this->createMock(ServerInfoAwareConnection::class); + /** @var DriverConnection|ServerInfoAwareConnection|MockObject $driverConnectionMock */ + $driverConnectionMock = $this->createMock([DriverConnection::class, ServerInfoAwareConnection::class]); /** @var AbstractPlatform|MockObject $platformMock */ $platformMock = $this->getMockForAbstractClass(AbstractPlatform::class); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/AbstractDriverTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/AbstractDriverTest.php index 0669f8b6539..992a9ba691c 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Driver/AbstractDriverTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/AbstractDriverTest.php @@ -33,8 +33,8 @@ public function testConnectsWithoutDatabaseNameParameter() : void $params = $this->connection->getParams(); unset($params['dbname']); - $user = $params['user'] ?? null; - $password = $params['password'] ?? null; + $user = $params['user'] ?? ''; + $password = $params['password'] ?? ''; $connection = $this->driver->connect($params, $user, $password); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOPgSql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOPgSql/DriverTest.php index 5a392031044..2f06cfe3862 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOPgSql/DriverTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOPgSql/DriverTest.php @@ -79,8 +79,8 @@ public function testConnectsWithApplicationNameParameter() : void $parameters = $this->connection->getParams(); $parameters['application_name'] = 'doctrine'; - $user = $parameters['user'] ?? null; - $password = $parameters['password'] ?? null; + $user = $parameters['user'] ?? ''; + $password = $parameters['password'] ?? ''; $connection = $this->driver->connect($parameters, $user, $password); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php index 4e850c1be34..a55c89d6f68 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -117,8 +117,8 @@ public function testDropsDatabaseWithActiveConnections() : void $params['dbname'] = 'test_drop_database'; } - $user = $params['user'] ?? null; - $password = $params['password'] ?? null; + $user = $params['user'] ?? ''; + $password = $params['password'] ?? ''; $connection = $this->connection->getDriver()->connect($params, $user, $password); diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php index f6ab16add9f..404b3ac0ad1 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php @@ -51,8 +51,8 @@ public function testDropsDatabaseWithActiveConnections() : void $params = $this->connection->getParams(); $params['dbname'] = 'test_drop_database'; - $user = $params['user'] ?? null; - $password = $params['password'] ?? null; + $user = $params['user'] ?? ''; + $password = $params['password'] ?? ''; $connection = $this->connection->getDriver()->connect($params, $user, $password);