Unverified Commit 3cfb57d4 authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #4049 from morozov/result

Replace forward-compatible ResultStatement interfaces with Result
parents 11e8ed4e e7c7cb17
# Upgrade to 2.11
## Deprecated `ArrayStatement` and `ResultCacheStatement` classes.
The `ArrayStatement` and `ResultCacheStatement` classes are deprecated. In a future major release they will be renamed and marked internal as implementation details of the caching layer.
## Deprecated `ResultStatement` interface
1. The `ResultStatement` interface is deprecated. Use the `Driver\Result` and `Abstraction\Result` interfaces instead.
2. `ResultStatement::closeCursor()` is deprecated in favor of `Result::free()`.
## Deprecated `FetchMode` and the corresponding methods
1. The `FetchMode` class and the `setFetchMode()` method of the `Connection` and `Statement` interfaces are deprecated.
2. The `Statement::fetch()` method is deprecated in favor of `fetchNumeric()`, `fetchAssociative()` and `fetchOne()`.
3. The `Statement::fetchAll()` method is deprecated in favor of `fetchAllNumeric()`, `fetchAllAssociative()` and `fetchFirstColumn()`.
4. The `Statement::fetchColumn()` method is deprecated in favor of `fetchOne()`.
2. The `Statement::fetch()` method is deprecated in favor of `Result::fetchNumeric()`, `::fetchAssociative()` and `::fetchOne()`.
3. The `Statement::fetchAll()` method is deprecated in favor of `Result::fetchAllNumeric()`, `::fetchAllAssociative()` and `::fetchFirstColumn()`.
4. The `Statement::fetchColumn()` method is deprecated in favor of `Result::fetchOne()`.
5. The `Connection::fetchArray()` and `fetchAssoc()` method are deprecated in favor of `fetchNumeric()` and `fetchAssociative()` respectively.
6. The `StatementIterator` class and the usage of a `Statement` object as `Traversable` is deprecated in favor of `iterateNumeric()`, `iterateAssociative()` and `iterateColumn()`.
6. The `StatementIterator` class and the usage of a `Statement` object as `Traversable` is deprecated in favor of `Result::iterateNumeric()`, `::iterateAssociative()` and `::iterateColumn()`.
7. Fetching data in mixed mode (`FetchMode::MIXED`) is deprecated.
## Deprecated `Connection::project()`
......
......@@ -2,16 +2,17 @@
declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility;
namespace Doctrine\DBAL\Abstraction;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as BaseResultStatement;
use Doctrine\DBAL\Driver\Result as DriverResult;
use Traversable;
/**
* Forward compatibility extension for the DBAL ResultStatement interface.
* Abstraction-level result statement execution result. Provides additional methods on top
* of the driver-level interface.
*/
interface ResultStatement extends BaseResultStatement
interface Result extends DriverResult
{
/**
* Returns an iterator over the result set rows represented as numeric arrays.
......
......@@ -4,9 +4,9 @@ namespace Doctrine\DBAL\Cache;
use ArrayIterator;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use InvalidArgumentException;
use IteratorAggregate;
use PDO;
......@@ -16,7 +16,10 @@ use function array_values;
use function count;
use function reset;
class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompatibleResultStatement
/**
* @deprecated
*/
class ArrayStatement implements IteratorAggregate, ResultStatement, Result
{
/** @var mixed[] */
private $data;
......@@ -45,14 +48,24 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
unset($this->data);
$this->free();
return true;
}
/**
* {@inheritdoc}
*/
public function rowCount()
{
return count($this->data);
}
/**
* {@inheritdoc}
*/
......@@ -210,6 +223,11 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa
return FetchUtils::fetchFirstColumn($this);
}
public function free(): void
{
$this->data = [];
}
/**
* @return mixed|false
*/
......
......@@ -6,10 +6,10 @@ use ArrayIterator;
use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use InvalidArgumentException;
use IteratorAggregate;
use PDO;
......@@ -32,8 +32,10 @@ use function reset;
*
* Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
* This means that the memory usage for cached results might increase by using this feature.
*
* @deprecated
*/
class ResultCacheStatement implements IteratorAggregate, ResultStatement, ForwardCompatibleResultStatement
class ResultCacheStatement implements IteratorAggregate, ResultStatement, Result
{
/** @var Cache */
private $resultCache;
......@@ -72,12 +74,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
$this->statement->closeCursor();
$this->data = null;
$this->free();
return true;
}
......@@ -234,7 +236,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
*/
public function fetchAllNumeric(): array
{
if ($this->statement instanceof ForwardCompatibleResultStatement) {
if ($this->statement instanceof Result) {
$data = $this->statement->fetchAllAssociative();
} else {
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
......@@ -250,7 +252,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
*/
public function fetchAllAssociative(): array
{
if ($this->statement instanceof ForwardCompatibleResultStatement) {
if ($this->statement instanceof Result) {
$data = $this->statement->fetchAllAssociative();
} else {
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
......@@ -287,6 +289,11 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
return $this->statement->rowCount();
}
public function free(): void
{
$this->data = null;
}
/**
* @return array<string,mixed>|false
*
......@@ -298,7 +305,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
$this->data = [];
}
if ($this->statement instanceof ForwardCompatibleResultStatement) {
if ($this->statement instanceof Result) {
$row = $this->statement->fetchAssociative();
} else {
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);
......
......@@ -4,6 +4,7 @@ namespace Doctrine\DBAL;
use Closure;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Abstraction\Result;
use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\DBAL\Cache\CacheException;
use Doctrine\DBAL\Cache\QueryCacheProfile;
......@@ -14,7 +15,6 @@ use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\ForwardCompatibility\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder;
......@@ -616,7 +616,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchAssociative();
}
......@@ -643,7 +643,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchNumeric();
}
......@@ -670,7 +670,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchOne();
}
......@@ -956,7 +956,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchAllNumeric();
}
......@@ -982,7 +982,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchAllAssociative();
}
......@@ -1008,7 +1008,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchFirstColumn();
}
......@@ -1034,7 +1034,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
yield from $stmt->iterateNumeric();
} else {
while (($row = $stmt->fetch(FetchMode::NUMERIC)) !== false) {
......@@ -1062,7 +1062,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
yield from $stmt->iterateAssociative();
} else {
while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE)) !== false) {
......@@ -1090,7 +1090,7 @@ class Connection implements DriverConnection
try {
$stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
yield from $stmt->iterateColumn();
} else {
while (($value = $stmt->fetch(FetchMode::COLUMN)) !== false) {
......
......@@ -4,8 +4,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement;
/**
* @internal
*/
......@@ -16,9 +14,9 @@ final class FetchUtils
*
* @throws DriverException
*/
public static function fetchOne(ResultStatement $stmt)
public static function fetchOne(Result $result)
{
$row = $stmt->fetchNumeric();
$row = $result->fetchNumeric();
if ($row === false) {
return false;
......@@ -32,11 +30,11 @@ final class FetchUtils
*
* @throws DriverException
*/
public static function fetchAllNumeric(ResultStatement $stmt): array
public static function fetchAllNumeric(Result $result): array
{
$rows = [];
while (($row = $stmt->fetchNumeric()) !== false) {
while (($row = $result->fetchNumeric()) !== false) {
$rows[] = $row;
}
......@@ -48,11 +46,11 @@ final class FetchUtils
*
* @throws DriverException
*/
public static function fetchAllAssociative(ResultStatement $stmt): array
public static function fetchAllAssociative(Result $result): array
{
$rows = [];
while (($row = $stmt->fetchAssociative()) !== false) {
while (($row = $result->fetchAssociative()) !== false) {
$rows[] = $row;
}
......@@ -64,11 +62,11 @@ final class FetchUtils
*
* @throws DriverException
*/
public static function fetchFirstColumn(ResultStatement $stmt): array
public static function fetchFirstColumn(Result $result): array
{
$rows = [];
while (($row = $stmt->fetchOne()) !== false) {
while (($row = $result->fetchOne()) !== false) {
$rows[] = $row;
}
......
......@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use PDO;
......@@ -50,7 +50,7 @@ use const DB2_LONG;
use const DB2_PARAM_FILE;
use const DB2_PARAM_IN;
class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement
class DB2Statement implements IteratorAggregate, Statement, Result
{
/** @var resource */
private $stmt;
......@@ -147,6 +147,8 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
......@@ -426,6 +428,15 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes
return @db2_num_rows($this->stmt) ? : 0;
}
public function free(): void
{
$this->bindParam = [];
db2_free_result($this->stmt);
$this->result = false;
}
/**
* Casts a stdClass object to the given class name mapping its' properties.
*
......
......@@ -3,11 +3,11 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use mysqli;
......@@ -27,7 +27,7 @@ use function is_resource;
use function sprintf;
use function str_repeat;
class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement
class MysqliStatement implements IteratorAggregate, Statement, Result
{
/** @var string[] */
protected static $_paramTypeMap = [
......@@ -498,11 +498,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
$this->_stmt->free_result();
$this->result = false;
$this->free();
return true;
}
......@@ -527,6 +528,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible
return $this->_stmt->field_count;
}
public function free(): void
{
$this->_stmt->free_result();
$this->result = false;
}
/**
* {@inheritdoc}
*
......
......@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use InvalidArgumentException;
use IteratorAggregate;
......@@ -51,7 +51,7 @@ use const SQLT_CHR;
/**
* The OCI8 implementation of the Statement interface.
*/
class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement
class OCI8Statement implements IteratorAggregate, Statement, Result
{
/** @var resource */
protected $_dbh;
......@@ -331,17 +331,12 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
// not having the result means there's nothing to close
if (! $this->result) {
return true;
}
oci_cancel($this->_sth);
$this->result = false;
$this->free();
return true;
}
......@@ -601,6 +596,18 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe
return $this->doFetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0];
}
public function free(): void
{
// not having the result means there's nothing to close
if (! $this->result) {
return;
}
oci_cancel($this->_sth);
$this->result = false;
}
/**
* @return mixed|false
*/
......
......@@ -3,7 +3,7 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\ParameterType;
use PDO;
......@@ -36,7 +36,7 @@ class Connection extends PDOConnection
$stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
$stmt->execute([$name]);
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchOne();
}
......
......@@ -3,7 +3,6 @@
namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use PDO;
......@@ -20,7 +19,7 @@ use const E_USER_DEPRECATED;
* The PDO implementation of the Statement interface.
* Used by all PDO-based drivers.
*/
class PDOStatement extends \PDOStatement implements Statement, ForwardCompatibleResultStatement
class PDOStatement extends \PDOStatement implements Statement, Result
{
private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL,
......@@ -111,6 +110,8 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
......@@ -250,6 +251,11 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible
return $this->fetchAll(PDO::FETCH_COLUMN);
}
public function free(): void
{
parent::closeCursor();
}
/**
* Converts DBAL parameter type to PDO parameter type
*
......
......@@ -2,18 +2,15 @@
declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility\Driver;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\ResultStatement as BaseResultStatement;
namespace Doctrine\DBAL\Driver;
/**
* Forward compatibility extension for the ResultStatement interface.
* Driver-level result statement execution result.
*/
interface ResultStatement extends BaseResultStatement
interface Result
{
/**
* Returns the next row of a result set as a numeric array or FALSE if there are no more rows.
* Returns the next row of the result as a numeric array or FALSE if there are no more rows.
*
* @return array<int,mixed>|false
*
......@@ -22,7 +19,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchNumeric();
/**
* Returns the next row of a result set as an associative array or FALSE if there are no more rows.
* Returns the next row of the result as an associative array or FALSE if there are no more rows.
*
* @return array<string,mixed>|false
*
......@@ -31,7 +28,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchAssociative();
/**
* Returns the first value of the next row of a result set or FALSE if there are no more rows.
* Returns the first value of the next row of the result or FALSE if there are no more rows.
*
* @return mixed|false
*
......@@ -40,7 +37,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchOne();
/**
* Returns an array containing all of the result set rows represented as numeric arrays.
* Returns an array containing all of the result rows represented as numeric arrays.
*
* @return array<int,array<int,mixed>>
*
......@@ -49,7 +46,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchAllNumeric(): array;
/**
* Returns an array containing all of the result set rows represented as associative arrays.
* Returns an array containing all of the result rows represented as associative arrays.
*
* @return array<int,array<string,mixed>>
*
......@@ -58,11 +55,35 @@ interface ResultStatement extends BaseResultStatement
public function fetchAllAssociative(): array;
/**
* Returns an array containing the values of the first column of the result set.
* Returns an array containing the values of the first column of the result.
*
* @return array<int,mixed>
*
* @throws DriverException
*/
public function fetchFirstColumn(): array;
/**
* Returns the number of rows affected by the DELETE, INSERT, or UPDATE statement that produced the result.
*
* If the statement executed a SELECT query or a similar platform-specific SQL (e.g. DESCRIBE, SHOW, etc.),
* some database drivers may return the number of rows returned by that query. However, this behaviour
* is not guaranteed for all drivers and should not be relied on in portable applications.
*
* @return int The number of rows.
*/
public function rowCount();
/**
* Returns the number of columns in the result
*
* @return int The number of columns in the result. If the columns cannot be counted,
* this method must return 0.
*/
public function columnCount();
/**
* Discards the non-fetched portion of the result, enabling the originating statement to be executed again.
*/
public function free(): void;
}
......@@ -13,6 +13,8 @@ interface ResultStatement extends Traversable
/**
* Closes the cursor, enabling the statement to be executed again.
*
* @deprecated Use Result::free() instead.
*
* @return bool TRUE on success or FALSE on failure.
*/
public function closeCursor();
......
......@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use function assert;
......@@ -129,7 +129,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
{
$stmt = $this->query("SELECT PROPERTY('ProductVersion')");
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
$version = $stmt->fetchOne();
} else {
$version = $stmt->fetchColumn();
......@@ -151,7 +151,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
$stmt = $this->query('SELECT ' . $name . '.CURRVAL');
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchOne();
}
......
......@@ -4,10 +4,10 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use PDO;
......@@ -44,7 +44,7 @@ use const SASQL_BOTH;
/**
* SAP SQL Anywhere implementation of the Statement interface.
*/
class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement
class SQLAnywhereStatement implements IteratorAggregate, Statement, Result
{
/** @var resource The connection resource. */
private $conn;
......@@ -136,6 +136,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*
* @throws SQLAnywhereException
*/
public function closeCursor()
......@@ -388,6 +390,11 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa
return sasql_stmt_affected_rows($this->stmt);
}
public function free(): void
{
sasql_stmt_reset($this->stmt);
}
/**
* {@inheritdoc}
*
......
......@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use function func_get_args;
......@@ -144,7 +144,7 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection
$stmt = $this->query('SELECT @@IDENTITY');
}
if ($stmt instanceof ForwardCompatibleResultStatement) {
if ($stmt instanceof Result) {
return $stmt->fetchOne();
}
......
......@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use PDO;
......@@ -42,7 +42,7 @@ use const SQLSRV_PARAM_IN;
/**
* SQL Server Statement.
*/
class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement
class SQLSrvStatement implements IteratorAggregate, Statement, Result
{
/**
* The SQLSRV Resource.
......@@ -186,22 +186,12 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
// not having the result means there's nothing to close
if ($this->stmt === null || ! $this->result) {
return true;
}
// emulate it by fetching and discarding rows, similarly to what PDO does in this case
// @link http://php.net/manual/en/pdostatement.closecursor.php
// @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075
// deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them
while (sqlsrv_fetch($this->stmt)) {
}
$this->result = false;
$this->free();
return true;
}
......@@ -498,6 +488,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible
return sqlsrv_rows_affected($this->stmt) ?: 0;
}
public function free(): void
{
// not having the result means there's nothing to close
if ($this->stmt === null || ! $this->result) {
return;
}
// emulate it by fetching and discarding rows, similarly to what PDO does in this case
// @link http://php.net/manual/en/pdostatement.closecursor.php
// @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075
// deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them
while (sqlsrv_fetch($this->stmt)) {
}
$this->result = false;
}
/**
* @return mixed|false
*/
......
......@@ -2,11 +2,11 @@
namespace Doctrine\DBAL\Portability;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use PDO;
......@@ -19,7 +19,7 @@ use function rtrim;
/**
* Portability wrapper for a Statement.
*/
class Statement implements IteratorAggregate, DriverStatement, ForwardCompatibleResultStatement
class Statement implements IteratorAggregate, DriverStatement, Result
{
/** @var int */
private $portability;
......@@ -67,6 +67,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
/**
* {@inheritdoc}
*
* @deprecated Use free() instead.
*/
public function closeCursor()
{
......@@ -185,7 +187,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchNumeric()
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$row = $this->stmt->fetchNumeric();
} else {
$row = $this->stmt->fetch(FetchMode::NUMERIC);
......@@ -199,7 +201,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchAssociative()
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$row = $this->stmt->fetchAssociative();
} else {
$row = $this->stmt->fetch(FetchMode::ASSOCIATIVE);
......@@ -213,7 +215,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchOne()
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$value = $this->stmt->fetchOne();
} else {
$value = $this->stmt->fetch(FetchMode::COLUMN);
......@@ -233,7 +235,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchAllNumeric(): array
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchAllNumeric();
} else {
$data = $this->stmt->fetchAll(FetchMode::NUMERIC);
......@@ -247,7 +249,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchAllAssociative(): array
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchAllAssociative();
} else {
$data = $this->stmt->fetchAll(FetchMode::ASSOCIATIVE);
......@@ -261,7 +263,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/
public function fetchFirstColumn(): array
{
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchFirstColumn();
} else {
$data = $this->stmt->fetchAll(FetchMode::COLUMN);
......@@ -270,6 +272,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
return $this->fixResultSet($data, true, false);
}
public function free(): void
{
if ($this->stmt instanceof Result) {
$this->stmt->free();
return;
}
$this->stmt->closeCursor();
}
/**
* @param mixed $result
*
......
......@@ -2,9 +2,9 @@
namespace Doctrine\DBAL;
use Doctrine\DBAL\Abstraction\Result;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ForwardCompatibility\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use IteratorAggregate;
......@@ -19,7 +19,7 @@ use function is_string;
* A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support
* for logging, DBAL mapping types, etc.
*/
class Statement implements IteratorAggregate, DriverStatement, ForwardCompatibleResultStatement
class Statement implements IteratorAggregate, DriverStatement, Result
{
/**
* The SQL statement.
......@@ -182,6 +182,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
/**
* Closes the cursor, freeing the database resources used by this statement.
*
* @deprecated Use Result::free() instead.
*
* @return bool TRUE on success, FALSE on failure.
*/
public function closeCursor()
......@@ -289,7 +291,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchNumeric()
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchNumeric();
}
......@@ -307,7 +309,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAssociative()
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchAssociative();
}
......@@ -325,7 +327,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchOne()
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchOne();
}
......@@ -343,7 +345,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAllNumeric(): array
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchAllNumeric();
}
......@@ -361,7 +363,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAllAssociative(): array
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchAllAssociative();
}
......@@ -379,7 +381,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchFirstColumn(): array
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
return $this->stmt->fetchFirstColumn();
}
......@@ -399,7 +401,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateNumeric(): Traversable
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
while (($row = $this->stmt->fetchNumeric()) !== false) {
yield $row;
}
......@@ -423,7 +425,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateAssociative(): Traversable
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
while (($row = $this->stmt->fetchAssociative()) !== false) {
yield $row;
}
......@@ -447,7 +449,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateColumn(): Traversable
{
try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) {
if ($this->stmt instanceof Result) {
while (($value = $this->stmt->fetchOne()) !== false) {
yield $value;
}
......@@ -471,6 +473,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
return $this->stmt->rowCount();
}
public function free(): void
{
if ($this->stmt instanceof Result) {
$this->stmt->free();
return;
}
$this->stmt->closeCursor();
}
/**
* Gets the wrapped driver statement.
*
......
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