PDO connection and statement classes made final

parent 4f578bea
# Upgrade to 3.0 # Upgrade to 3.0
## BC BREAK: Changes in PDO driver classes
1. The `PDO\Connection` and `PDO\Statement` classes have been made final.
2. The `PDOSqlsrv\Connection` and `PDOSqlsrv\Statement` classes have been made final and no longer extend the corresponding PDO classes.
## BC BREAK: Changes in driver-level exception handling ## BC BREAK: Changes in driver-level exception handling
1. The `convertException()` method has been removed from the `Driver` interface. The logic of exception conversion has been moved to the `ExceptionConverter` interface. The drivers now must implement the `getExceptionConverter()` method. 1. The `convertException()` method has been removed from the `Driver` interface. The logic of exception conversion has been moved to the `ExceptionConverter` interface. The drivers now must implement the `getExceptionConverter()` method.
......
...@@ -13,7 +13,7 @@ use PDOStatement; ...@@ -13,7 +13,7 @@ use PDOStatement;
use function assert; use function assert;
class Connection implements ServerInfoAwareConnection final class Connection implements ServerInfoAwareConnection
{ {
/** @var PDO */ /** @var PDO */
private $connection; private $connection;
...@@ -57,6 +57,9 @@ class Connection implements ServerInfoAwareConnection ...@@ -57,6 +57,9 @@ class Connection implements ServerInfoAwareConnection
return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
} }
/**
* @return Statement
*/
public function prepare(string $sql): StatementInterface public function prepare(string $sql): StatementInterface
{ {
try { try {
......
...@@ -14,7 +14,7 @@ use PDOStatement; ...@@ -14,7 +14,7 @@ use PDOStatement;
use function array_slice; use function array_slice;
use function func_get_args; use function func_get_args;
class Statement implements StatementInterface final class Statement implements StatementInterface
{ {
private const PARAM_TYPE_MAP = [ private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL, ParameterType::NULL => PDO::PARAM_NULL,
......
...@@ -2,27 +2,66 @@ ...@@ -2,27 +2,66 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv; namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\PDO\Connection as BaseConnection; use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
use Doctrine\DBAL\Driver\PDO\Statement as BaseStatement; use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use PDOStatement; use PDO;
use function is_string; use function is_string;
use function strpos; use function strpos;
use function substr; use function substr;
/** final class Connection implements ServerInfoAwareConnection
* Sqlsrv Connection implementation.
*/
class Connection extends BaseConnection
{ {
/** @var PDOConnection */
private $connection;
public function __construct(PDOConnection $connection)
{
$this->connection = $connection;
}
public function prepare(string $sql): StatementInterface
{
return new Statement(
$this->connection->prepare($sql)
);
}
public function query(string $sql): Result
{
return $this->connection->query($sql);
}
/**
* {@inheritDoc}
*/
public function quote($value, $type = ParameterType::STRING)
{
$val = $this->connection->quote($value, $type);
// Fix for a driver version terminating all values with null byte
if (is_string($val) && strpos($val, "\0") !== false) {
$val = substr($val, 0, -1);
}
return $val;
}
public function exec(string $statement): int
{
return $this->connection->exec($statement);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function lastInsertId($name = null) public function lastInsertId($name = null)
{ {
if ($name === null) { if ($name === null) {
return parent::lastInsertId($name); return $this->connection->lastInsertId($name);
} }
return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
...@@ -33,20 +72,37 @@ class Connection extends BaseConnection ...@@ -33,20 +72,37 @@ class Connection extends BaseConnection
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function quote($value, $type = ParameterType::STRING) public function beginTransaction()
{ {
$val = parent::quote($value, $type); return $this->connection->beginTransaction();
}
// Fix for a driver version terminating all values with null byte /**
if (is_string($val) && strpos($val, "\0") !== false) { * {@inheritDoc}
$val = substr($val, 0, -1); */
public function commit()
{
return $this->connection->commit();
} }
return $val; /**
* {@inheritDoc}
*/
public function rollBack()
{
return $this->connection->rollBack();
}
/**
* {@inheritDoc}
*/
public function getServerVersion()
{
return $this->connection->getServerVersion();
} }
protected function createStatement(PDOStatement $stmt): BaseStatement public function getWrappedConnection(): PDO
{ {
return new Statement($stmt); return $this->connection->getWrappedConnection();
} }
} }
...@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Driver\PDOSqlsrv; ...@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver; use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost; use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
use Doctrine\DBAL\Driver\Exception; use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
use PDO; use PDO;
use function is_int; use function is_int;
...@@ -37,10 +38,12 @@ class Driver extends AbstractSQLServerDriver ...@@ -37,10 +38,12 @@ class Driver extends AbstractSQLServerDriver
} }
return new Connection( return new Connection(
new PDOConnection(
$this->_constructPdoDsn($params, $dsnOptions), $this->_constructPdoDsn($params, $dsnOptions),
$params['user'] ?? '', $params['user'] ?? '',
$params['password'] ?? '', $params['password'] ?? '',
$pdoOptions $pdoOptions
)
); );
} }
......
...@@ -2,17 +2,32 @@ ...@@ -2,17 +2,32 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv; namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\PDO\Statement as BaseStatement; use Doctrine\DBAL\Driver\PDO\Statement as PDOStatement;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use PDO; use PDO;
/** /**
* PDO SQL Server Statement * PDO SQL Server Statement
*/ */
class Statement extends BaseStatement final class Statement implements StatementInterface
{ {
/** @var PDOStatement */
private $statement;
/**
* @internal The statement can be only instantiated by its driver connection.
*/
public function __construct(PDOStatement $statement)
{
$this->statement = $statement;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @param mixed $driverOptions
*/ */
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
{ {
...@@ -23,7 +38,7 @@ class Statement extends BaseStatement ...@@ -23,7 +38,7 @@ class Statement extends BaseStatement
$driverOptions = PDO::SQLSRV_ENCODING_BINARY; $driverOptions = PDO::SQLSRV_ENCODING_BINARY;
} }
return parent::bindParam($column, $variable, $type, $length, $driverOptions); return $this->statement->bindParam($column, $variable, $type, $length, $driverOptions);
} }
/** /**
...@@ -33,4 +48,12 @@ class Statement extends BaseStatement ...@@ -33,4 +48,12 @@ class Statement extends BaseStatement
{ {
return $this->bindParam($param, $value, $type); return $this->bindParam($param, $value, $type);
} }
/**
* {@inheritdoc}
*/
public function execute($params = null): Result
{
return $this->statement->execute($params);
}
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Doctrine\DBAL\Tests\Functional\Driver\PDOSqlsrv; namespace Doctrine\DBAL\Tests\Functional\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver as DriverInterface; use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\PDO\Connection; use Doctrine\DBAL\Driver\PDOSqlsrv\Connection;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver; use Doctrine\DBAL\Driver\PDOSqlsrv\Driver;
use Doctrine\DBAL\Tests\Functional\Driver\AbstractDriverTest; use Doctrine\DBAL\Tests\Functional\Driver\AbstractDriverTest;
use Doctrine\DBAL\Tests\TestUtil; use Doctrine\DBAL\Tests\TestUtil;
......
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