Remove deprecated connection classes

parent f63c9893
......@@ -4,11 +4,16 @@
- `AbstractDriverException`
- `DriverException`
- `PDOConnection`
- `PDOException`
- `IBMDB2\DB2Connection`
- `IBMDB2\DB2Driver`
- `IBMDB2\DB2Exception`
- `Mysqli\MysqliConnection`
- `Mysqli\MysqliException`
- `OCI8\OCI8Connection`
- `OCI8\OCI8Exception`
- `SQLSrv\SQLSrvConnection`
- `SQLSrv\SQLSrvException`
## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed.
......
......@@ -87,9 +87,8 @@
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/IBMDB2/Connection.php</exclude-pattern>
<exclude-pattern>src/Driver/Mysqli/Exception/ConnectionFailed.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>
......@@ -112,12 +111,6 @@
<exclude-pattern>src/Schema/Comparator.php</exclude-pattern>
</rule>
<!-- DB2_AUTOCOMMIT_ON/DB2_AUTOCOMMIT_OFF are of int type but db2_autocommit() incorrectly expects bool,
see https://bugs.php.net/bug.php?id=77591 -->
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing">
<exclude-pattern>src/Driver/IBMDB2/DB2Connection.php</exclude-pattern>
</rule>
<!-- The SQLSRV_* functions are defined in the upper case by the sqlsrv extension and violate the standard
see https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server -->
<rule ref="Squiz.PHP.LowercasePHPFunctions">
......
......@@ -19,7 +19,7 @@ parameters:
# changing these would be a BC break, to be done in next major
- "~^Casting to bool something that's already bool.~"
- '~^Property Doctrine\\DBAL\\Schema\\Schema::\$_schemaConfig \(Doctrine\\DBAL\\Schema\\SchemaConfig\) does not accept default value of type false\.\z~'
- '~^Return type \(int\|false\) of method Doctrine\\DBAL\\Driver\\OCI8\\OCI8Connection\:\:lastInsertId\(\) should be compatible with return type \(string\) of method Doctrine\\DBAL\\Driver\\Connection::lastInsertId\(\)~'
- '~^Return type \(int\|false\) of method Doctrine\\DBAL\\Driver\\OCI8\\Connection\:\:lastInsertId\(\) should be compatible with return type \(string\) of method Doctrine\\DBAL\\Driver\\Connection::lastInsertId\(\)~'
# https://github.com/phpstan/phpstan/issues/2857
# TODO: remove in 4.0.0
......@@ -48,12 +48,12 @@ parameters:
# Requires a release of https://github.com/JetBrains/phpstorm-stubs/pull/553
-
message: '~^Call to function assert\(\) with true will always evaluate to true\.$~'
path: %currentWorkingDirectory%/src/Driver/PDOConnection.php
path: %currentWorkingDirectory%/src/Driver/PDO/Connection.php
# Requires a release of https://github.com/JetBrains/phpstorm-stubs/pull/553
-
message: '~^Strict comparison using !== between int and false will always evaluate to true\.$~'
path: %currentWorkingDirectory%/src/Driver/PDOConnection.php
path: %currentWorkingDirectory%/src/Driver/PDO/Connection.php
# False Positive
- '~Strict comparison using === between 1 and 2 will always evaluate to false~'
......
......@@ -38,7 +38,7 @@
Fixing these issues requires an API change
-->
<file name="src/Driver/PDOSqlsrv/Connection.php"/>
<file name="src/Driver/SQLSrv/SQLSrvConnection.php"/>
<file name="src/Driver/SQLSrv/Connection.php"/>
</errorLevel>
</FalsableReturnStatement>
<NullableReturnStatement>
......
......@@ -2,6 +2,162 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
final class Connection extends DB2Connection
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionError;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\IBMDB2\Exception\PrepareFailed;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use stdClass;
use function assert;
use function db2_autocommit;
use function db2_commit;
use function db2_connect;
use function db2_escape_string;
use function db2_exec;
use function db2_last_insert_id;
use function db2_num_rows;
use function db2_pconnect;
use function db2_prepare;
use function db2_rollback;
use function db2_server_info;
use function error_get_last;
use function is_bool;
use const DB2_AUTOCOMMIT_OFF;
use const DB2_AUTOCOMMIT_ON;
final class Connection implements ServerInfoAwareConnection
{
/** @var resource */
private $conn = null;
/**
* @param array<string,mixed> $driverOptions
*
* @throws Exception
*/
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($database, $username, $password, $driverOptions);
}
if ($conn === false) {
throw ConnectionFailed::new();
}
$this->conn = $conn;
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = db2_server_info($this->conn);
assert($serverInfo instanceof stdClass);
return $serverInfo->DBMS_VER;
}
public function prepare(string $sql): DriverStatement
{
$stmt = @db2_prepare($this->conn, $sql);
if ($stmt === false) {
throw PrepareFailed::new(error_get_last()['message']);
}
return new Statement($stmt);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
$input = db2_escape_string($input);
if ($type === ParameterType::INTEGER) {
return $input;
}
return "'" . $input . "'";
}
public function exec(string $statement): int
{
$stmt = @db2_exec($this->conn, $statement);
if ($stmt === false) {
throw ConnectionError::new($this->conn);
}
return db2_num_rows($stmt);
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
return db2_last_insert_id($this->conn);
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
assert(is_bool($result));
return $result;
}
/**
* {@inheritdoc}
*/
public function commit()
{
if (! db2_commit($this->conn)) {
throw ConnectionError::new($this->conn);
}
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
/**
* {@inheritdoc}
*/
public function rollBack()
{
if (! db2_rollback($this->conn)) {
throw ConnectionError::new($this->conn);
}
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
}
<?php
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionError;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\IBMDB2\Exception\PrepareFailed;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use stdClass;
use function assert;
use function db2_autocommit;
use function db2_commit;
use function db2_connect;
use function db2_escape_string;
use function db2_exec;
use function db2_last_insert_id;
use function db2_num_rows;
use function db2_pconnect;
use function db2_prepare;
use function db2_rollback;
use function db2_server_info;
use function error_get_last;
use function is_bool;
use const DB2_AUTOCOMMIT_OFF;
use const DB2_AUTOCOMMIT_ON;
/**
* @deprecated Use {@link Connection} instead
*/
class DB2Connection implements ServerInfoAwareConnection
{
/** @var resource */
private $conn = null;
/**
* @param array<string,mixed> $driverOptions
*
* @throws Exception
*/
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($database, $username, $password, $driverOptions);
}
if ($conn === false) {
throw ConnectionFailed::new();
}
$this->conn = $conn;
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = db2_server_info($this->conn);
assert($serverInfo instanceof stdClass);
return $serverInfo->DBMS_VER;
}
public function prepare(string $sql): DriverStatement
{
$stmt = @db2_prepare($this->conn, $sql);
if ($stmt === false) {
throw PrepareFailed::new(error_get_last()['message']);
}
return new Statement($stmt);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
$input = db2_escape_string($input);
if ($type === ParameterType::INTEGER) {
return $input;
}
return "'" . $input . "'";
}
public function exec(string $statement): int
{
$stmt = @db2_exec($this->conn, $statement);
if ($stmt === false) {
throw ConnectionError::new($this->conn);
}
return db2_num_rows($stmt);
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
return db2_last_insert_id($this->conn);
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
assert(is_bool($result));
return $result;
}
/**
* {@inheritdoc}
*/
public function commit()
{
if (! db2_commit($this->conn)) {
throw ConnectionError::new($this->conn);
}
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
/**
* {@inheritdoc}
*/
public function rollBack()
{
if (! db2_rollback($this->conn)) {
throw ConnectionError::new($this->conn);
}
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
}
......@@ -2,6 +2,168 @@
namespace Doctrine\DBAL\Driver\Mysqli;
final class Connection extends MysqliConnection
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use mysqli;
use function floor;
use function mysqli_init;
use function stripos;
final class Connection implements PingableConnection, ServerInfoAwareConnection
{
/**
* Name of the option to set connection flags
*/
public const OPTION_FLAGS = 'flags';
/** @var mysqli */
private $conn;
/**
* @param iterable<Initializer> $preInitializers
* @param iterable<Initializer> $postInitializers
*
* @throws Exception
*/
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($connection);
}
if (! @$connection->real_connect($host, $username, $password, $database, $port, $socket, $flags)) {
throw ConnectionFailed::new($connection);
}
foreach ($postInitializers as $initializer) {
$initializer->initialize($connection);
}
$this->conn = $connection;
}
/**
* Retrieves mysqli native resource handle.
*
* Could be used if part of your application is not using DBAL.
*
* @return mysqli
*/
public function getWrappedResourceHandle()
{
return $this->conn;
}
/**
* {@inheritdoc}
*
* The server version detection includes a special case for MariaDB
* to support '5.5.5-' prefixed versions introduced in Maria 10+
*
* @link https://jira.mariadb.org/browse/MDEV-4088
*/
public function getServerVersion()
{
$serverInfos = $this->conn->get_server_info();
if (stripos($serverInfos, 'mariadb') !== false) {
return $serverInfos;
}
$majorVersion = floor($this->conn->server_version / 10000);
$minorVersion = floor(($this->conn->server_version - $majorVersion * 10000) / 100);
$patchVersion = floor($this->conn->server_version - $majorVersion * 10000 - $minorVersion * 100);
return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->conn, $sql);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
return "'" . $this->conn->escape_string($input) . "'";
}
public function exec(string $statement): int
{
if ($this->conn->query($statement) === false) {
throw ConnectionError::new($this->conn);
}
return $this->conn->affected_rows;
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
return $this->conn->insert_id;
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$this->conn->query('START TRANSACTION');
return true;
}
/**
* {@inheritdoc}
*/
public function commit()
{
return $this->conn->commit();
}
/**
* {@inheritdoc}non-PHPdoc)
*/
public function rollBack()
{
return $this->conn->rollback();
}
/**
* Pings the server and re-connects when `mysqli.reconnect = 1`
*
* @deprecated
*
* @return bool
*/
public function ping()
{
return $this->conn->ping();
}
}
......@@ -34,9 +34,9 @@ class Driver extends AbstractMySQLDriver
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]);
if (isset($driverOptions[Connection::OPTION_FLAGS])) {
$flags = $driverOptions[Connection::OPTION_FLAGS];
unset($driverOptions[Connection::OPTION_FLAGS]);
}
$preInitializers = $this->withOptions($preInitializers, $driverOptions);
......
<?php
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use mysqli;
use function floor;
use function mysqli_init;
use function stripos;
/**
* @deprecated Use {@link Connection} instead
*/
class MysqliConnection implements PingableConnection, ServerInfoAwareConnection
{
/**
* Name of the option to set connection flags
*/
public const OPTION_FLAGS = 'flags';
/** @var mysqli */
private $conn;
/**
* @param iterable<Initializer> $preInitializers
* @param iterable<Initializer> $postInitializers
*
* @throws Exception
*/
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($connection);
}
if (! @$connection->real_connect($host, $username, $password, $database, $port, $socket, $flags)) {
throw ConnectionFailed::new($connection);
}
foreach ($postInitializers as $initializer) {
$initializer->initialize($connection);
}
$this->conn = $connection;
}
/**
* Retrieves mysqli native resource handle.
*
* Could be used if part of your application is not using DBAL.
*
* @return mysqli
*/
public function getWrappedResourceHandle()
{
return $this->conn;
}
/**
* {@inheritdoc}
*
* The server version detection includes a special case for MariaDB
* to support '5.5.5-' prefixed versions introduced in Maria 10+
*
* @link https://jira.mariadb.org/browse/MDEV-4088
*/
public function getServerVersion()
{
$serverInfos = $this->conn->get_server_info();
if (stripos($serverInfos, 'mariadb') !== false) {
return $serverInfos;
}
$majorVersion = floor($this->conn->server_version / 10000);
$minorVersion = floor(($this->conn->server_version - $majorVersion * 10000) / 100);
$patchVersion = floor($this->conn->server_version - $majorVersion * 10000 - $minorVersion * 100);
return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->conn, $sql);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
return "'" . $this->conn->escape_string($input) . "'";
}
public function exec(string $statement): int
{
if ($this->conn->query($statement) === false) {
throw ConnectionError::new($this->conn);
}
return $this->conn->affected_rows;
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
return $this->conn->insert_id;
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$this->conn->query('START TRANSACTION');
return true;
}
/**
* {@inheritdoc}
*/
public function commit()
{
return $this->conn->commit();
}
/**
* {@inheritdoc}non-PHPdoc)
*/
public function rollBack()
{
return $this->conn->rollback();
}
/**
* Pings the server and re-connects when `mysqli.reconnect = 1`
*
* @deprecated
*
* @return bool
*/
public function ping()
{
return $this->conn->ping();
}
}
......@@ -2,6 +2,182 @@
namespace Doctrine\DBAL\Driver\OCI8;
final class Connection extends OCI8Connection
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\OCI8\Exception\SequenceDoesNotExist;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use UnexpectedValueException;
use function addcslashes;
use function is_float;
use function is_int;
use function oci_commit;
use function oci_connect;
use function oci_pconnect;
use function oci_rollback;
use function oci_server_version;
use function preg_match;
use function sprintf;
use function str_replace;
use const OCI_NO_AUTO_COMMIT;
final class Connection implements ConnectionInterface, ServerInfoAwareConnection
{
/** @var resource */
protected $dbh;
/** @var ExecutionMode */
private $executionMode;
/**
* Creates a Connection to an Oracle Database using oci8 extension.
*
* @param string $username
* @param string $password
* @param string $db
* @param string $charset
* @param int $sessionMode
* @param bool $persistent
*
* @throws Exception
*/
public function __construct(
$username,
$password,
$db,
$charset = '',
$sessionMode = OCI_NO_AUTO_COMMIT,
$persistent = false
) {
$dbh = $persistent
? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
: @oci_connect($username, $password, $db, $charset, $sessionMode);
if ($dbh === false) {
throw ConnectionFailed::new();
}
$this->dbh = $dbh;
$this->executionMode = new ExecutionMode();
}
/**
* {@inheritdoc}
*
* @throws UnexpectedValueException If the version string returned by the database server
* does not contain a parsable version number.
*/
public function getServerVersion()
{
$version = oci_server_version($this->dbh);
if ($version === false) {
throw Error::new($this->dbh);
}
if (preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches) === 0) {
throw new UnexpectedValueException(
sprintf(
'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
'Please report this database version string to the Doctrine team.',
$version
)
);
}
return $matches[1];
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->dbh, $sql, $this->executionMode);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($value, $type = ParameterType::STRING)
{
if (is_int($value) || is_float($value)) {
return $value;
}
$value = str_replace("'", "''", $value);
return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
}
public function exec(string $statement): int
{
return $this->prepare($statement)->execute()->rowCount();
}
/**
* {@inheritdoc}
*
* @return int|false
*/
public function lastInsertId($name = null)
{
if ($name === null) {
return false;
}
$result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne();
if ($result === false) {
throw SequenceDoesNotExist::new();
}
return (int) $result;
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$this->executionMode->disableAutoCommit();
return true;
}
/**
* {@inheritdoc}
*/
public function commit()
{
if (! oci_commit($this->dbh)) {
throw Error::new($this->dbh);
}
$this->executionMode->enableAutoCommit();
return true;
}
/**
* {@inheritdoc}
*/
public function rollBack()
{
if (! oci_rollback($this->dbh)) {
throw Error::new($this->dbh);
}
$this->executionMode->enableAutoCommit();
return true;
}
}
<?php
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\OCI8\Exception\SequenceDoesNotExist;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use UnexpectedValueException;
use function addcslashes;
use function is_float;
use function is_int;
use function oci_commit;
use function oci_connect;
use function oci_pconnect;
use function oci_rollback;
use function oci_server_version;
use function preg_match;
use function sprintf;
use function str_replace;
use const OCI_NO_AUTO_COMMIT;
/**
* OCI8 implementation of the Connection interface.
*
* @deprecated Use {@link Connection} instead
*/
class OCI8Connection implements ConnectionInterface, ServerInfoAwareConnection
{
/** @var resource */
protected $dbh;
/** @var ExecutionMode */
private $executionMode;
/**
* Creates a Connection to an Oracle Database using oci8 extension.
*
* @param string $username
* @param string $password
* @param string $db
* @param string $charset
* @param int $sessionMode
* @param bool $persistent
*
* @throws Exception
*/
public function __construct(
$username,
$password,
$db,
$charset = '',
$sessionMode = OCI_NO_AUTO_COMMIT,
$persistent = false
) {
$dbh = $persistent
? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
: @oci_connect($username, $password, $db, $charset, $sessionMode);
if ($dbh === false) {
throw ConnectionFailed::new();
}
$this->dbh = $dbh;
$this->executionMode = new ExecutionMode();
}
/**
* {@inheritdoc}
*
* @throws UnexpectedValueException If the version string returned by the database server
* does not contain a parsable version number.
*/
public function getServerVersion()
{
$version = oci_server_version($this->dbh);
if ($version === false) {
throw Error::new($this->dbh);
}
if (preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches) === 0) {
throw new UnexpectedValueException(
sprintf(
'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
'Please report this database version string to the Doctrine team.',
$version
)
);
}
return $matches[1];
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->dbh, $sql, $this->executionMode);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritdoc}
*/
public function quote($value, $type = ParameterType::STRING)
{
if (is_int($value) || is_float($value)) {
return $value;
}
$value = str_replace("'", "''", $value);
return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
}
public function exec(string $statement): int
{
return $this->prepare($statement)->execute()->rowCount();
}
/**
* {@inheritdoc}
*
* @return int|false
*/
public function lastInsertId($name = null)
{
if ($name === null) {
return false;
}
$result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne();
if ($result === false) {
throw SequenceDoesNotExist::new();
}
return (int) $result;
}
/**
* {@inheritdoc}
*/
public function beginTransaction()
{
$this->executionMode->disableAutoCommit();
return true;
}
/**
* {@inheritdoc}
*/
public function commit()
{
if (! oci_commit($this->dbh)) {
throw Error::new($this->dbh);
}
$this->executionMode->enableAutoCommit();
return true;
}
/**
* {@inheritdoc}
*/
public function rollBack()
{
if (! oci_rollback($this->dbh)) {
throw Error::new($this->dbh);
}
$this->executionMode->enableAutoCommit();
return true;
}
}
......@@ -2,8 +2,142 @@
namespace Doctrine\DBAL\Driver\PDO;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use PDO;
use PDOException;
use PDOStatement;
class Connection extends PDOConnection
use function assert;
class Connection implements ServerInfoAwareConnection
{
/** @var PDO */
private $connection;
/**
* @param string $dsn
* @param string|null $user
* @param string|null $password
* @param mixed[]|null $options
*
* @throws ExceptionInterface
*/
public function __construct($dsn, $user = null, $password = null, ?array $options = null)
{
try {
$this->connection = new PDO($dsn, (string) $user, (string) $password, (array) $options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
public function exec(string $statement): int
{
try {
$result = $this->connection->exec($statement);
assert($result !== false);
return $result;
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
}
public function prepare(string $sql): StatementInterface
{
try {
return $this->createStatement(
$this->connection->prepare($sql)
);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
public function query(string $sql): ResultInterface
{
try {
$stmt = $this->connection->query($sql);
assert($stmt instanceof PDOStatement);
return new Result($stmt);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
return $this->connection->quote($input, $type);
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
try {
if ($name === null) {
return $this->connection->lastInsertId();
}
return $this->connection->lastInsertId($name);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* Creates a wrapped statement
*/
protected function createStatement(PDOStatement $stmt): Statement
{
return new Statement($stmt);
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
return $this->connection->beginTransaction();
}
/**
* {@inheritDoc}
*/
public function commit()
{
return $this->connection->commit();
}
/**
* {@inheritDoc}
*/
public function rollBack()
{
return $this->connection->rollBack();
}
public function getWrappedConnection(): PDO
{
return $this->connection;
}
}
<?php
namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
use Doctrine\DBAL\Driver\PDO\Exception;
use Doctrine\DBAL\Driver\PDO\Result;
use Doctrine\DBAL\Driver\PDO\Statement;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use PDO;
use PDOException;
use PDOStatement;
use function assert;
/**
* PDO implementation of the Connection interface.
*
* Used by all PDO-based drivers.
*
* @deprecated Use {@link Connection} instead
*/
class PDOConnection implements ServerInfoAwareConnection
{
/** @var PDO */
private $connection;
/**
* @param string $dsn
* @param string|null $user
* @param string|null $password
* @param mixed[]|null $options
*
* @throws ExceptionInterface
*/
public function __construct($dsn, $user = null, $password = null, ?array $options = null)
{
try {
$this->connection = new PDO($dsn, (string) $user, (string) $password, (array) $options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
public function exec(string $statement): int
{
try {
$result = $this->connection->exec($statement);
assert($result !== false);
return $result;
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
}
public function prepare(string $sql): StatementInterface
{
try {
return $this->createStatement(
$this->connection->prepare($sql)
);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
public function query(string $sql): ResultInterface
{
try {
$stmt = $this->connection->query($sql);
assert($stmt instanceof PDOStatement);
return new Result($stmt);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* {@inheritdoc}
*/
public function quote($input, $type = ParameterType::STRING)
{
return $this->connection->quote($input, $type);
}
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
try {
if ($name === null) {
return $this->connection->lastInsertId();
}
return $this->connection->lastInsertId($name);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
/**
* Creates a wrapped statement
*/
protected function createStatement(PDOStatement $stmt): Statement
{
return new Statement($stmt);
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
return $this->connection->beginTransaction();
}
/**
* {@inheritDoc}
*/
public function commit()
{
return $this->connection->commit();
}
/**
* {@inheritDoc}
*/
public function rollBack()
{
return $this->connection->rollBack();
}
public function getWrappedConnection(): PDO
{
return $this->connection;
}
}
......@@ -2,6 +2,157 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
final class Connection extends SQLSrvConnection
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use function is_float;
use function is_int;
use function sprintf;
use function sqlsrv_begin_transaction;
use function sqlsrv_commit;
use function sqlsrv_configure;
use function sqlsrv_connect;
use function sqlsrv_query;
use function sqlsrv_rollback;
use function sqlsrv_rows_affected;
use function sqlsrv_server_info;
use function str_replace;
final class Connection implements ServerInfoAwareConnection
{
/** @var resource */
protected $conn;
/** @var LastInsertId */
protected $lastInsertId;
/**
* @param string $serverName
* @param mixed[] $connectionOptions
*
* @throws Exception
*/
public function __construct($serverName, $connectionOptions)
{
if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
throw Error::new();
}
$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === false) {
throw Error::new();
}
$this->conn = $conn;
$this->lastInsertId = new LastInsertId();
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = sqlsrv_server_info($this->conn);
return $serverInfo['SQLServerVersion'];
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->conn, $sql, $this->lastInsertId);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritDoc}
*/
public function quote($value, $type = ParameterType::STRING)
{
if (is_int($value)) {
return $value;
}
if (is_float($value)) {
return sprintf('%F', $value);
}
return "'" . str_replace("'", "''", $value) . "'";
}
public function exec(string $statement): int
{
$stmt = sqlsrv_query($this->conn, $statement);
if ($stmt === false) {
throw Error::new();
}
$rowsAffected = sqlsrv_rows_affected($stmt);
if ($rowsAffected === false) {
throw Error::new();
}
return $rowsAffected;
}
/**
* {@inheritDoc}
*/
public function lastInsertId($name = null)
{
if ($name !== null) {
$result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
->execute([$name]);
} else {
$result = $this->query('SELECT @@IDENTITY');
}
return $result->fetchOne();
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! sqlsrv_begin_transaction($this->conn)) {
throw Error::new();
}
return true;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! sqlsrv_commit($this->conn)) {
throw Error::new();
}
return true;
}
/**
* {@inheritDoc}
*/
public function rollBack()
{
if (! sqlsrv_rollback($this->conn)) {
throw Error::new();
}
return true;
}
}
<?php
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use function is_float;
use function is_int;
use function sprintf;
use function sqlsrv_begin_transaction;
use function sqlsrv_commit;
use function sqlsrv_configure;
use function sqlsrv_connect;
use function sqlsrv_query;
use function sqlsrv_rollback;
use function sqlsrv_rows_affected;
use function sqlsrv_server_info;
use function str_replace;
/**
* SQL Server implementation for the Connection interface.
*
* @deprecated Use {@link Connection} instead
*/
class SQLSrvConnection implements ServerInfoAwareConnection
{
/** @var resource */
protected $conn;
/** @var LastInsertId */
protected $lastInsertId;
/**
* @param string $serverName
* @param mixed[] $connectionOptions
*
* @throws Exception
*/
public function __construct($serverName, $connectionOptions)
{
if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
throw Error::new();
}
$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === false) {
throw Error::new();
}
$this->conn = $conn;
$this->lastInsertId = new LastInsertId();
}
/**
* {@inheritdoc}
*/
public function getServerVersion()
{
$serverInfo = sqlsrv_server_info($this->conn);
return $serverInfo['SQLServerVersion'];
}
public function prepare(string $sql): DriverStatement
{
return new Statement($this->conn, $sql, $this->lastInsertId);
}
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
}
/**
* {@inheritDoc}
*/
public function quote($value, $type = ParameterType::STRING)
{
if (is_int($value)) {
return $value;
}
if (is_float($value)) {
return sprintf('%F', $value);
}
return "'" . str_replace("'", "''", $value) . "'";
}
public function exec(string $statement): int
{
$stmt = sqlsrv_query($this->conn, $statement);
if ($stmt === false) {
throw Error::new();
}
$rowsAffected = sqlsrv_rows_affected($stmt);
if ($rowsAffected === false) {
throw Error::new();
}
return $rowsAffected;
}
/**
* {@inheritDoc}
*/
public function lastInsertId($name = null)
{
if ($name !== null) {
$result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
->execute([$name]);
} else {
$result = $this->query('SELECT @@IDENTITY');
}
return $result->fetchOne();
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! sqlsrv_begin_transaction($this->conn)) {
throw Error::new();
}
return true;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! sqlsrv_commit($this->conn)) {
throw Error::new();
}
return true;
}
/**
* {@inheritDoc}
*/
public function rollBack()
{
if (! sqlsrv_rollback($this->conn)) {
throw Error::new();
}
return true;
}
}
......@@ -9,7 +9,7 @@ use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection as BaseConnection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
use Doctrine\DBAL\Driver\Result as DriverResult;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Result as DBALResult;
......
......@@ -8,7 +8,7 @@ use Doctrine\DBAL\Tests\FunctionalTestCase;
use function extension_loaded;
class MysqliConnectionTest extends FunctionalTestCase
class ConnectionTest extends FunctionalTestCase
{
protected function setUp(): void
{
......
......@@ -4,7 +4,7 @@ namespace Doctrine\DBAL\Tests\Driver\PDOPgSql;
use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
use Doctrine\DBAL\Driver\PDOPgSql\Driver;
use Doctrine\DBAL\Tests\Driver\AbstractPostgreSQLDriverTest;
use Doctrine\DBAL\Tests\TestUtil;
......
......@@ -5,7 +5,7 @@ namespace Doctrine\DBAL\Tests\Functional;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
......
......@@ -11,7 +11,6 @@ use ReflectionProperty;
use function db2_close;
use function extension_loaded;
use function get_parent_class;
class ConnectionTest extends FunctionalTestCase
{
......@@ -45,7 +44,7 @@ class ConnectionTest extends FunctionalTestCase
{
$driverConnection = $this->connection->getWrappedConnection();
$re = new ReflectionProperty(get_parent_class($driverConnection), 'conn');
$re = new ReflectionProperty($driverConnection, 'conn');
$re->setAccessible(true);
$conn = $re->getValue($driverConnection);
db2_close($conn);
......
......@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Tests\Functional\Driver\Mysqli;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Mysqli\Connection;
use Doctrine\DBAL\Driver\Mysqli\Driver;
use Doctrine\DBAL\Driver\Mysqli\MysqliConnection;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Tests\TestUtil;
......@@ -70,7 +70,7 @@ class ConnectionTest extends FunctionalTestCase
/**
* @param mixed[] $driverOptions
*/
private function getConnection(array $driverOptions): MysqliConnection
private function getConnection(array $driverOptions): Connection
{
$params = TestUtil::getConnectionParams();
......
......@@ -2,8 +2,8 @@
namespace Doctrine\DBAL\Tests\Functional\Driver\OCI8;
use Doctrine\DBAL\Driver\OCI8\Connection;
use Doctrine\DBAL\Driver\OCI8\Driver;
use Doctrine\DBAL\Driver\OCI8\OCI8Connection;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase;
......@@ -11,7 +11,7 @@ use function extension_loaded;
class ConnectionTest extends FunctionalTestCase
{
/** @var OCI8Connection */
/** @var Connection */
protected $driverConnection;
protected function setUp(): void
......
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