Simplify Driver::connect() signature

parent 57aab098
# Upgrade to 3.0
## BC BREAK changes the `Driver::connect()` signature
The method no longer accepts the `$username`, `$password` and `$driverOptions` arguments. The corresponding values are expected to be passed as the "user", "password" and "driver_options" keys of the `$params` argument respectively.
## Removed `MasterSlaveConnection`
This class was deprecated in favor of `PrimaryReadReplicaConnection`
......
......@@ -83,11 +83,12 @@
<!-- https://github.com/squizlabs/PHP_CodeSniffer/issues/2837 -->
<rule ref="Squiz.NamingConventions.ValidVariableName.NotCamelCaps">
<!--
This file uses the return value db2_server_info(), which does not follow conventions
phpcs wrongly complains about it, and that has been reported here:
These files use the underlying driver APIs that don't comply with the coding standard
phpcs wrongly complains about them, and that has been reported here:
https://github.com/squizlabs/PHP_CodeSniffer/issues/2950
-->
<exclude-pattern>src/Driver/IBMDB2/DB2Connection.php</exclude-pattern>
<exclude-pattern>src/Driver/Mysqli/MysqliConnection.php</exclude-pattern>
<!-- See https://github.com/squizlabs/PHP_CodeSniffer/issues/2837 -->
<exclude-pattern>src/SQLParserUtils.php</exclude-pattern>
<exclude-pattern>src/Tools/Dumper.php</exclude-pattern>
......
......@@ -352,12 +352,8 @@ class Connection implements DriverConnection
return false;
}
$driverOptions = $this->params['driverOptions'] ?? [];
$user = $this->params['user'] ?? null;
$password = $this->params['password'] ?? null;
try {
$this->_conn = $this->_driver->connect($this->params, $user, $password, $driverOptions);
$this->_conn = $this->_driver->connect($this->params);
} catch (DriverException $e) {
throw DBALException::driverException($this->_driver, $e);
}
......
......@@ -225,15 +225,10 @@ class PrimaryReadReplicaConnection extends Connection
{
$params = $this->getParams();
$driverOptions = $params['driverOptions'] ?? [];
$connectionParams = $this->chooseConnectionConfiguration($connectionName, $params);
$user = $connectionParams['user'] ?? null;
$password = $connectionParams['password'] ?? null;
try {
return $this->_driver->connect($connectionParams, $user, $password, $driverOptions);
return $this->_driver->connect($connectionParams);
} catch (DriverException $e) {
throw DBALException::driverException($this->_driver, $e);
}
......
......@@ -2,6 +2,7 @@
namespace Doctrine\DBAL;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
......@@ -15,18 +16,13 @@ interface Driver
/**
* Attempts to create a connection with the database.
*
* The usage of NULL to indicate empty username or password is deprecated. Use an empty string instead.
* @param mixed[] $params All connection parameters.
*
* @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.
*
* @return \Doctrine\DBAL\Driver\Connection The database connection.
* @return DriverConnection The database connection.
*
* @throws DriverException
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = []);
public function connect(array $params);
/**
* Gets the DatabasePlatform instance that provides all the metadata about
......
......@@ -33,21 +33,21 @@ class DB2Connection implements ServerInfoAwareConnection
private $conn = null;
/**
* @param mixed[] $params
* @param string $username
* @param string $password
* @param mixed[] $driverOptions
* @param array<string,mixed> $driverOptions
*
* @throws DB2Exception
*/
public function __construct(array $params, $username, $password, $driverOptions = [])
{
$isPersistent = (isset($params['persistent']) && $params['persistent'] === true);
if ($isPersistent) {
$conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
public function __construct(
string $database,
bool $persistent,
string $username,
string $password,
array $driverOptions = []
) {
if ($persistent) {
$conn = db2_pconnect($database, $username, $password, $driverOptions);
} else {
$conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
$conn = db2_connect($database, $username, $password, $driverOptions);
}
if ($conn === false) {
......
......@@ -12,17 +12,14 @@ class DB2Driver extends AbstractDB2Driver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$params['user'] = $username;
$params['password'] = $password;
$params['dbname'] = DataSourceName::fromConnectionParameters($params)->toString();
return new DB2Connection(
$params,
(string) $username,
(string) $password,
$driverOptions
DataSourceName::fromConnectionParameters($params)->toString(),
isset($params['persistent']) && $params['persistent'] === true,
$params['user'] ?? '',
$params['password'] ?? '',
$params['driver_options'] ?? []
);
}
......
......@@ -3,15 +3,115 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
use function count;
class Driver extends AbstractMySQLDriver
{
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
if (! empty($params['persistent'])) {
if (! isset($params['host'])) {
throw HostRequired::forPersistentConnection();
}
$host = 'p:' . $params['host'];
} else {
$host = $params['host'] ?? null;
}
$flags = null;
$preInitializers = $postInitializers = [];
if (isset($params['driver_options'])) {
$driverOptions = $params['driver_options'];
if (isset($driverOptions[MysqliConnection::OPTION_FLAGS])) {
$flags = $driverOptions[MysqliConnection::OPTION_FLAGS];
unset($driverOptions[MysqliConnection::OPTION_FLAGS]);
}
$preInitializers = $this->withOptions($preInitializers, $driverOptions);
}
$preInitializers = $this->withSecure($preInitializers, $params);
$postInitializers = $this->withCharset($postInitializers, $params);
return new MysqliConnection(
$host,
$params['user'] ?? null,
$params['password'] ?? null,
$params['dbname'] ?? null,
$params['port'] ?? null,
$params['unix_socket'] ?? null,
$flags,
$preInitializers,
$postInitializers
);
}
/**
* @param list<Initializer> $initializers
* @param array<int,mixed> $options
*
* @return list<Initializer>
*/
private function withOptions(array $initializers, array $options): array
{
return new MysqliConnection($params, (string) $username, (string) $password, $driverOptions);
if (count($options) !== 0) {
$initializers[] = new Options($options);
}
return $initializers;
}
/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
*
* @return list<Initializer>
*/
private function withSecure(array $initializers, array $params): array
{
if (
isset($params['ssl_key']) ||
isset($params['ssl_cert']) ||
isset($params['ssl_ca']) ||
isset($params['ssl_capath']) ||
isset($params['ssl_cipher'])
) {
$initializers[] = new Secure(
$params['ssl_key'] ?? null,
$params['ssl_cert'] ?? null,
$params['ssl_ca'] ?? null,
$params['ssl_capath'] ?? null,
$params['ssl_cipher'] ?? null
);
}
return $initializers;
}
/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
*
* @return list<Initializer>
*/
private function withCharset(array $initializers, array $params): array
{
if (isset($params['charset'])) {
$initializers[] = new Charset($params['charset']);
}
return $initializers;
}
/**
......
......@@ -2,9 +2,6 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
......@@ -12,9 +9,7 @@ use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use mysqli;
use function count;
use function floor;
use function ini_get;
use function mysqli_init;
use function stripos;
......@@ -29,55 +24,41 @@ class MysqliConnection implements PingableConnection, ServerInfoAwareConnection
private $conn;
/**
* @param mixed[] $params
* @param string $username
* @param string $password
* @param mixed[] $driverOptions
* @param iterable<Initializer> $preInitializers
* @param iterable<Initializer> $postInitializers
*
* @throws MysqliException
*/
public function __construct(array $params, $username, $password, array $driverOptions = [])
{
$socket = $params['unix_socket'] ?? ini_get('mysqli.default_socket');
$dbname = $params['dbname'] ?? null;
$port = $params['port'] ?? null;
if (! empty($params['persistent'])) {
if (! isset($params['host'])) {
throw HostRequired::forPersistentConnection();
}
$host = 'p:' . $params['host'];
} else {
$host = $params['host'] ?? null;
}
$flags = $driverOptions[static::OPTION_FLAGS] ?? null;
unset($driverOptions[static::OPTION_FLAGS]);
$this->conn = mysqli_init();
$preInitializers = $postInitializers = [];
$preInitializers = $this->withOptions($preInitializers, $driverOptions);
$preInitializers = $this->withSecure($preInitializers, $params);
$postInitializers = $this->withCharset($postInitializers, $params);
public function __construct(
?string $host = null,
?string $username = null,
?string $password = null,
?string $database = null,
?int $port = null,
?string $socket = null,
?int $flags = null,
iterable $preInitializers = [],
iterable $postInitializers = []
) {
$connection = mysqli_init();
foreach ($preInitializers as $initializer) {
$initializer->initialize($this->conn);
$initializer->initialize($connection);
}
if (! @$this->conn->real_connect($host, $username, $password, $dbname, $port, $socket, $flags)) {
if (! @$connection->real_connect($host, $username, $password, $database, $port, $socket, $flags)) {
throw new MysqliException(
$this->conn->connect_error,
$this->conn->sqlstate ?? 'HY000',
$this->conn->connect_errno
$connection->connect_error,
'HY000',
$connection->connect_errno
);
}
foreach ($postInitializers as $initializer) {
$initializer->initialize($this->conn);
$initializer->initialize($connection);
}
$this->conn = $connection;
}
/**
......@@ -192,61 +173,4 @@ class MysqliConnection implements PingableConnection, ServerInfoAwareConnection
{
return $this->conn->ping();
}
/**
* @param list<Initializer> $initializers
* @param array<int,mixed> $options
*
* @return list<Initializer>
*/
private function withOptions(array $initializers, array $options): array
{
if (count($options) !== 0) {
$initializers[] = new Options($options);
}
return $initializers;
}
/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
*
* @return list<Initializer>
*/
private function withSecure(array $initializers, array $params): array
{
if (
isset($params['ssl_key']) ||
isset($params['ssl_cert']) ||
isset($params['ssl_ca']) ||
isset($params['ssl_capath']) ||
isset($params['ssl_cipher'])
) {
$initializers[] = new Secure(
$params['ssl_key'] ?? null,
$params['ssl_cert'] ?? null,
$params['ssl_ca'] ?? null,
$params['ssl_capath'] ?? null,
$params['ssl_cipher'] ?? null
);
}
return $initializers;
}
/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
*
* @return list<Initializer>
*/
private function withCharset(array $initializers, array $params): array
{
if (isset($params['charset'])) {
$initializers[] = new Charset($params['charset']);
}
return $initializers;
}
}
......@@ -14,11 +14,11 @@ class Driver extends AbstractOracleDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
return new OCI8Connection(
(string) $username,
(string) $password,
$params['user'] ?? '',
$params['password'] ?? '',
$this->_constructDsn($params),
$params['charset'] ?? '',
$params['sessionMode'] ?? OCI_NO_AUTO_COMMIT,
......
......@@ -14,16 +14,18 @@ class Driver extends AbstractMySQLDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$driverOptions = $params['driver_options'] ?? [];
if (! empty($params['persistent'])) {
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
return new PDOConnection(
$this->constructPdoDsn($params),
$username,
$password,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
);
}
......
......@@ -19,16 +19,18 @@ class Driver extends AbstractOracleDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$driverOptions = $params['driver_options'] ?? [];
if (! empty($params['persistent'])) {
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
return new PDOConnection(
$this->constructPdoDsn($params),
$username,
$password,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
);
}
......
......@@ -16,17 +16,19 @@ class Driver extends AbstractPostgreSQLDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$driverOptions = $params['driver_options'] ?? [];
if (! empty($params['persistent'])) {
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
$connection = new PDOConnection(
$this->_constructPdoDsn($params),
$username,
$password,
$driverOptions
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions,
);
if (
......
......@@ -23,8 +23,10 @@ class Driver extends AbstractSQLiteDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$driverOptions = $params['driver_options'] ?? [];
if (isset($driverOptions['userDefinedFunctions'])) {
$this->_userDefinedFunctions = array_merge(
$this->_userDefinedFunctions,
......@@ -35,8 +37,8 @@ class Driver extends AbstractSQLiteDriver
$connection = new PDOConnection(
$this->_constructPdoDsn($params),
$username,
$password,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
);
......
......@@ -16,15 +16,17 @@ class Driver extends AbstractSQLServerDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
$pdoOptions = $dsnOptions = [];
foreach ($driverOptions as $option => $value) {
if (is_int($option)) {
$pdoOptions[$option] = $value;
} else {
$dsnOptions[$option] = $value;
if (isset($params['driver_options'])) {
foreach ($params['driver_options'] as $option => $value) {
if (is_int($option)) {
$pdoOptions[$option] = $value;
} else {
$dsnOptions[$option] = $value;
}
}
}
......@@ -34,8 +36,8 @@ class Driver extends AbstractSQLServerDriver
return new Connection(
$this->_constructPdoDsn($params, $dsnOptions),
$username,
$password,
$params['user'] ?? '',
$params['password'] ?? '',
$pdoOptions
);
}
......
......@@ -12,7 +12,7 @@ class Driver extends AbstractSQLServerDriver
/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
public function connect(array $params)
{
if (! isset($params['host'])) {
throw new SQLSrvException("Missing 'host' in configuration for sqlsrv driver.");
......@@ -23,6 +23,8 @@ class Driver extends AbstractSQLServerDriver
$serverName .= ', ' . $params['port'];
}
$driverOptions = $params['driver_options'] ?? [];
if (isset($params['dbname'])) {
$driverOptions['Database'] = $params['dbname'];
}
......@@ -31,12 +33,12 @@ class Driver extends AbstractSQLServerDriver
$driverOptions['CharacterSet'] = $params['charset'];
}
if ($username !== null) {
$driverOptions['UID'] = $username;
if (isset($params['user'])) {
$driverOptions['UID'] = $params['user'];
}
if ($password !== null) {
$driverOptions['PWD'] = $password;
if (isset($params['password'])) {
$driverOptions['PWD'] = $params['password'];
}
if (! isset($driverOptions['ReturnDatesAsStrings'])) {
......
......@@ -2,6 +2,7 @@
namespace Doctrine\DBAL\Tests\Driver\Mysqli;
use Doctrine\DBAL\Driver\Mysqli\Driver;
use Doctrine\DBAL\Driver\Mysqli\HostRequired;
use Doctrine\DBAL\Driver\Mysqli\MysqliConnection;
use Doctrine\DBAL\Platforms\MySqlPlatform;
......@@ -44,6 +45,6 @@ class MysqliConnectionTest extends FunctionalTestCase
public function testHostnameIsRequiredForPersistentConnection(): void
{
$this->expectException(HostRequired::class);
new MysqliConnection(['persistent' => 'true'], '', '');
(new Driver())->connect(['persistent' => 'true']);
}
}
......@@ -3,13 +3,15 @@
namespace Doctrine\DBAL\Tests\Driver\PDOPgSql;
use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\PDOPgSql\Driver;
use Doctrine\DBAL\Tests\Driver\AbstractPostgreSQLDriverTest;
use Doctrine\DBAL\Tests\TestUtil;
use PDO;
use PDOException;
use function array_merge;
class DriverTest extends AbstractPostgreSQLDriverTest
{
public function testReturnsName(): void
......@@ -92,15 +94,13 @@ class DriverTest extends AbstractPostgreSQLDriverTest
/**
* @param array<int,mixed> $driverOptions
*/
private function connect(array $driverOptions): PDOConnection
private function connect(array $driverOptions): Connection
{
$params = TestUtil::getConnectionParams();
return $this->createDriver()->connect(
$params,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
array_merge(
TestUtil::getConnectionParams(),
['driver_options' => $driverOptions]
)
);
}
}
......@@ -31,10 +31,7 @@ abstract class AbstractDriverTest extends FunctionalTestCase
$params = $this->connection->getParams();
unset($params['dbname']);
$user = $params['user'] ?? null;
$password = $params['password'] ?? null;
$connection = $this->driver->connect($params, $user, $password);
$connection = $this->driver->connect($params);
self::assertInstanceOf(DriverConnection::class, $connection);
}
......
......@@ -8,6 +8,7 @@ use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Tests\TestUtil;
use function array_merge;
use function extension_loaded;
use const MYSQLI_OPT_CONNECT_TIMEOUT;
......@@ -73,11 +74,11 @@ class ConnectionTest extends FunctionalTestCase
{
$params = TestUtil::getConnectionParams();
return new MysqliConnection(
$params,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
return (new Driver())->connect(
array_merge(
$params,
['driver_options' => $driverOptions]
)
);
}
}
......@@ -78,10 +78,7 @@ class DriverTest extends AbstractDriverTest
$parameters = $this->connection->getParams();
$parameters['application_name'] = 'doctrine';
$user = $parameters['user'] ?? null;
$password = $parameters['password'] ?? null;
$connection = $this->driver->connect($parameters, $user, $password);
$connection = $this->driver->connect($parameters);
$hash = microtime(true); // required to identify the record in the results uniquely
$sql = sprintf('SELECT * FROM pg_stat_activity WHERE %d = %d', $hash, $hash);
......
......@@ -10,8 +10,8 @@ use Doctrine\DBAL\Tests\Functional\Driver\AbstractDriverTest;
use Doctrine\DBAL\Tests\TestUtil;
use PDO;
use function array_merge;
use function assert;
use function extension_loaded;
class DriverTest extends AbstractDriverTest
......@@ -46,13 +46,11 @@ class DriverTest extends AbstractDriverTest
*/
protected function getConnection(array $driverOptions): Connection
{
$params = TestUtil::getConnectionParams();
return $this->connection->getDriver()->connect(
$params,
$params['user'] ?? '',
$params['password'] ?? '',
$driverOptions
array_merge(
TestUtil::getConnectionParams(),
['driver_options' => $driverOptions]
)
);
}
......
......@@ -117,10 +117,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
$params['dbname'] = 'test_drop_database';
}
$user = $params['user'] ?? null;
$password = $params['password'] ?? null;
$connection = $this->connection->getDriver()->connect($params, $user, $password);
$connection = $this->connection->getDriver()->connect($params);
self::assertInstanceOf(Connection::class, $connection);
......
......@@ -50,10 +50,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
$params = $this->connection->getParams();
$params['dbname'] = 'test_drop_database';
$user = $params['user'] ?? null;
$password = $params['password'] ?? null;
$connection = $this->connection->getDriver()->connect($params, $user, $password);
$connection = $this->connection->getDriver()->connect($params);
self::assertInstanceOf(Connection::class, $connection);
......
Markdown is supported
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