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 # 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 ## Deprecated `FetchMode` and the corresponding methods
1. The `FetchMode` class and the `setFetchMode()` method of the `Connection` and `Statement` interfaces are deprecated. 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()`. 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 `fetchAllNumeric()`, `fetchAllAssociative()` and `fetchFirstColumn()`. 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 `fetchOne()`. 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. 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. 7. Fetching data in mixed mode (`FetchMode::MIXED`) is deprecated.
## Deprecated `Connection::project()` ## Deprecated `Connection::project()`
......
...@@ -2,16 +2,17 @@ ...@@ -2,16 +2,17 @@
declare(strict_types=1); declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility; namespace Doctrine\DBAL\Abstraction;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as BaseResultStatement; use Doctrine\DBAL\Driver\Result as DriverResult;
use Traversable; 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. * Returns an iterator over the result set rows represented as numeric arrays.
......
...@@ -4,9 +4,9 @@ namespace Doctrine\DBAL\Cache; ...@@ -4,9 +4,9 @@ namespace Doctrine\DBAL\Cache;
use ArrayIterator; use ArrayIterator;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -16,7 +16,10 @@ use function array_values; ...@@ -16,7 +16,10 @@ use function array_values;
use function count; use function count;
use function reset; use function reset;
class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompatibleResultStatement /**
* @deprecated
*/
class ArrayStatement implements IteratorAggregate, ResultStatement, Result
{ {
/** @var mixed[] */ /** @var mixed[] */
private $data; private $data;
...@@ -45,14 +48,24 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa ...@@ -45,14 +48,24 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
unset($this->data); $this->free();
return true; return true;
} }
/**
* {@inheritdoc}
*/
public function rowCount()
{
return count($this->data);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -210,6 +223,11 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa ...@@ -210,6 +223,11 @@ class ArrayStatement implements IteratorAggregate, ResultStatement, ForwardCompa
return FetchUtils::fetchFirstColumn($this); return FetchUtils::fetchFirstColumn($this);
} }
public function free(): void
{
$this->data = [];
}
/** /**
* @return mixed|false * @return mixed|false
*/ */
......
...@@ -6,10 +6,10 @@ use ArrayIterator; ...@@ -6,10 +6,10 @@ use ArrayIterator;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -32,8 +32,10 @@ use function reset; ...@@ -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. * 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. * 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 */ /** @var Cache */
private $resultCache; private $resultCache;
...@@ -72,12 +74,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -72,12 +74,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
$this->statement->closeCursor(); $this->free();
$this->data = null;
return true; return true;
} }
...@@ -234,7 +236,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -234,7 +236,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
*/ */
public function fetchAllNumeric(): array public function fetchAllNumeric(): array
{ {
if ($this->statement instanceof ForwardCompatibleResultStatement) { if ($this->statement instanceof Result) {
$data = $this->statement->fetchAllAssociative(); $data = $this->statement->fetchAllAssociative();
} else { } else {
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE); $data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
...@@ -250,7 +252,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -250,7 +252,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
*/ */
public function fetchAllAssociative(): array public function fetchAllAssociative(): array
{ {
if ($this->statement instanceof ForwardCompatibleResultStatement) { if ($this->statement instanceof Result) {
$data = $this->statement->fetchAllAssociative(); $data = $this->statement->fetchAllAssociative();
} else { } else {
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE); $data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
...@@ -287,6 +289,11 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -287,6 +289,11 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
return $this->statement->rowCount(); return $this->statement->rowCount();
} }
public function free(): void
{
$this->data = null;
}
/** /**
* @return array<string,mixed>|false * @return array<string,mixed>|false
* *
...@@ -298,7 +305,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar ...@@ -298,7 +305,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement, Forwar
$this->data = []; $this->data = [];
} }
if ($this->statement instanceof ForwardCompatibleResultStatement) { if ($this->statement instanceof Result) {
$row = $this->statement->fetchAssociative(); $row = $this->statement->fetchAssociative();
} else { } else {
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE); $row = $this->statement->fetch(FetchMode::ASSOCIATIVE);
......
...@@ -4,6 +4,7 @@ namespace Doctrine\DBAL; ...@@ -4,6 +4,7 @@ namespace Doctrine\DBAL;
use Closure; use Closure;
use Doctrine\Common\EventManager; use Doctrine\Common\EventManager;
use Doctrine\DBAL\Abstraction\Result;
use Doctrine\DBAL\Cache\ArrayStatement; use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\DBAL\Cache\CacheException; use Doctrine\DBAL\Cache\CacheException;
use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Cache\QueryCacheProfile;
...@@ -14,7 +15,6 @@ use Doctrine\DBAL\Driver\ResultStatement; ...@@ -14,7 +15,6 @@ use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\ForwardCompatibility\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder; use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Query\QueryBuilder;
...@@ -616,7 +616,7 @@ class Connection implements DriverConnection ...@@ -616,7 +616,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchAssociative(); return $stmt->fetchAssociative();
} }
...@@ -643,7 +643,7 @@ class Connection implements DriverConnection ...@@ -643,7 +643,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchNumeric(); return $stmt->fetchNumeric();
} }
...@@ -670,7 +670,7 @@ class Connection implements DriverConnection ...@@ -670,7 +670,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchOne(); return $stmt->fetchOne();
} }
...@@ -956,7 +956,7 @@ class Connection implements DriverConnection ...@@ -956,7 +956,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchAllNumeric(); return $stmt->fetchAllNumeric();
} }
...@@ -982,7 +982,7 @@ class Connection implements DriverConnection ...@@ -982,7 +982,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchAllAssociative(); return $stmt->fetchAllAssociative();
} }
...@@ -1008,7 +1008,7 @@ class Connection implements DriverConnection ...@@ -1008,7 +1008,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchFirstColumn(); return $stmt->fetchFirstColumn();
} }
...@@ -1034,7 +1034,7 @@ class Connection implements DriverConnection ...@@ -1034,7 +1034,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
yield from $stmt->iterateNumeric(); yield from $stmt->iterateNumeric();
} else { } else {
while (($row = $stmt->fetch(FetchMode::NUMERIC)) !== false) { while (($row = $stmt->fetch(FetchMode::NUMERIC)) !== false) {
...@@ -1062,7 +1062,7 @@ class Connection implements DriverConnection ...@@ -1062,7 +1062,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
yield from $stmt->iterateAssociative(); yield from $stmt->iterateAssociative();
} else { } else {
while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE)) !== false) { while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE)) !== false) {
...@@ -1090,7 +1090,7 @@ class Connection implements DriverConnection ...@@ -1090,7 +1090,7 @@ class Connection implements DriverConnection
try { try {
$stmt = $this->executeQuery($query, $params, $types); $stmt = $this->executeQuery($query, $params, $types);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
yield from $stmt->iterateColumn(); yield from $stmt->iterateColumn();
} else { } else {
while (($value = $stmt->fetch(FetchMode::COLUMN)) !== false) { while (($value = $stmt->fetch(FetchMode::COLUMN)) !== false) {
......
...@@ -4,8 +4,6 @@ declare(strict_types=1); ...@@ -4,8 +4,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver; namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement;
/** /**
* @internal * @internal
*/ */
...@@ -16,9 +14,9 @@ final class FetchUtils ...@@ -16,9 +14,9 @@ final class FetchUtils
* *
* @throws DriverException * @throws DriverException
*/ */
public static function fetchOne(ResultStatement $stmt) public static function fetchOne(Result $result)
{ {
$row = $stmt->fetchNumeric(); $row = $result->fetchNumeric();
if ($row === false) { if ($row === false) {
return false; return false;
...@@ -32,11 +30,11 @@ final class FetchUtils ...@@ -32,11 +30,11 @@ final class FetchUtils
* *
* @throws DriverException * @throws DriverException
*/ */
public static function fetchAllNumeric(ResultStatement $stmt): array public static function fetchAllNumeric(Result $result): array
{ {
$rows = []; $rows = [];
while (($row = $stmt->fetchNumeric()) !== false) { while (($row = $result->fetchNumeric()) !== false) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -48,11 +46,11 @@ final class FetchUtils ...@@ -48,11 +46,11 @@ final class FetchUtils
* *
* @throws DriverException * @throws DriverException
*/ */
public static function fetchAllAssociative(ResultStatement $stmt): array public static function fetchAllAssociative(Result $result): array
{ {
$rows = []; $rows = [];
while (($row = $stmt->fetchAssociative()) !== false) { while (($row = $result->fetchAssociative()) !== false) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -64,11 +62,11 @@ final class FetchUtils ...@@ -64,11 +62,11 @@ final class FetchUtils
* *
* @throws DriverException * @throws DriverException
*/ */
public static function fetchFirstColumn(ResultStatement $stmt): array public static function fetchFirstColumn(Result $result): array
{ {
$rows = []; $rows = [];
while (($row = $stmt->fetchOne()) !== false) { while (($row = $result->fetchOne()) !== false) {
$rows[] = $row; $rows[] = $row;
} }
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\IBMDB2; namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -50,7 +50,7 @@ use const DB2_LONG; ...@@ -50,7 +50,7 @@ use const DB2_LONG;
use const DB2_PARAM_FILE; use const DB2_PARAM_FILE;
use const DB2_PARAM_IN; use const DB2_PARAM_IN;
class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement class DB2Statement implements IteratorAggregate, Statement, Result
{ {
/** @var resource */ /** @var resource */
private $stmt; private $stmt;
...@@ -147,6 +147,8 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes ...@@ -147,6 +147,8 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
...@@ -426,6 +428,15 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes ...@@ -426,6 +428,15 @@ class DB2Statement implements IteratorAggregate, Statement, ForwardCompatibleRes
return @db2_num_rows($this->stmt) ? : 0; 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. * Casts a stdClass object to the given class name mapping its' properties.
* *
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
namespace Doctrine\DBAL\Driver\Mysqli; namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use mysqli; use mysqli;
...@@ -27,7 +27,7 @@ use function is_resource; ...@@ -27,7 +27,7 @@ use function is_resource;
use function sprintf; use function sprintf;
use function str_repeat; use function str_repeat;
class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement class MysqliStatement implements IteratorAggregate, Statement, Result
{ {
/** @var string[] */ /** @var string[] */
protected static $_paramTypeMap = [ protected static $_paramTypeMap = [
...@@ -498,11 +498,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -498,11 +498,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
$this->_stmt->free_result(); $this->free();
$this->result = false;
return true; return true;
} }
...@@ -527,6 +528,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -527,6 +528,12 @@ class MysqliStatement implements IteratorAggregate, Statement, ForwardCompatible
return $this->_stmt->field_count; return $this->_stmt->field_count;
} }
public function free(): void
{
$this->_stmt->free_result();
$this->result = false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\OCI8; namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
...@@ -51,7 +51,7 @@ use const SQLT_CHR; ...@@ -51,7 +51,7 @@ use const SQLT_CHR;
/** /**
* The OCI8 implementation of the Statement interface. * The OCI8 implementation of the Statement interface.
*/ */
class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement class OCI8Statement implements IteratorAggregate, Statement, Result
{ {
/** @var resource */ /** @var resource */
protected $_dbh; protected $_dbh;
...@@ -331,17 +331,12 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe ...@@ -331,17 +331,12 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
// not having the result means there's nothing to close $this->free();
if (! $this->result) {
return true;
}
oci_cancel($this->_sth);
$this->result = false;
return true; return true;
} }
...@@ -601,6 +596,18 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe ...@@ -601,6 +596,18 @@ class OCI8Statement implements IteratorAggregate, Statement, ForwardCompatibleRe
return $this->doFetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0]; 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 * @return mixed|false
*/ */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv; namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\PDOConnection; use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement; use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use PDO; use PDO;
...@@ -36,7 +36,7 @@ class Connection extends PDOConnection ...@@ -36,7 +36,7 @@ class Connection extends PDOConnection
$stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?'); $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
$stmt->execute([$name]); $stmt->execute([$name]);
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchOne(); return $stmt->fetchOne();
} }
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
namespace Doctrine\DBAL\Driver; namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use PDO; use PDO;
...@@ -20,7 +19,7 @@ use const E_USER_DEPRECATED; ...@@ -20,7 +19,7 @@ use const E_USER_DEPRECATED;
* The PDO implementation of the Statement interface. * The PDO implementation of the Statement interface.
* Used by all PDO-based drivers. * 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 = [ private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL, ParameterType::NULL => PDO::PARAM_NULL,
...@@ -111,6 +110,8 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible ...@@ -111,6 +110,8 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
...@@ -250,6 +251,11 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible ...@@ -250,6 +251,11 @@ class PDOStatement extends \PDOStatement implements Statement, ForwardCompatible
return $this->fetchAll(PDO::FETCH_COLUMN); return $this->fetchAll(PDO::FETCH_COLUMN);
} }
public function free(): void
{
parent::closeCursor();
}
/** /**
* Converts DBAL parameter type to PDO parameter type * Converts DBAL parameter type to PDO parameter type
* *
......
...@@ -2,18 +2,15 @@ ...@@ -2,18 +2,15 @@
declare(strict_types=1); declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility\Driver; namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\ResultStatement as BaseResultStatement;
/** /**
* 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 * @return array<int,mixed>|false
* *
...@@ -22,7 +19,7 @@ interface ResultStatement extends BaseResultStatement ...@@ -22,7 +19,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchNumeric(); 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 * @return array<string,mixed>|false
* *
...@@ -31,7 +28,7 @@ interface ResultStatement extends BaseResultStatement ...@@ -31,7 +28,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchAssociative(); 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 * @return mixed|false
* *
...@@ -40,7 +37,7 @@ interface ResultStatement extends BaseResultStatement ...@@ -40,7 +37,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchOne(); 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>> * @return array<int,array<int,mixed>>
* *
...@@ -49,7 +46,7 @@ interface ResultStatement extends BaseResultStatement ...@@ -49,7 +46,7 @@ interface ResultStatement extends BaseResultStatement
public function fetchAllNumeric(): array; 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>> * @return array<int,array<string,mixed>>
* *
...@@ -58,11 +55,35 @@ interface ResultStatement extends BaseResultStatement ...@@ -58,11 +55,35 @@ interface ResultStatement extends BaseResultStatement
public function fetchAllAssociative(): array; 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> * @return array<int,mixed>
* *
* @throws DriverException * @throws DriverException
*/ */
public function fetchFirstColumn(): array; 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 ...@@ -13,6 +13,8 @@ interface ResultStatement extends Traversable
/** /**
* Closes the cursor, enabling the statement to be executed again. * Closes the cursor, enabling the statement to be executed again.
* *
* @deprecated Use Result::free() instead.
*
* @return bool TRUE on success or FALSE on failure. * @return bool TRUE on success or FALSE on failure.
*/ */
public function closeCursor(); public function closeCursor();
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Driver\SQLAnywhere; namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use function assert; use function assert;
...@@ -129,7 +129,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection ...@@ -129,7 +129,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
{ {
$stmt = $this->query("SELECT PROPERTY('ProductVersion')"); $stmt = $this->query("SELECT PROPERTY('ProductVersion')");
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
$version = $stmt->fetchOne(); $version = $stmt->fetchOne();
} else { } else {
$version = $stmt->fetchColumn(); $version = $stmt->fetchColumn();
...@@ -151,7 +151,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection ...@@ -151,7 +151,7 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
$stmt = $this->query('SELECT ' . $name . '.CURRVAL'); $stmt = $this->query('SELECT ' . $name . '.CURRVAL');
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchOne(); return $stmt->fetchOne();
} }
......
...@@ -4,10 +4,10 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere; ...@@ -4,10 +4,10 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -44,7 +44,7 @@ use const SASQL_BOTH; ...@@ -44,7 +44,7 @@ use const SASQL_BOTH;
/** /**
* SAP SQL Anywhere implementation of the Statement interface. * 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. */ /** @var resource The connection resource. */
private $conn; private $conn;
...@@ -136,6 +136,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa ...@@ -136,6 +136,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
* @deprecated Use free() instead.
*
* @throws SQLAnywhereException * @throws SQLAnywhereException
*/ */
public function closeCursor() public function closeCursor()
...@@ -388,6 +390,11 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa ...@@ -388,6 +390,11 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement, ForwardCompa
return sasql_stmt_affected_rows($this->stmt); return sasql_stmt_affected_rows($this->stmt);
} }
public function free(): void
{
sasql_stmt_reset($this->stmt);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Driver\SQLSrv; namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use function func_get_args; use function func_get_args;
...@@ -144,7 +144,7 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection ...@@ -144,7 +144,7 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection
$stmt = $this->query('SELECT @@IDENTITY'); $stmt = $this->query('SELECT @@IDENTITY');
} }
if ($stmt instanceof ForwardCompatibleResultStatement) { if ($stmt instanceof Result) {
return $stmt->fetchOne(); return $stmt->fetchOne();
} }
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
namespace Doctrine\DBAL\Driver\SQLSrv; namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\FetchUtils; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -42,7 +42,7 @@ use const SQLSRV_PARAM_IN; ...@@ -42,7 +42,7 @@ use const SQLSRV_PARAM_IN;
/** /**
* SQL Server Statement. * SQL Server Statement.
*/ */
class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatibleResultStatement class SQLSrvStatement implements IteratorAggregate, Statement, Result
{ {
/** /**
* The SQLSRV Resource. * The SQLSRV Resource.
...@@ -186,22 +186,12 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -186,22 +186,12 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
// not having the result means there's nothing to close $this->free();
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;
return true; return true;
} }
...@@ -498,6 +488,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible ...@@ -498,6 +488,23 @@ class SQLSrvStatement implements IteratorAggregate, Statement, ForwardCompatible
return sqlsrv_rows_affected($this->stmt) ?: 0; 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 * @return mixed|false
*/ */
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
namespace Doctrine\DBAL\Portability; namespace Doctrine\DBAL\Portability;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use PDO; use PDO;
...@@ -19,7 +19,7 @@ use function rtrim; ...@@ -19,7 +19,7 @@ use function rtrim;
/** /**
* Portability wrapper for a Statement. * Portability wrapper for a Statement.
*/ */
class Statement implements IteratorAggregate, DriverStatement, ForwardCompatibleResultStatement class Statement implements IteratorAggregate, DriverStatement, Result
{ {
/** @var int */ /** @var int */
private $portability; private $portability;
...@@ -67,6 +67,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -67,6 +67,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated Use free() instead.
*/ */
public function closeCursor() public function closeCursor()
{ {
...@@ -185,7 +187,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -185,7 +187,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchNumeric() public function fetchNumeric()
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$row = $this->stmt->fetchNumeric(); $row = $this->stmt->fetchNumeric();
} else { } else {
$row = $this->stmt->fetch(FetchMode::NUMERIC); $row = $this->stmt->fetch(FetchMode::NUMERIC);
...@@ -199,7 +201,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -199,7 +201,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchAssociative() public function fetchAssociative()
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$row = $this->stmt->fetchAssociative(); $row = $this->stmt->fetchAssociative();
} else { } else {
$row = $this->stmt->fetch(FetchMode::ASSOCIATIVE); $row = $this->stmt->fetch(FetchMode::ASSOCIATIVE);
...@@ -213,7 +215,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -213,7 +215,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchOne() public function fetchOne()
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$value = $this->stmt->fetchOne(); $value = $this->stmt->fetchOne();
} else { } else {
$value = $this->stmt->fetch(FetchMode::COLUMN); $value = $this->stmt->fetch(FetchMode::COLUMN);
...@@ -233,7 +235,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -233,7 +235,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchAllNumeric(): array public function fetchAllNumeric(): array
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchAllNumeric(); $data = $this->stmt->fetchAllNumeric();
} else { } else {
$data = $this->stmt->fetchAll(FetchMode::NUMERIC); $data = $this->stmt->fetchAll(FetchMode::NUMERIC);
...@@ -247,7 +249,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -247,7 +249,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchAllAssociative(): array public function fetchAllAssociative(): array
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchAllAssociative(); $data = $this->stmt->fetchAllAssociative();
} else { } else {
$data = $this->stmt->fetchAll(FetchMode::ASSOCIATIVE); $data = $this->stmt->fetchAll(FetchMode::ASSOCIATIVE);
...@@ -261,7 +263,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -261,7 +263,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
*/ */
public function fetchFirstColumn(): array public function fetchFirstColumn(): array
{ {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
$data = $this->stmt->fetchFirstColumn(); $data = $this->stmt->fetchFirstColumn();
} else { } else {
$data = $this->stmt->fetchAll(FetchMode::COLUMN); $data = $this->stmt->fetchAll(FetchMode::COLUMN);
...@@ -270,6 +272,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -270,6 +272,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
return $this->fixResultSet($data, true, false); 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 * @param mixed $result
* *
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
namespace Doctrine\DBAL; namespace Doctrine\DBAL;
use Doctrine\DBAL\Abstraction\Result;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ForwardCompatibility\ResultStatement as ForwardCompatibleResultStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use IteratorAggregate; use IteratorAggregate;
...@@ -19,7 +19,7 @@ use function is_string; ...@@ -19,7 +19,7 @@ use function is_string;
* A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support * A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support
* for logging, DBAL mapping types, etc. * for logging, DBAL mapping types, etc.
*/ */
class Statement implements IteratorAggregate, DriverStatement, ForwardCompatibleResultStatement class Statement implements IteratorAggregate, DriverStatement, Result
{ {
/** /**
* The SQL statement. * The SQL statement.
...@@ -182,6 +182,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -182,6 +182,8 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
/** /**
* Closes the cursor, freeing the database resources used by this statement. * Closes the cursor, freeing the database resources used by this statement.
* *
* @deprecated Use Result::free() instead.
*
* @return bool TRUE on success, FALSE on failure. * @return bool TRUE on success, FALSE on failure.
*/ */
public function closeCursor() public function closeCursor()
...@@ -289,7 +291,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -289,7 +291,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchNumeric() public function fetchNumeric()
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchNumeric(); return $this->stmt->fetchNumeric();
} }
...@@ -307,7 +309,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -307,7 +309,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAssociative() public function fetchAssociative()
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchAssociative(); return $this->stmt->fetchAssociative();
} }
...@@ -325,7 +327,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -325,7 +327,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchOne() public function fetchOne()
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchOne(); return $this->stmt->fetchOne();
} }
...@@ -343,7 +345,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -343,7 +345,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAllNumeric(): array public function fetchAllNumeric(): array
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchAllNumeric(); return $this->stmt->fetchAllNumeric();
} }
...@@ -361,7 +363,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -361,7 +363,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchAllAssociative(): array public function fetchAllAssociative(): array
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchAllAssociative(); return $this->stmt->fetchAllAssociative();
} }
...@@ -379,7 +381,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -379,7 +381,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function fetchFirstColumn(): array public function fetchFirstColumn(): array
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
return $this->stmt->fetchFirstColumn(); return $this->stmt->fetchFirstColumn();
} }
...@@ -399,7 +401,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -399,7 +401,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateNumeric(): Traversable public function iterateNumeric(): Traversable
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
while (($row = $this->stmt->fetchNumeric()) !== false) { while (($row = $this->stmt->fetchNumeric()) !== false) {
yield $row; yield $row;
} }
...@@ -423,7 +425,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -423,7 +425,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateAssociative(): Traversable public function iterateAssociative(): Traversable
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
while (($row = $this->stmt->fetchAssociative()) !== false) { while (($row = $this->stmt->fetchAssociative()) !== false) {
yield $row; yield $row;
} }
...@@ -447,7 +449,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -447,7 +449,7 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
public function iterateColumn(): Traversable public function iterateColumn(): Traversable
{ {
try { try {
if ($this->stmt instanceof ForwardCompatibleResultStatement) { if ($this->stmt instanceof Result) {
while (($value = $this->stmt->fetchOne()) !== false) { while (($value = $this->stmt->fetchOne()) !== false) {
yield $value; yield $value;
} }
...@@ -471,6 +473,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible ...@@ -471,6 +473,17 @@ class Statement implements IteratorAggregate, DriverStatement, ForwardCompatible
return $this->stmt->rowCount(); 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. * 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