Unverified Commit a7aa9760 authored by Sergei Morozov's avatar Sergei Morozov

Merge branch '3.0.x'

parents 0ac110cf 74eca6ba
...@@ -22,10 +22,6 @@ The `CompositeExpression` class is now immutable. ...@@ -22,10 +22,6 @@ The `CompositeExpression` class is now immutable.
The `OCI8Statement::convertPositionalToNamedPlaceholders()` method has been extracted to an internal utility class. The `OCI8Statement::convertPositionalToNamedPlaceholders()` method has been extracted to an internal utility class.
## BC BREAK: Dropped handling of one-based numeric arrays of parameters in `Statement::execute()`
The statement implementations no longer detect whether `$params` is a zero- or one-based array. A zero-based numeric array is expected.
## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed. ## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed.
The `ServerInfoAwareConnection::requiresQueryForServerVersion()` method has been removed as an implementation detail which is the same for almost all supported drivers. The `ServerInfoAwareConnection::requiresQueryForServerVersion()` method has been removed as an implementation detail which is the same for almost all supported drivers.
...@@ -97,7 +93,6 @@ Table columns are no longer indexed by column name. Use the `name` attribute of ...@@ -97,7 +93,6 @@ Table columns are no longer indexed by column name. Use the `name` attribute of
- The following methods have been removed as leaking internal implementation details: `::getHost()`, `::getPort()`, `::getUsername()`, `::getPassword()`. - The following methods have been removed as leaking internal implementation details: `::getHost()`, `::getPort()`, `::getUsername()`, `::getPassword()`.
- The `::getDatabase()` method can now return null which means that no database is currently selected. - The `::getDatabase()` method can now return null which means that no database is currently selected.
- The `::project()` method has been removed. Use `::executeQuery()` and fetch the data from the statement using one of the `Statement::fetch*()` methods instead.
## BC BREAK: Changes in `Doctrine\DBAL\Driver\SQLSrv\LastInsertId` ## BC BREAK: Changes in `Doctrine\DBAL\Driver\SQLSrv\LastInsertId`
...@@ -154,10 +149,6 @@ The `Doctrine\DBAL\Driver::getName()` has been removed. ...@@ -154,10 +149,6 @@ The `Doctrine\DBAL\Driver::getName()` has been removed.
`AbstractSchemaManager::extractDoctrineTypeFromComment()` made `protected`. It takes the comment by reference, removes the type annotation from it and returns the extracted Doctrine type. `AbstractSchemaManager::extractDoctrineTypeFromComment()` made `protected`. It takes the comment by reference, removes the type annotation from it and returns the extracted Doctrine type.
## BC BREAK `::errorCode()` and `::errorInfo()` removed from `Connection` and `Statement` APIs
The error information is available in `DriverException` trown in case of an error.
## BC BREAK Changes in driver exceptions ## BC BREAK Changes in driver exceptions
1. The `Doctrine\DBAL\Driver\DriverException::getErrorCode()` method is removed. In order to obtain the driver error code, please use `::getCode()`. 1. The `Doctrine\DBAL\Driver\DriverException::getErrorCode()` method is removed. In order to obtain the driver error code, please use `::getCode()`.
...@@ -269,6 +260,32 @@ The Doctrine\DBAL\Version class is no longer available: please refrain from chec ...@@ -269,6 +260,32 @@ The Doctrine\DBAL\Version class is no longer available: please refrain from chec
# Upgrade to 3.0 # Upgrade to 3.0
## BC BREAK `Statement::rowCount()` is moved.
`Statement::rowCount()` has been moved to the `ResultStatement` interface where it belongs by definition.
## Removed `FetchMode` and the corresponding methods
1. The `FetchMode` class and the `setFetchMode()` method of the `Connection` and `Statement` interfaces are removed.
2. The `Statement::fetch()` method is replaced with `fetchNumeric()`, `fetchAssociative()` and `fetchOne()`.
3. The `Statement::fetchAll()` method is replaced with `fetchAllNumeric()`, `fetchAllAssociative()` and `fechColumn()`.
4. The `Statement::fetchColumn()` method is replaced with `fetchOne()`.
5. The `Connection::fetchArray()` and `fetchAssoc()` methods are replaced with `fetchNumeric()` and `fetchAssociative()` respectively.
6. The `StatementIterator` class is removed. The usage of a `Statement` object as `Traversable` is no longer possible. Use `iterateNumeric()`, `iterateAssociative()` and `iterateColumn()` instead.
7. Fetching data in mixed mode (former `FetchMode::MIXED`) is no longer possible.
## BC BREAK: Dropped handling of one-based numeric arrays of parameters in `Statement::execute()`
The statement implementations no longer detect whether `$params` is a zero- or one-based array. A zero-based numeric array is expected.
## BC BREAK `Statement::project()` has been removed
- The `Statement::project()` method has been removed. Use `::executeQuery()` and fetch the data from the statement using one of the `Statement::fetch*()` methods instead.
## BC BREAK `::errorCode()` and `::errorInfo()` removed from `Connection` and `Statement` APIs
The error information is available in `DriverException` thrown in case of an error.
## BC BREAK: Dropped support for `FetchMode::CUSTOM_OBJECT` and `::STANDARD_OBJECT` ## BC BREAK: Dropped support for `FetchMode::CUSTOM_OBJECT` and `::STANDARD_OBJECT`
Instead of fetching an object, fetch an array and map it to an object of the desired class. Instead of fetching an object, fetch an array and map it to an object of the desired class.
...@@ -407,6 +424,16 @@ Please use other database client applications for import, e.g.: ...@@ -407,6 +424,16 @@ Please use other database client applications for import, e.g.:
# Upgrade to 2.11 # Upgrade to 2.11
## 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()` and `fetchAllAssociative()`. There is no currently replacement for `Statement::fetchAll(FETCH_MODE::COLUMN)`. In a future major version, `fetchColumn()` will be used as a replacement.
4. The `Statement::fetchColumn()` method is deprecated in favor of `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()`.
7. Fetching data in mixed mode (`FetchMode::MIXED`) is deprecated.
## Deprecated `Connection::project()` ## Deprecated `Connection::project()`
The `Connection::project()` method is deprecated. Implement data transformation outside of DBAL. The `Connection::project()` method is deprecated. Implement data transformation outside of DBAL.
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"} {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
], ],
"require": { "require": {
"php": "^7.3", "php": "^7.3 || ^8.0",
"doctrine/cache": "^1.0", "doctrine/cache": "^1.0",
"doctrine/event-manager": "^1.0", "doctrine/event-manager": "^1.0",
"ocramius/package-versions": "^1.4" "ocramius/package-versions": "^1.4"
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
"phpstan/phpstan-phpunit": "^0.12", "phpstan/phpstan-phpunit": "^0.12",
"phpstan/phpstan-strict-rules": "^0.12.2", "phpstan/phpstan-strict-rules": "^0.12.2",
"phpunit/phpunit": "^9.1.1", "phpunit/phpunit": "^9.1.1",
"slevomat/coding-standard": "^6.3.6",
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
"vimeo/psalm": "^3.11" "vimeo/psalm": "^3.11"
}, },
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "380f0866b260bf8eb74733a2461f927f", "content-hash": "ec7d2054f95cb2a24421dcf208e65186",
"packages": [ "packages": [
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
...@@ -820,16 +820,16 @@ ...@@ -820,16 +820,16 @@
}, },
{ {
"name": "netresearch/jsonmapper", "name": "netresearch/jsonmapper",
"version": "v2.1.0", "version": "v2.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/cweiske/jsonmapper.git", "url": "https://github.com/cweiske/jsonmapper.git",
"reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" "reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e245890383c3ed38b6d202ee373c23ccfebc0f54",
"reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", "reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -862,7 +862,7 @@ ...@@ -862,7 +862,7 @@
} }
], ],
"description": "Map nested JSON structures onto PHP classes", "description": "Map nested JSON structures onto PHP classes",
"time": "2020-04-16T18:48:43+00:00" "time": "2020-03-04T17:23:33+00:00"
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
...@@ -1371,21 +1371,21 @@ ...@@ -1371,21 +1371,21 @@
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
"version": "0.12.6", "version": "0.12.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git", "url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "26394996368b6d033d012547d3197f4e07e23021" "reference": "7232c17e2493dc598173da784477ce0afb2c4e0e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/26394996368b6d033d012547d3197f4e07e23021", "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/7232c17e2493dc598173da784477ce0afb2c4e0e",
"reference": "26394996368b6d033d012547d3197f4e07e23021", "reference": "7232c17e2493dc598173da784477ce0afb2c4e0e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "~7.1", "php": "~7.1",
"phpstan/phpstan": "^0.12.4" "phpstan/phpstan": "^0.12.6"
}, },
"conflict": { "conflict": {
"phpunit/phpunit": "<7.0" "phpunit/phpunit": "<7.0"
...@@ -1423,7 +1423,7 @@ ...@@ -1423,7 +1423,7 @@
"MIT" "MIT"
], ],
"description": "PHPUnit extensions and rules for PHPStan", "description": "PHPUnit extensions and rules for PHPStan",
"time": "2020-01-10T12:07:21+00:00" "time": "2020-04-17T08:04:10+00:00"
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
...@@ -1872,6 +1872,16 @@ ...@@ -1872,6 +1872,16 @@
"testing", "testing",
"xunit" "xunit"
], ],
"funding": [
{
"url": "https://phpunit.de/donate.html",
"type": "custom"
},
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
"time": "2020-04-03T14:40:04+00:00" "time": "2020-04-03T14:40:04+00:00"
}, },
{ {
...@@ -1965,6 +1975,12 @@ ...@@ -1965,6 +1975,12 @@
], ],
"description": "Collection of value objects that represent the PHP code units", "description": "Collection of value objects that represent the PHP code units",
"homepage": "https://github.com/sebastianbergmann/code-unit", "homepage": "https://github.com/sebastianbergmann/code-unit",
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
"time": "2020-03-30T11:59:20+00:00" "time": "2020-03-30T11:59:20+00:00"
}, },
{ {
...@@ -2183,6 +2199,12 @@ ...@@ -2183,6 +2199,12 @@
"environment", "environment",
"hhvm" "hhvm"
], ],
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
"time": "2020-03-31T12:14:15+00:00" "time": "2020-03-31T12:14:15+00:00"
}, },
{ {
...@@ -2587,16 +2609,16 @@ ...@@ -2587,16 +2609,16 @@
}, },
{ {
"name": "slevomat/coding-standard", "name": "slevomat/coding-standard",
"version": "6.3.3", "version": "6.3.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/slevomat/coding-standard.git", "url": "https://github.com/slevomat/coding-standard.git",
"reference": "b905a82255749de847fd4de607c7a4c8163f058d" "reference": "500f55b5e2dee1dcef8e88f2038990acdba29f1c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b905a82255749de847fd4de607c7a4c8163f058d", "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/500f55b5e2dee1dcef8e88f2038990acdba29f1c",
"reference": "b905a82255749de847fd4de607c7a4c8163f058d", "reference": "500f55b5e2dee1dcef8e88f2038990acdba29f1c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -2640,7 +2662,7 @@ ...@@ -2640,7 +2662,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-04-28T07:15:08+00:00" "time": "2020-05-27T06:28:47+00:00"
}, },
{ {
"name": "squizlabs/php_codesniffer", "name": "squizlabs/php_codesniffer",
...@@ -3053,8 +3075,8 @@ ...@@ -3053,8 +3075,8 @@
"authors": [ "authors": [
{ {
"name": "Arne Blankerts", "name": "Arne Blankerts",
"email": "arne@blankerts.de", "role": "Developer",
"role": "Developer" "email": "arne@blankerts.de"
} }
], ],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
...@@ -3306,7 +3328,7 @@ ...@@ -3306,7 +3328,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^7.3" "php": "^7.3 || ^8.0"
}, },
"platform-dev": [], "platform-dev": [],
"platform-overrides": { "platform-overrides": {
......
...@@ -42,7 +42,7 @@ object is closed: ...@@ -42,7 +42,7 @@ object is closed:
<?php <?php
$stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key")); $stmt = $conn->executeCacheQuery($query, $params, $types, new QueryCacheProfile(0, "some key"));
$data = $stmt->fetchAll(); $data = $stmt->fetchAllAssociative();
$stmt->closeCursor(); // at this point the result is cached $stmt->closeCursor(); // at this point the result is cached
.. warning:: .. warning::
......
...@@ -41,7 +41,7 @@ the query until there are no more rows: ...@@ -41,7 +41,7 @@ the query until there are no more rows:
<?php <?php
while ($row = $stmt->fetch()) { while (($row = $stmt->fetchAssociative()) !== false) {
echo $row['headline']; echo $row['headline'];
} }
...@@ -308,7 +308,7 @@ Prepare a given SQL statement and return the ...@@ -308,7 +308,7 @@ Prepare a given SQL statement and return the
<?php <?php
$statement = $conn->prepare('SELECT * FROM user'); $statement = $conn->prepare('SELECT * FROM user');
$statement->execute(); $statement->execute();
$users = $statement->fetchAll(); $users = $statement->fetchAllAssociative();
/* /*
array( array(
...@@ -346,7 +346,7 @@ parameters to the execute method, then returning the statement: ...@@ -346,7 +346,7 @@ parameters to the execute method, then returning the statement:
<?php <?php
$statement = $conn->executeQuery('SELECT * FROM user WHERE username = ?', array('jwage')); $statement = $conn->executeQuery('SELECT * FROM user WHERE username = ?', array('jwage'));
$user = $statement->fetch(); $user = $statement->fetchAssociative();
/* /*
array( array(
...@@ -360,15 +360,15 @@ to perform necessary type conversions between actual input ...@@ -360,15 +360,15 @@ to perform necessary type conversions between actual input
parameters and expected database values. See the parameters and expected database values. See the
:ref:`Types <mappingMatrix>` section for more information. :ref:`Types <mappingMatrix>` section for more information.
fetchAll() fetchAllAssociative()
~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
Execute the query and fetch all results into an array: Execute the query and fetch all results into an array:
.. code-block:: php .. code-block:: php
<?php <?php
$users = $conn->fetchAll('SELECT * FROM user'); $users = $conn->fetchAllAssociative('SELECT * FROM user');
/* /*
array( array(
...@@ -379,15 +379,15 @@ Execute the query and fetch all results into an array: ...@@ -379,15 +379,15 @@ Execute the query and fetch all results into an array:
) )
*/ */
fetchArray() fetchNumeric()
~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Numeric index retrieval of first result row of the given query: Numeric index retrieval of first result row of the given query:
.. code-block:: php .. code-block:: php
<?php <?php
$user = $conn->fetchArray('SELECT * FROM user WHERE username = ?', array('jwage')); $user = $conn->fetchNumeric('SELECT * FROM user WHERE username = ?', array('jwage'));
/* /*
array( array(
...@@ -396,26 +396,26 @@ Numeric index retrieval of first result row of the given query: ...@@ -396,26 +396,26 @@ Numeric index retrieval of first result row of the given query:
) )
*/ */
fetchColumn() fetchOne()
~~~~~~~~~~~~~ ~~~~~~~~~~
Retrieve only the given column of the first result row. Retrieve only the value of the first column of the first result row.
.. code-block:: php .. code-block:: php
<?php <?php
$username = $conn->fetchColumn('SELECT username FROM user WHERE id = ?', array(1), 0); $username = $conn->fetchOne('SELECT username FROM user WHERE id = ?', array(1), 0);
echo $username; // jwage echo $username; // jwage
fetchAssoc() fetchAssociative()
~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Retrieve assoc row of the first result row. Retrieve associative array of the first result row.
.. code-block:: php .. code-block:: php
<?php <?php
$user = $conn->fetchAssoc('SELECT * FROM user WHERE username = ?', array('jwage')); $user = $conn->fetchAssociative('SELECT * FROM user WHERE username = ?', array('jwage'));
/* /*
array( array(
'username' => 'jwage', 'username' => 'jwage',
......
...@@ -4,18 +4,13 @@ declare(strict_types=1); ...@@ -4,18 +4,13 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Cache; namespace Doctrine\DBAL\Cache;
use ArrayIterator; use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use IteratorAggregate;
use function array_merge;
use function array_values; use function array_values;
use function count; use function count;
use function reset; use function reset;
use function sprintf;
final class ArrayStatement implements IteratorAggregate, ResultStatement final class ArrayStatement implements ResultStatement
{ {
/** @var mixed[] */ /** @var mixed[] */
private $data; private $data;
...@@ -26,9 +21,6 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -26,9 +21,6 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
/** @var int */ /** @var int */
private $num = 0; private $num = 0;
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
/** /**
* @param mixed[] $data * @param mixed[] $data
*/ */
...@@ -57,78 +49,75 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -57,78 +49,75 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
return count($this->data); return count($this->data);
} }
public function setFetchMode(int $fetchMode) : void
{
$this->defaultFetchMode = $fetchMode;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchNumeric()
{ {
$data = $this->fetchAll(); $row = $this->fetch();
if ($row === false) {
return false;
}
return new ArrayIterator($data); return array_values($row);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchAssociative()
{ {
if (! isset($this->data[$this->num])) { return $this->fetch();
return false;
} }
$row = $this->data[$this->num++]; /**
$fetchMode = $fetchMode ?? $this->defaultFetchMode; * {@inheritdoc}
*/
if ($fetchMode === FetchMode::ASSOCIATIVE) { public function fetchOne()
return $row; {
} $row = $this->fetch();
if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
}
if ($fetchMode === FetchMode::MIXED) { if ($row === false) {
return array_merge($row, array_values($row)); return false;
} }
if ($fetchMode === FetchMode::COLUMN) {
return reset($row); return reset($row);
} }
throw new InvalidArgumentException(
sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAllNumeric() : array
{ {
$rows = []; return FetchUtils::fetchAllNumeric($this);
while ($row = $this->fetch($fetchMode)) {
$rows[] = $row;
} }
return $rows; /**
* {@inheritdoc}
*/
public function fetchAllAssociative() : array
{
return FetchUtils::fetchAllAssociative($this);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchColumn() : array
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchColumn($this);
}
if ($row === false) { /**
* @return mixed|false
*/
private function fetch()
{
if (! isset($this->data[$this->num])) {
return false; return false;
} }
return $row[0]; return $this->data[$this->num++];
} }
} }
...@@ -4,15 +4,12 @@ declare(strict_types=1); ...@@ -4,15 +4,12 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Cache; namespace Doctrine\DBAL\Cache;
use ArrayIterator;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode; use function array_map;
use InvalidArgumentException;
use IteratorAggregate;
use function array_merge;
use function array_values; use function array_values;
use function reset;
/** /**
* Cache statement for SQL results. * Cache statement for SQL results.
...@@ -27,7 +24,7 @@ use function reset; ...@@ -27,7 +24,7 @@ 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.
*/ */
final class ResultCacheStatement implements IteratorAggregate, ResultStatement final class ResultCacheStatement implements ResultStatement
{ {
/** @var Cache */ /** @var Cache */
private $resultCache; private $resultCache;
...@@ -51,12 +48,9 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -51,12 +48,9 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
*/ */
private $emptied = false; private $emptied = false;
/** @var mixed[] */ /** @var array<int,array<string,mixed>> */
private $data; private $data;
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
public function __construct(ResultStatement $stmt, Cache $resultCache, string $cacheKey, string $realKey, int $lifetime) public function __construct(ResultStatement $stmt, Cache $resultCache, string $cacheKey, string $realKey, int $lifetime)
{ {
$this->statement = $stmt; $this->statement = $stmt;
...@@ -90,76 +84,61 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -90,76 +84,61 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
return $this->statement->columnCount(); return $this->statement->columnCount();
} }
public function setFetchMode(int $fetchMode) : void public function rowCount() : int
{ {
$this->defaultFetchMode = $fetchMode; return $this->statement->rowCount();
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchNumeric()
{ {
$data = $this->fetchAll(); $row = $this->fetch();
return new ArrayIterator($data); if ($row === false) {
return false;
}
return array_values($row);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchAssociative()
{ {
if ($this->data === null) { return $this->fetch();
$this->data = [];
}
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);
if ($row !== false) {
$this->data[] = $row;
$fetchMode = $fetchMode ?? $this->defaultFetchMode;
if ($fetchMode === FetchMode::ASSOCIATIVE) {
return $row;
}
if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
}
if ($fetchMode === FetchMode::MIXED) {
return array_merge($row, array_values($row));
}
if ($fetchMode === FetchMode::COLUMN) {
return reset($row);
} }
throw new InvalidArgumentException('Invalid fetch-style given for caching result.'); /**
} * {@inheritdoc}
*/
$this->emptied = true; public function fetchOne()
{
return false; return FetchUtils::fetchOne($this);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAllNumeric() : array
{ {
$data = $this->statement->fetchAll($fetchMode); $this->store(
$this->statement->fetchAllAssociative()
);
if ($fetchMode === FetchMode::COLUMN) { return array_map('array_values', $this->data);
foreach ($data as $key => $value) {
$data[$key] = [$value];
}
} }
$this->data = $data; /**
$this->emptied = true; * {@inheritdoc}
*/
public function fetchAllAssociative() : array
{
$this->store(
$this->statement->fetchAllAssociative()
);
return $this->data; return $this->data;
} }
...@@ -167,30 +146,41 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -167,30 +146,41 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchColumn() : array
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchColumn($this);
}
if ($row === false) { /**
return false; * @return array<string,mixed>|false
*
* @throws DriverException
*/
private function fetch()
{
if ($this->data === null) {
$this->data = [];
} }
return $row[0]; $row = $this->statement->fetchAssociative();
if ($row !== false) {
$this->data[] = $row;
return $row;
}
$this->emptied = true;
return false;
} }
/** /**
* Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement * @param array<int,array<string,mixed>> $data
* executed by the corresponding object.
*
* If the last SQL statement executed by the associated Statement object was a SELECT statement,
* some databases may return the number of rows returned by that statement. However,
* this behaviour is not guaranteed for all databases and should not be
* relied on for portable applications.
*
* @return int The number of rows.
*/ */
public function rowCount() : int private function store(array $data) : void
{ {
return $this->statement->rowCount(); $this->data = $data;
$this->emptied = true;
} }
} }
This diff is collapsed.
...@@ -324,8 +324,6 @@ class MasterSlaveConnection extends Connection ...@@ -324,8 +324,6 @@ class MasterSlaveConnection extends Connection
$statement = $this->_conn->query($sql); $statement = $this->_conn->query($sql);
$statement->setFetchMode($this->defaultFetchMode);
$logger->stopQuery(); $logger->stopQuery();
return $statement; return $statement;
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver;
/**
* @internal
*/
final class FetchUtils
{
/**
* @return mixed|false
*
* @throws DriverException
*/
public static function fetchOne(ResultStatement $stmt)
{
$row = $stmt->fetchNumeric();
if ($row === false) {
return false;
}
return $row[0];
}
/**
* @return array<int,array<int,mixed>>
*
* @throws DriverException
*/
public static function fetchAllNumeric(ResultStatement $stmt) : array
{
$rows = [];
while (($row = $stmt->fetchNumeric()) !== false) {
$rows[] = $row;
}
return $rows;
}
/**
* @return array<int,array<string,mixed>>
*
* @throws DriverException
*/
public static function fetchAllAssociative(ResultStatement $stmt) : array
{
$rows = [];
while (($row = $stmt->fetchAssociative()) !== false) {
$rows[] = $row;
}
return $rows;
}
/**
* @return array<int,mixed>
*
* @throws DriverException
*/
public static function fetchColumn(ResultStatement $stmt) : array
{
$rows = [];
while (($row = $stmt->fetchOne()) !== false) {
$rows[] = $row;
}
return $rows;
}
}
...@@ -4,17 +4,14 @@ declare(strict_types=1); ...@@ -4,17 +4,14 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\IBMDB2; namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use function assert; use function assert;
use function db2_bind_param; use function db2_bind_param;
use function db2_execute; use function db2_execute;
use function db2_fetch_array; use function db2_fetch_array;
use function db2_fetch_assoc; use function db2_fetch_assoc;
use function db2_fetch_both;
use function db2_free_result; use function db2_free_result;
use function db2_num_fields; use function db2_num_fields;
use function db2_num_rows; use function db2_num_rows;
...@@ -33,7 +30,7 @@ use const DB2_LONG; ...@@ -33,7 +30,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;
final class DB2Statement implements IteratorAggregate, Statement final class DB2Statement implements Statement
{ {
/** @var resource */ /** @var resource */
private $stmt; private $stmt;
...@@ -49,9 +46,6 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -49,9 +46,6 @@ final class DB2Statement implements IteratorAggregate, Statement
*/ */
private $lobs = []; private $lobs = [];
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
/** /**
* Indicates whether the statement is in the state when fetching results is possible * Indicates whether the statement is in the state when fetching results is possible
* *
...@@ -133,8 +127,6 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -133,8 +127,6 @@ final class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated The error information is available via exceptions.
*/ */
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
...@@ -173,85 +165,62 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -173,85 +165,62 @@ final class DB2Statement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
public function setFetchMode(int $fetchMode) : void
{
$this->defaultFetchMode = $fetchMode;
}
/** /**
* {@inheritdoc} * {@inheritDoc}
*/ */
public function getIterator() public function fetchNumeric()
{ {
return new StatementIterator($this); if (! $this->result) {
return false;
}
return db2_fetch_array($this->stmt);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchAssociative()
{ {
// do not try fetching from the statement if it's not expected to contain result // do not try fetching from the statement if it's not expected to contain the result
// in order to prevent exceptional situation // in order to prevent exceptional situation
if (! $this->result) { if (! $this->result) {
return false; return false;
} }
$fetchMode = $fetchMode ?? $this->defaultFetchMode;
switch ($fetchMode) {
case FetchMode::COLUMN:
return $this->fetchColumn();
case FetchMode::MIXED:
return db2_fetch_both($this->stmt);
case FetchMode::ASSOCIATIVE:
return db2_fetch_assoc($this->stmt); return db2_fetch_assoc($this->stmt);
case FetchMode::NUMERIC:
return db2_fetch_array($this->stmt);
default:
throw new DB2Exception('Given Fetch-Style ' . $fetchMode . ' is not supported.');
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchOne()
{ {
$rows = []; return FetchUtils::fetchOne($this);
switch ($fetchMode) {
case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
} }
break; /**
* {@inheritdoc}
default: */
while (($row = $this->fetch($fetchMode)) !== false) { public function fetchAllNumeric() : array
$rows[] = $row; {
} return FetchUtils::fetchAllNumeric($this);
}
return $rows;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchAllAssociative() : array
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchAllAssociative($this);
if ($row === false) {
return false;
} }
return $row[0]; /**
* {@inheritdoc}
*/
public function fetchColumn() : array
{
return FetchUtils::fetchColumn($this);
} }
public function rowCount() : int public function rowCount() : int
......
...@@ -5,17 +5,14 @@ declare(strict_types=1); ...@@ -5,17 +5,14 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli; namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError; use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset; use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError; use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownFetchMode;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType; use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use mysqli; use mysqli;
use mysqli_stmt; use mysqli_stmt;
use stdClass; use stdClass;
...@@ -32,7 +29,7 @@ use function is_int; ...@@ -32,7 +29,7 @@ use function is_int;
use function is_resource; use function is_resource;
use function str_repeat; use function str_repeat;
final class MysqliStatement implements IteratorAggregate, Statement final class MysqliStatement implements Statement
{ {
/** @var string[] */ /** @var string[] */
private static $paramTypeMap = [ private static $paramTypeMap = [
...@@ -89,9 +86,6 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -89,9 +86,6 @@ final class MysqliStatement implements IteratorAggregate, Statement
*/ */
private $values = []; private $values = [];
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
/** /**
* Indicates whether the statement is in the state when fetching results is possible * Indicates whether the statement is in the state when fetching results is possible
* *
...@@ -326,20 +320,14 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -326,20 +320,14 @@ final class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchNumeric()
{ {
// do not try fetching from the statement if it's not expected to contain result // do not try fetching from the statement if it's not expected to contain the result
// in order to prevent exceptional situation // in order to prevent exceptional situation
if (! $this->result) { if (! $this->result) {
return false; return false;
} }
$fetchMode = $fetchMode ?? $this->defaultFetchMode;
if ($fetchMode === FetchMode::COLUMN) {
return $this->fetchColumn();
}
$values = $this->_fetch(); $values = $this->_fetch();
if ($values === null) { if ($values === null) {
...@@ -350,59 +338,56 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -350,59 +338,56 @@ final class MysqliStatement implements IteratorAggregate, Statement
throw StatementError::new($this->stmt); throw StatementError::new($this->stmt);
} }
if ($fetchMode === FetchMode::NUMERIC) {
return $values; return $values;
} }
$assoc = array_combine($this->columnNames, $values); /**
assert(is_array($assoc)); * {@inheritDoc}
*/
public function fetchAssociative()
{
$values = $this->fetchNumeric();
switch ($fetchMode) { if ($values === false) {
case FetchMode::ASSOCIATIVE: return false;
return $assoc; }
case FetchMode::MIXED: $row = array_combine($this->columnNames, $values);
return $assoc + $values; assert(is_array($row));
default: return $row;
throw UnknownFetchMode::new($fetchMode);
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchOne()
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; return FetchUtils::fetchOne($this);
$rows = [];
if ($fetchMode === FetchMode::COLUMN) {
while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
}
} else {
while (($row = $this->fetch($fetchMode)) !== false) {
$rows[] = $row;
}
} }
return $rows; /**
* {@inheritdoc}
*/
public function fetchAllNumeric() : array
{
return FetchUtils::fetchAllNumeric($this);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchAllAssociative() : array
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchAllAssociative($this);
if ($row === false) {
return false;
} }
return $row[0]; /**
* {@inheritdoc}
*/
public function fetchColumn() : array
{
return FetchUtils::fetchColumn($this);
} }
public function closeCursor() : void public function closeCursor() : void
...@@ -424,17 +409,4 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -424,17 +409,4 @@ final class MysqliStatement implements IteratorAggregate, Statement
{ {
return $this->stmt->field_count; return $this->stmt->field_count;
} }
public function setFetchMode(int $fetchMode) : void
{
$this->defaultFetchMode = $fetchMode;
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
return new StatementIterator($this);
}
} }
...@@ -116,9 +116,7 @@ final class OCI8Connection implements Connection, ServerInfoAwareConnection ...@@ -116,9 +116,7 @@ final class OCI8Connection implements Connection, ServerInfoAwareConnection
throw new OCI8Exception('The driver does not support identity columns.'); throw new OCI8Exception('The driver does not support identity columns.');
} }
$sql = 'SELECT ' . $name . '.CURRVAL FROM DUAL'; $result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne();
$stmt = $this->query($sql);
$result = $stmt->fetchColumn();
if ($result === false) { if ($result === false) {
throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.'); throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
......
...@@ -4,12 +4,9 @@ declare(strict_types=1); ...@@ -4,12 +4,9 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\OCI8; namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use InvalidArgumentException;
use IteratorAggregate;
use function assert; use function assert;
use function is_int; use function is_int;
use function is_resource; use function is_resource;
...@@ -27,11 +24,11 @@ use function sprintf; ...@@ -27,11 +24,11 @@ use function sprintf;
use const OCI_ASSOC; use const OCI_ASSOC;
use const OCI_B_BIN; use const OCI_B_BIN;
use const OCI_B_BLOB; use const OCI_B_BLOB;
use const OCI_BOTH;
use const OCI_COMMIT_ON_SUCCESS; use const OCI_COMMIT_ON_SUCCESS;
use const OCI_D_LOB; use const OCI_D_LOB;
use const OCI_FETCHSTATEMENT_BY_COLUMN; use const OCI_FETCHSTATEMENT_BY_COLUMN;
use const OCI_FETCHSTATEMENT_BY_ROW; use const OCI_FETCHSTATEMENT_BY_ROW;
use const OCI_NO_AUTO_COMMIT;
use const OCI_NUM; use const OCI_NUM;
use const OCI_RETURN_LOBS; use const OCI_RETURN_LOBS;
use const OCI_RETURN_NULLS; use const OCI_RETURN_NULLS;
...@@ -41,7 +38,7 @@ use const SQLT_CHR; ...@@ -41,7 +38,7 @@ use const SQLT_CHR;
/** /**
* The OCI8 implementation of the Statement interface. * The OCI8 implementation of the Statement interface.
*/ */
final class OCI8Statement implements IteratorAggregate, Statement final class OCI8Statement implements Statement
{ {
/** @var resource */ /** @var resource */
protected $_dbh; protected $_dbh;
...@@ -52,17 +49,6 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -52,17 +49,6 @@ final class OCI8Statement implements IteratorAggregate, Statement
/** @var ExecutionMode */ /** @var ExecutionMode */
protected $executionMode; protected $executionMode;
/** @var int[] */
protected static $fetchModeMap = [
FetchMode::MIXED => OCI_BOTH,
FetchMode::ASSOCIATIVE => OCI_ASSOC,
FetchMode::NUMERIC => OCI_NUM,
FetchMode::COLUMN => OCI_NUM,
];
/** @var int */
protected $_defaultFetchMode = FetchMode::MIXED;
/** @var string[] */ /** @var string[] */
protected $_paramMap = []; protected $_paramMap = [];
...@@ -190,8 +176,6 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -190,8 +176,6 @@ final class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated The error information is available via exceptions.
*/ */
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
...@@ -221,71 +205,88 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -221,71 +205,88 @@ final class OCI8Statement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
public function setFetchMode(int $fetchMode) : void public function rowCount() : int
{ {
$this->_defaultFetchMode = $fetchMode; $count = oci_num_rows($this->_sth);
if ($count !== false) {
return $count;
}
return 0;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchNumeric()
{ {
return new StatementIterator($this); return $this->fetch(OCI_NUM);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchAssociative()
{ {
// do not try fetching from the statement if it's not expected to contain result return $this->fetch(OCI_ASSOC);
// in order to prevent exceptional situation
if (! $this->result) {
return false;
} }
$fetchMode = $fetchMode ?? $this->_defaultFetchMode; /**
* {@inheritdoc}
if ($fetchMode === FetchMode::COLUMN) { */
return $this->fetchColumn(); public function fetchOne()
{
return FetchUtils::fetchOne($this);
} }
if (! isset(self::$fetchModeMap[$fetchMode])) { /**
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode)); * {@inheritdoc}
*/
public function fetchAllNumeric() : array
{
return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_ROW);
} }
return oci_fetch_array( /**
$this->_sth, * {@inheritdoc}
self::$fetchModeMap[$fetchMode] | OCI_RETURN_NULLS | OCI_RETURN_LOBS */
); public function fetchAllAssociative() : array
{
return $this->fetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchColumn() : array
{ {
$fetchMode = $fetchMode ?? $this->_defaultFetchMode; return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0];
$result = [];
if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
} }
if (self::$fetchModeMap[$fetchMode] === OCI_BOTH) { /**
while ($row = $this->fetch($fetchMode)) { * @return mixed|false
$result[] = $row; */
private function fetch(int $mode)
{
// do not try fetching from the statement if it's not expected to contain the result
// in order to prevent exceptional situation
if (! $this->result) {
return false;
} }
} else {
$fetchStructure = OCI_FETCHSTATEMENT_BY_ROW;
if ($fetchMode === FetchMode::COLUMN) { return oci_fetch_array(
$fetchStructure = OCI_FETCHSTATEMENT_BY_COLUMN; $this->_sth,
$mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS
);
} }
// do not try fetching from the statement if it's not expected to contain result /**
* @return array<mixed>
*/
private function fetchAll(int $mode, int $fetchStructure) : array
{
// do not try fetching from the statement if it's not expected to contain the result
// in order to prevent exceptional situation // in order to prevent exceptional situation
if (! $this->result) { if (! $this->result) {
return []; return [];
...@@ -296,45 +297,9 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -296,45 +297,9 @@ final class OCI8Statement implements IteratorAggregate, Statement
$result, $result,
0, 0,
-1, -1,
self::$fetchModeMap[$fetchMode] | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS $mode | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS
); );
if ($fetchMode === FetchMode::COLUMN) {
$result = $result[0];
}
}
return $result; return $result;
} }
/**
* {@inheritdoc}
*/
public function fetchColumn()
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
if (! $this->result) {
return false;
}
$row = oci_fetch_array($this->_sth, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
if ($row === false) {
return false;
}
return $row[0];
}
public function rowCount() : int
{
$count = oci_num_rows($this->_sth);
if ($count !== false) {
return $count;
}
return 0;
}
} }
...@@ -23,7 +23,7 @@ class Connection extends PDOConnection ...@@ -23,7 +23,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]);
return $stmt->fetchColumn(); return $stmt->fetchOne();
} }
public function quote(string $input) : string public function quote(string $input) : string
......
...@@ -4,11 +4,8 @@ declare(strict_types=1); ...@@ -4,11 +4,8 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver; namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Exception\UnknownFetchMode;
use Doctrine\DBAL\Driver\Exception\UnknownParamType; use Doctrine\DBAL\Driver\Exception\UnknownParamType;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use PDO; use PDO;
use function array_slice; use function array_slice;
use function assert; use function assert;
...@@ -20,7 +17,7 @@ use function is_array; ...@@ -20,7 +17,7 @@ use function is_array;
* 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 implements IteratorAggregate, Statement class PDOStatement implements Statement
{ {
private const PARAM_TYPE_MAP = [ private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL, ParameterType::NULL => PDO::PARAM_NULL,
...@@ -31,13 +28,6 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -31,13 +28,6 @@ class PDOStatement implements IteratorAggregate, Statement
ParameterType::BOOLEAN => PDO::PARAM_BOOL, ParameterType::BOOLEAN => PDO::PARAM_BOOL,
]; ];
private const FETCH_MODE_MAP = [
FetchMode::ASSOCIATIVE => PDO::FETCH_ASSOC,
FetchMode::NUMERIC => PDO::FETCH_NUM,
FetchMode::MIXED => PDO::FETCH_BOTH,
FetchMode::COLUMN => PDO::FETCH_COLUMN,
];
/** @var \PDOStatement */ /** @var \PDOStatement */
private $stmt; private $stmt;
...@@ -46,17 +36,6 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -46,17 +36,6 @@ class PDOStatement implements IteratorAggregate, Statement
$this->stmt = $stmt; $this->stmt = $stmt;
} }
public function setFetchMode(int $fetchMode) : void
{
$fetchMode = $this->convertFetchMode($fetchMode);
try {
$this->stmt->setFetchMode($fetchMode);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -122,88 +101,94 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -122,88 +101,94 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchNumeric()
{ {
try { return $this->fetch(PDO::FETCH_NUM);
if ($fetchMode === null) {
return $this->stmt->fetch();
} }
return $this->stmt->fetch( /**
$this->convertFetchMode($fetchMode) * {@inheritdoc}
); */
} catch (\PDOException $exception) { public function fetchAssociative()
throw new PDOException($exception); {
} return $this->fetch(PDO::FETCH_ASSOC);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchOne()
{ {
try { return $this->fetch(PDO::FETCH_COLUMN);
if ($fetchMode === null) {
$data = $this->stmt->fetchAll();
} else {
$data = $this->stmt->fetchAll(
$this->convertFetchMode($fetchMode)
);
}
} catch (\PDOException $exception) {
throw new PDOException($exception);
} }
assert(is_array($data)); /**
* {@inheritdoc}
return $data; */
public function fetchAllNumeric() : array
{
return $this->fetchAll(PDO::FETCH_NUM);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchAllAssociative() : array
{ {
try { return $this->fetchAll(PDO::FETCH_ASSOC);
return $this->stmt->fetchColumn();
} catch (\PDOException $exception) {
throw new PDOException($exception);
} }
/**
* {@inheritdoc}
*/
public function fetchColumn() : array
{
return $this->fetchAll(PDO::FETCH_COLUMN);
} }
/** /**
* Converts DBAL parameter type to PDO parameter type * @return mixed|false
* *
* @param int $type Parameter type * @throws PDOException
*/ */
private function convertParamType(int $type) : int private function fetch(int $mode)
{ {
if (! isset(self::PARAM_TYPE_MAP[$type])) { try {
throw UnknownParamType::new($type); return $this->stmt->fetch($mode);
} catch (\PDOException $exception) {
throw new PDOException($exception);
} }
return self::PARAM_TYPE_MAP[$type];
} }
/** /**
* Converts DBAL fetch mode to PDO fetch mode * @return array<int,mixed>
* *
* @param int $fetchMode Fetch mode * @throws PDOException
*/ */
private function convertFetchMode(int $fetchMode) : int private function fetchAll(int $mode) : array
{ {
if (! isset(self::FETCH_MODE_MAP[$fetchMode])) { try {
throw UnknownFetchMode::new($fetchMode); $data = $this->stmt->fetchAll($mode);
} catch (\PDOException $exception) {
throw new PDOException($exception);
} }
return self::FETCH_MODE_MAP[$fetchMode]; assert(is_array($data));
return $data;
} }
/** /**
* {@inheritdoc} * Converts DBAL parameter type to PDO parameter type
*
* @param int $type Parameter type
*/ */
public function getIterator() private function convertParamType(int $type) : int
{ {
yield from $this->stmt; if (! isset(self::PARAM_TYPE_MAP[$type])) {
throw UnknownParamType::new($type);
}
return self::PARAM_TYPE_MAP[$type];
} }
} }
...@@ -4,12 +4,10 @@ declare(strict_types=1); ...@@ -4,12 +4,10 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver; namespace Doctrine\DBAL\Driver;
use Traversable;
/** /**
* Interface for the reading part of a prepare statement only. * Interface for the reading part of a prepare statement only.
*/ */
interface ResultStatement extends Traversable interface ResultStatement
{ {
/** /**
* Closes the cursor, enabling the statement to be executed again. * Closes the cursor, enabling the statement to be executed again.
...@@ -37,40 +35,56 @@ interface ResultStatement extends Traversable ...@@ -37,40 +35,56 @@ interface ResultStatement extends Traversable
public function rowCount() : int; public function rowCount() : int;
/** /**
* Sets the fetch mode to use while iterating this statement. * Returns the next row of a result set as a numeric array or FALSE if there are no more rows.
*
* @return array<int,mixed>|false
*
* @throws DriverException
*/
public function fetchNumeric();
/**
* Returns the next row of a result set as an associative array or FALSE if there are no more rows.
*
* @return array<string,mixed>|false
* *
* @param int $fetchMode Controls how the next row will be returned to the caller. * @throws DriverException
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants.
*/ */
public function setFetchMode(int $fetchMode) : void; public function fetchAssociative();
/** /**
* Returns the next row of a result set. * Returns the first value of the next row of a result set or FALSE if there are no more rows.
* *
* @param int|null $fetchMode Controls how the next row will be returned to the caller. * @return mixed|false
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
* defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
* *
* @return mixed The return value of this method on success depends on the fetch mode. In all cases, FALSE is * @throws DriverException
* returned on failure.
*/ */
public function fetch(?int $fetchMode = null); public function fetchOne();
/** /**
* Returns an array containing all of the result set rows. * Returns an array containing all of the result set rows represented as numeric arrays.
* *
* @param int|null $fetchMode Controls how the next row will be returned to the caller. * @return array<int,array<int,mixed>>
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
* defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
* *
* @return mixed[] * @throws DriverException
*/ */
public function fetchAll(?int $fetchMode = null) : array; public function fetchAllNumeric() : array;
/** /**
* Returns a single column from the next row of a result set or FALSE if there are no more rows. * Returns an array containing all of the result set rows represented as associative arrays.
*
* @return array<int,array<string,mixed>>
*
* @throws DriverException
*/
public function fetchAllAssociative() : array;
/**
* Returns an array containing the values of the first column of the result set.
*
* @return array<int,mixed>
* *
* @return mixed|false A single column in the next row of a result set, or FALSE if there are no more rows. * @throws DriverException
*/ */
public function fetchColumn(); public function fetchColumn() : array;
} }
...@@ -92,8 +92,7 @@ final class SQLAnywhereConnection implements ServerInfoAwareConnection ...@@ -92,8 +92,7 @@ final class SQLAnywhereConnection implements ServerInfoAwareConnection
public function getServerVersion() : string public function getServerVersion() : string
{ {
$version = $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn(); $version = $this->query("SELECT PROPERTY('ProductVersion')")->fetchOne();
assert(is_string($version)); assert(is_string($version));
return $version; return $version;
...@@ -105,7 +104,7 @@ final class SQLAnywhereConnection implements ServerInfoAwareConnection ...@@ -105,7 +104,7 @@ final class SQLAnywhereConnection implements ServerInfoAwareConnection
return sasql_insert_id($this->connection); return sasql_insert_id($this->connection);
} }
return $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn(); return $this->query('SELECT ' . $name . '.CURRVAL')->fetchOne();
} }
public function prepare(string $sql) : DriverStatement public function prepare(string $sql) : DriverStatement
......
...@@ -4,17 +4,15 @@ declare(strict_types=1); ...@@ -4,17 +4,15 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\SQLAnywhere; namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\GetVariableType; use Doctrine\DBAL\Exception\GetVariableType;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use function array_key_exists; use function array_key_exists;
use function assert; use function assert;
use function is_int; use function is_int;
use function is_resource; use function is_resource;
use function sasql_fetch_array;
use function sasql_fetch_assoc; use function sasql_fetch_assoc;
use function sasql_fetch_row; use function sasql_fetch_row;
use function sasql_prepare; use function sasql_prepare;
...@@ -25,19 +23,15 @@ use function sasql_stmt_field_count; ...@@ -25,19 +23,15 @@ use function sasql_stmt_field_count;
use function sasql_stmt_reset; use function sasql_stmt_reset;
use function sasql_stmt_result_metadata; use function sasql_stmt_result_metadata;
use function sprintf; use function sprintf;
use const SASQL_BOTH;
/** /**
* SAP SQL Anywhere implementation of the Statement interface. * SAP SQL Anywhere implementation of the Statement interface.
*/ */
final class SQLAnywhereStatement implements IteratorAggregate, Statement final class SQLAnywhereStatement implements Statement
{ {
/** @var resource The connection resource. */ /** @var resource The connection resource. */
private $conn; private $conn;
/** @var int Default fetch mode to use. */
private $defaultFetchMode = FetchMode::MIXED;
/** @var resource|null The result set resource to fetch. */ /** @var resource|null The result set resource to fetch. */
private $result; private $result;
...@@ -157,85 +151,69 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -157,85 +151,69 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
* *
* @throws SQLAnywhereException * @throws SQLAnywhereException
*/ */
public function fetch(?int $fetchMode = null) public function fetchNumeric()
{ {
if (! is_resource($this->result)) { if (! is_resource($this->result)) {
return false; return false;
} }
$fetchMode = $fetchMode ?? $this->defaultFetchMode;
switch ($fetchMode) {
case FetchMode::COLUMN:
return $this->fetchColumn();
case FetchMode::ASSOCIATIVE:
return sasql_fetch_assoc($this->result);
case FetchMode::MIXED:
return sasql_fetch_array($this->result, SASQL_BOTH);
case FetchMode::NUMERIC:
return sasql_fetch_row($this->result); return sasql_fetch_row($this->result);
default:
throw new SQLAnywhereException(sprintf('Fetch mode is not supported %d.', $fetchMode));
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAssociative()
{ {
$rows = []; if (! is_resource($this->result)) {
return false;
switch ($fetchMode) {
case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
}
break;
default:
while (($row = $this->fetch($fetchMode)) !== false) {
$rows[] = $row;
}
} }
return $rows; return sasql_fetch_assoc($this->result);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @throws DriverException
*/ */
public function fetchColumn() public function fetchOne()
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchOne($this);
if ($row === false) {
return false;
} }
return $row[0]; /**
* @return array<int,array<int,mixed>>
*
* @throws DriverException
*/
public function fetchAllNumeric() : array
{
return FetchUtils::fetchAllNumeric($this);
} }
/** /**
* {@inheritdoc} * @return array<int,array<string,mixed>>
*
* @throws DriverException
*/ */
public function getIterator() public function fetchAllAssociative() : array
{ {
return new StatementIterator($this); return FetchUtils::fetchAllAssociative($this);
} }
public function rowCount() : int /**
* @return array<int,mixed>
*
* @throws DriverException
*/
public function fetchColumn() : array
{ {
return sasql_stmt_affected_rows($this->stmt); return FetchUtils::fetchColumn($this);
} }
public function setFetchMode(int $fetchMode) : void public function rowCount() : int
{ {
$this->defaultFetchMode = $fetchMode; return sasql_stmt_affected_rows($this->stmt);
} }
} }
...@@ -100,7 +100,7 @@ final class SQLSrvConnection implements ServerInfoAwareConnection ...@@ -100,7 +100,7 @@ final class SQLSrvConnection implements ServerInfoAwareConnection
$stmt = $this->query('SELECT @@IDENTITY'); $stmt = $this->query('SELECT @@IDENTITY');
} }
return $stmt->fetchColumn(); return $stmt->fetchOne();
} }
public function beginTransaction() : void public function beginTransaction() : void
......
...@@ -4,11 +4,9 @@ declare(strict_types=1); ...@@ -4,11 +4,9 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\SQLSrv; namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use function assert; use function assert;
use function is_int; use function is_int;
use function sqlsrv_execute; use function sqlsrv_execute;
...@@ -25,14 +23,13 @@ use function SQLSRV_SQLTYPE_VARBINARY; ...@@ -25,14 +23,13 @@ use function SQLSRV_SQLTYPE_VARBINARY;
use function stripos; use function stripos;
use const SQLSRV_ENC_BINARY; use const SQLSRV_ENC_BINARY;
use const SQLSRV_FETCH_ASSOC; use const SQLSRV_FETCH_ASSOC;
use const SQLSRV_FETCH_BOTH;
use const SQLSRV_FETCH_NUMERIC; use const SQLSRV_FETCH_NUMERIC;
use const SQLSRV_PARAM_IN; use const SQLSRV_PARAM_IN;
/** /**
* SQL Server Statement. * SQL Server Statement.
*/ */
final class SQLSrvStatement implements IteratorAggregate, Statement final class SQLSrvStatement implements Statement
{ {
/** /**
* The SQLSRV Resource. * The SQLSRV Resource.
...@@ -69,24 +66,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -69,24 +66,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
*/ */
private $types = []; private $types = [];
/**
* Translations.
*
* @var int[]
*/
private static $fetchMap = [
FetchMode::MIXED => SQLSRV_FETCH_BOTH,
FetchMode::ASSOCIATIVE => SQLSRV_FETCH_ASSOC,
FetchMode::NUMERIC => SQLSRV_FETCH_NUMERIC,
];
/**
* The fetch style.
*
* @var int
*/
private $defaultFetchMode = FetchMode::MIXED;
/** /**
* The last insert ID. * The last insert ID.
* *
...@@ -181,8 +160,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -181,8 +160,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated The error information is available via exceptions.
*/ */
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
...@@ -213,81 +190,52 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -213,81 +190,52 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
public function setFetchMode(int $fetchMode) : void /**
* {@inheritdoc}
*/
public function fetchNumeric()
{ {
$this->defaultFetchMode = $fetchMode; return $this->fetch(SQLSRV_FETCH_NUMERIC);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchAssociative()
{ {
return new StatementIterator($this); return $this->fetch(SQLSRV_FETCH_ASSOC);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @throws SQLSrvException
*/ */
public function fetch(?int $fetchMode = null) public function fetchOne()
{ {
// do not try fetching from the statement if it's not expected to contain result return FetchUtils::fetchOne($this);
// in order to prevent exceptional situation
if ($this->stmt === null || ! $this->result) {
return false;
}
$fetchMode = $fetchMode ?? $this->defaultFetchMode;
if ($fetchMode === FetchMode::COLUMN) {
return $this->fetchColumn();
}
if (isset(self::$fetchMap[$fetchMode])) {
return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]) ?? false;
}
throw new SQLSrvException('Fetch mode is not supported.');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAllNumeric() : array
{ {
$rows = []; return FetchUtils::fetchAllNumeric($this);
switch ($fetchMode) {
case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
}
break;
default:
while (($row = $this->fetch($fetchMode)) !== false) {
$rows[] = $row;
}
}
return $rows;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn() public function fetchAllAssociative() : array
{ {
$row = $this->fetch(FetchMode::NUMERIC); return FetchUtils::fetchAllAssociative($this);
if ($row === false) {
return false;
} }
return $row[0]; /**
* {@inheritdoc}
*/
public function fetchColumn() : array
{
return FetchUtils::fetchColumn($this);
} }
public function rowCount() : int public function rowCount() : int
...@@ -349,4 +297,18 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -349,4 +297,18 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
return $stmt; return $stmt;
} }
/**
* @return mixed|false
*/
private function fetch(int $fetchType)
{
// do not try fetching from the statement if it's not expected to contain the result
// in order to prevent exceptional situation
if ($this->stmt === null || ! $this->result) {
return false;
}
return sqlsrv_fetch_array($this->stmt, $fetchType) ?? false;
}
} }
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver;
use IteratorAggregate;
final class StatementIterator implements IteratorAggregate
{
/** @var ResultStatement */
private $statement;
public function __construct(ResultStatement $statement)
{
$this->statement = $statement;
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
while (($result = $this->statement->fetch()) !== false) {
yield $result;
}
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL;
/**
* Contains statement fetch modes.
*/
final class FetchMode
{
/**
* Specifies that the fetch method shall return each row as an array indexed
* by column name as returned in the corresponding result set. If the result
* set contains multiple columns with the same name, the statement returns
* only a single value per column name.
*
* @see \PDO::FETCH_ASSOC
*/
public const ASSOCIATIVE = 2;
/**
* Specifies that the fetch method shall return each row as an array indexed
* by column number as returned in the corresponding result set, starting at
* column 0.
*
* @see \PDO::FETCH_NUM
*/
public const NUMERIC = 3;
/**
* Specifies that the fetch method shall return each row as an array indexed
* by both column name and number as returned in the corresponding result set,
* starting at column 0.
*
* @see \PDO::FETCH_BOTH
*/
public const MIXED = 4;
/**
* Specifies that the fetch method shall return only a single requested
* column from the next row in the result set.
*
* @see \PDO::FETCH_COLUMN
*/
public const COLUMN = 7;
/**
* This class cannot be instantiated.
*/
private function __construct()
{
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility\Driver;
use Doctrine\DBAL\Driver\ResultStatement as BaseResultStatement;
/**
* Forward compatibility extension for the ResultStatement interface.
*
* @deprecated
*/
interface ResultStatement extends BaseResultStatement
{
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\ForwardCompatibility;
use Doctrine\DBAL\ForwardCompatibility\Driver\ResultStatement as BaseResultStatement;
/**
* Forward compatibility extension for the DBAL ResultStatement interface.
*
* @deprecated
*/
interface ResultStatement extends BaseResultStatement
{
}
...@@ -7,7 +7,6 @@ namespace Doctrine\DBAL\Id; ...@@ -7,7 +7,6 @@ namespace Doctrine\DBAL\Id;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;
use Throwable; use Throwable;
use function array_change_key_case; use function array_change_key_case;
...@@ -102,8 +101,7 @@ class TableGenerator ...@@ -102,8 +101,7 @@ class TableGenerator
$sql = 'SELECT sequence_value, sequence_increment_by' $sql = 'SELECT sequence_value, sequence_increment_by'
. ' FROM ' . $platform->appendLockHint($this->generatorTableName, LockMode::PESSIMISTIC_WRITE) . ' FROM ' . $platform->appendLockHint($this->generatorTableName, LockMode::PESSIMISTIC_WRITE)
. ' WHERE sequence_name = ? ' . $platform->getWriteLockSQL(); . ' WHERE sequence_name = ? ' . $platform->getWriteLockSQL();
$stmt = $this->conn->executeQuery($sql, [$sequenceName]); $row = $this->conn->fetchAssociative($sql, [$sequenceName]);
$row = $stmt->fetch(FetchMode::ASSOCIATIVE);
if ($row !== false) { if ($row !== false) {
$row = array_change_key_case($row, CASE_LOWER); $row = array_change_key_case($row, CASE_LOWER);
......
...@@ -99,28 +99,20 @@ class Connection extends \Doctrine\DBAL\Connection ...@@ -99,28 +99,20 @@ class Connection extends \Doctrine\DBAL\Connection
array $types = [], array $types = [],
?QueryCacheProfile $qcp = null ?QueryCacheProfile $qcp = null
) : ResultStatement { ) : ResultStatement {
$stmt = new Statement(parent::executeQuery($query, $params, $types, $qcp), $this); return new Statement(parent::executeQuery($query, $params, $types, $qcp), $this);
$stmt->setFetchMode($this->defaultFetchMode);
return $stmt;
} }
public function prepare(string $sql) : DriverStatement public function prepare(string $sql) : DriverStatement
{ {
$stmt = new Statement(parent::prepare($sql), $this); return new Statement(parent::prepare($sql), $this);
$stmt->setFetchMode($this->defaultFetchMode);
return $stmt;
} }
public function query(string $sql) : ResultStatement public function query(string $sql) : ResultStatement
{ {
$connection = $this->getWrappedConnection(); return new Statement(
$this->getWrappedConnection()
$stmt = $connection->query($sql); ->query($sql),
$stmt = new Statement($stmt, $this); $this
$stmt->setFetchMode($this->defaultFetchMode); );
return $stmt;
} }
} }
...@@ -6,10 +6,7 @@ namespace Doctrine\DBAL\Portability; ...@@ -6,10 +6,7 @@ namespace Doctrine\DBAL\Portability;
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\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
use function array_change_key_case; use function array_change_key_case;
use function assert; use function assert;
use function is_string; use function is_string;
...@@ -18,7 +15,7 @@ use function rtrim; ...@@ -18,7 +15,7 @@ use function rtrim;
/** /**
* Portability wrapper for a Statement. * Portability wrapper for a Statement.
*/ */
final class Statement implements IteratorAggregate, DriverStatement final class Statement implements DriverStatement
{ {
/** @var int */ /** @var int */
private $portability; private $portability;
...@@ -29,9 +26,6 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -29,9 +26,6 @@ final class Statement implements IteratorAggregate, DriverStatement
/** @var int|null */ /** @var int|null */
private $case; private $case;
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
/** /**
* Wraps <tt>Statement</tt> and applies portability measures. * Wraps <tt>Statement</tt> and applies portability measures.
* *
...@@ -76,8 +70,6 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -76,8 +70,6 @@ final class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @deprecated The error information is available via exceptions.
*/ */
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
...@@ -86,91 +78,124 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -86,91 +78,124 @@ final class Statement implements IteratorAggregate, DriverStatement
$this->stmt->execute($params); $this->stmt->execute($params);
} }
public function setFetchMode(int $fetchMode) : void /**
* {@inheritdoc}
*/
public function fetchNumeric()
{ {
$this->defaultFetchMode = $fetchMode; return $this->fixResult(
$this->stmt->fetchAssociative(),
$this->stmt->setFetchMode($fetchMode); false
);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchAssociative()
{ {
return new StatementIterator($this); return $this->fixResult(
$this->stmt->fetchAssociative(),
true
);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null) public function fetchOne()
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; $value = $this->stmt->fetchOne();
$row = $this->stmt->fetch($fetchMode); if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $value === '') {
$value = null;
$iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0; } elseif (($this->portability & Connection::PORTABILITY_RTRIM) !== 0 && is_string($value)) {
$fixCase = $this->case !== null $value = rtrim($value);
&& ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED) }
&& ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
$row = $this->fixRow($row, $iterateRow, $fixCase); return $value;
}
return $row; /**
* {@inheritdoc}
*/
public function fetchAllNumeric() : array
{
return $this->fixResultSet(
$this->stmt->fetchAllNumeric(),
false,
true
);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAllAssociative() : array
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; return $this->fixResultSet(
$this->stmt->fetchAllAssociative(),
true,
true
);
}
$rows = $this->stmt->fetchAll($fetchMode); /**
* {@inheritdoc}
*/
public function fetchColumn() : array
{
return $this->fixResultSet(
$this->stmt->fetchColumn(),
true,
false
);
}
/**
* @param mixed $result
*
* @return mixed
*/
private function fixResult($result, bool $fixCase)
{
$iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0; $iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
$fixCase = $this->case !== null $fixCase = $fixCase && $this->case !== null && ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
&& ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED)
&& ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
if (! $iterateRow && ! $fixCase) { return $this->fixRow($result, $iterateRow, $fixCase);
return $rows;
} }
if ($fetchMode === FetchMode::COLUMN) { /**
foreach ($rows as $num => $row) { * @param array<int,mixed> $resultSet
$rows[$num] = [$row]; *
} * @return array<int,mixed>
} */
private function fixResultSet(array $resultSet, bool $fixCase, bool $isArray) : array
{
$iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
$fixCase = $fixCase && $this->case !== null && ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
foreach ($rows as $num => $row) { if (! $iterateRow && ! $fixCase) {
$rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); return $resultSet;
} }
if ($fetchMode === FetchMode::COLUMN) { if (! $isArray) {
foreach ($rows as $num => $row) { foreach ($resultSet as $num => $value) {
$rows[$num] = $row[0]; $resultSet[$num] = [$value];
} }
} }
return $rows; foreach ($resultSet as $num => $row) {
$resultSet[$num] = $this->fixRow($row, $iterateRow, $fixCase);
} }
/** if (! $isArray) {
* {@inheritdoc} foreach ($resultSet as $num => $row) {
*/ $resultSet[$num] = $row[0];
public function fetchColumn() }
{
$value = $this->stmt->fetchColumn();
if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $value === '') {
$value = null;
} elseif (($this->portability & Connection::PORTABILITY_RTRIM) !== 0 && is_string($value)) {
$value = rtrim($value);
} }
return $value; return $resultSet;
} }
public function rowCount() : int public function rowCount() : int
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL;
use Doctrine\DBAL\Driver\ResultStatement as DriverResultStatement;
use Traversable;
/**
* DBAL-level ResultStatement interface.
*/
interface ResultStatement extends DriverResultStatement
{
/**
* Returns an iterator over the result set rows represented as numeric arrays.
*
* @return Traversable<int,array<int,mixed>>
*
* @throws DBALException
*/
public function iterateNumeric() : Traversable;
/**
* Returns an iterator over the result set rows represented as associative arrays.
*
* @return Traversable<int,array<string,mixed>>
*
* @throws DBALException
*/
public function iterateAssociative() : Traversable;
/**
* Returns an iterator over the values of the first column of the result set.
*
* @return Traversable<int,mixed>
*
* @throws DBALException
*/
public function iterateColumn() : Traversable;
}
...@@ -93,7 +93,7 @@ abstract class AbstractSchemaManager ...@@ -93,7 +93,7 @@ abstract class AbstractSchemaManager
{ {
$sql = $this->_platform->getListDatabasesSQL(); $sql = $this->_platform->getListDatabasesSQL();
$databases = $this->_conn->fetchAll($sql); $databases = $this->_conn->fetchAllAssociative($sql);
return $this->_getPortableDatabasesList($databases); return $this->_getPortableDatabasesList($databases);
} }
...@@ -107,7 +107,7 @@ abstract class AbstractSchemaManager ...@@ -107,7 +107,7 @@ abstract class AbstractSchemaManager
{ {
$sql = $this->_platform->getListNamespacesSQL(); $sql = $this->_platform->getListNamespacesSQL();
$namespaces = $this->_conn->fetchAll($sql); $namespaces = $this->_conn->fetchAllAssociative($sql);
return $this->getPortableNamespacesList($namespaces); return $this->getPortableNamespacesList($namespaces);
} }
...@@ -126,7 +126,7 @@ abstract class AbstractSchemaManager ...@@ -126,7 +126,7 @@ abstract class AbstractSchemaManager
$sql = $this->_platform->getListSequencesSQL($database); $sql = $this->_platform->getListSequencesSQL($database);
$sequences = $this->_conn->fetchAll($sql); $sequences = $this->_conn->fetchAllAssociative($sql);
return $this->filterAssetNames($this->_getPortableSequencesList($sequences)); return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
} }
...@@ -152,7 +152,7 @@ abstract class AbstractSchemaManager ...@@ -152,7 +152,7 @@ abstract class AbstractSchemaManager
$sql = $this->_platform->getListTableColumnsSQL($table, $database); $sql = $this->_platform->getListTableColumnsSQL($table, $database);
$tableColumns = $this->_conn->fetchAll($sql); $tableColumns = $this->_conn->fetchAllAssociative($sql);
return $this->_getPortableTableColumnList($table, $database, $tableColumns); return $this->_getPortableTableColumnList($table, $database, $tableColumns);
} }
...@@ -168,7 +168,7 @@ abstract class AbstractSchemaManager ...@@ -168,7 +168,7 @@ abstract class AbstractSchemaManager
{ {
$sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
$tableIndexes = $this->_conn->fetchAll($sql); $tableIndexes = $this->_conn->fetchAllAssociative($sql);
return $this->_getPortableTableIndexesList($tableIndexes, $table); return $this->_getPortableTableIndexesList($tableIndexes, $table);
} }
...@@ -199,7 +199,7 @@ abstract class AbstractSchemaManager ...@@ -199,7 +199,7 @@ abstract class AbstractSchemaManager
{ {
$sql = $this->_platform->getListTablesSQL(); $sql = $this->_platform->getListTablesSQL();
$tables = $this->_conn->fetchAll($sql); $tables = $this->_conn->fetchAllAssociative($sql);
$tableNames = $this->_getPortableTablesList($tables); $tableNames = $this->_getPortableTablesList($tables);
return $this->filterAssetNames($tableNames); return $this->filterAssetNames($tableNames);
...@@ -267,7 +267,7 @@ abstract class AbstractSchemaManager ...@@ -267,7 +267,7 @@ abstract class AbstractSchemaManager
); );
$sql = $this->_platform->getListViewsSQL($database); $sql = $this->_platform->getListViewsSQL($database);
$views = $this->_conn->fetchAll($sql); $views = $this->_conn->fetchAllAssociative($sql);
return $this->_getPortableViewsList($views); return $this->_getPortableViewsList($views);
} }
...@@ -284,7 +284,7 @@ abstract class AbstractSchemaManager ...@@ -284,7 +284,7 @@ abstract class AbstractSchemaManager
} }
$sql = $this->_platform->getListTableForeignKeysSQL($table, $database); $sql = $this->_platform->getListTableForeignKeysSQL($table, $database);
$tableForeignKeys = $this->_conn->fetchAll($sql); $tableForeignKeys = $this->_conn->fetchAllAssociative($sql);
return $this->_getPortableTableForeignKeysList($tableForeignKeys); return $this->_getPortableTableForeignKeysList($tableForeignKeys);
} }
...@@ -553,7 +553,7 @@ abstract class AbstractSchemaManager ...@@ -553,7 +553,7 @@ abstract class AbstractSchemaManager
/** /**
* Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition. * Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition.
* *
* @param array<int, array<int, mixed>> $namespaces The list of namespace names in the native DBMS data definition. * @param array<int, array<string, mixed>> $namespaces The list of namespace names in the native DBMS data definition.
* *
* @return array<int, string> * @return array<int, string>
*/ */
...@@ -581,7 +581,7 @@ abstract class AbstractSchemaManager ...@@ -581,7 +581,7 @@ abstract class AbstractSchemaManager
/** /**
* Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition. * Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition.
* *
* @param array<string|int, mixed> $namespace The native DBMS namespace definition. * @param array<string, mixed> $namespace The native DBMS namespace definition.
*/ */
protected function getPortableNamespaceDefinition(array $namespace) : string protected function getPortableNamespaceDefinition(array $namespace) : string
{ {
......
...@@ -30,7 +30,7 @@ class DB2SchemaManager extends AbstractSchemaManager ...@@ -30,7 +30,7 @@ class DB2SchemaManager extends AbstractSchemaManager
{ {
$sql = $this->_platform->getListTablesSQL() . ' AND CREATOR = CURRENT_USER'; $sql = $this->_platform->getListTablesSQL() . ' AND CREATOR = CURRENT_USER';
$tables = $this->_conn->fetchAll($sql); $tables = $this->_conn->fetchAllAssociative($sql);
return $this->filterAssetNames($this->_getPortableTablesList($tables)); return $this->filterAssetNames($this->_getPortableTablesList($tables));
} }
...@@ -198,7 +198,7 @@ class DB2SchemaManager extends AbstractSchemaManager ...@@ -198,7 +198,7 @@ class DB2SchemaManager extends AbstractSchemaManager
assert($platform instanceof DB2Platform); assert($platform instanceof DB2Platform);
$sql = $platform->getListTableCommentsSQL($tableName); $sql = $platform->getListTableCommentsSQL($tableName);
$tableOptions = $this->_conn->fetchAssoc($sql); $tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions !== false) { if ($tableOptions !== false) {
$table->addOption('comment', $tableOptions['REMARKS']); $table->addOption('comment', $tableOptions['REMARKS']);
......
...@@ -311,7 +311,7 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -311,7 +311,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
assert($platform instanceof MySqlPlatform); assert($platform instanceof MySqlPlatform);
$sql = $platform->getListTableMetadataSQL($tableName); $sql = $platform->getListTableMetadataSQL($tableName);
$tableOptions = $this->_conn->fetchAssoc($sql); $tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions === false) { if ($tableOptions === false) {
return $table; return $table;
......
...@@ -344,7 +344,7 @@ WHERE ...@@ -344,7 +344,7 @@ WHERE
AND p.addr(+) = s.paddr AND p.addr(+) = s.paddr
SQL; SQL;
$activeUserSessions = $this->_conn->fetchAll($sql, [strtoupper($user)]); $activeUserSessions = $this->_conn->fetchAllAssociative($sql, [strtoupper($user)]);
foreach ($activeUserSessions as $activeUserSession) { foreach ($activeUserSessions as $activeUserSession) {
$activeUserSession = array_change_key_case($activeUserSession, CASE_LOWER); $activeUserSession = array_change_key_case($activeUserSession, CASE_LOWER);
...@@ -367,7 +367,7 @@ SQL; ...@@ -367,7 +367,7 @@ SQL;
assert($platform instanceof OraclePlatform); assert($platform instanceof OraclePlatform);
$sql = $platform->getListTableCommentsSQL($tableName); $sql = $platform->getListTableCommentsSQL($tableName);
$tableOptions = $this->_conn->fetchAssoc($sql); $tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions !== false) { if ($tableOptions !== false) {
$table->addOption('comment', $tableOptions['COMMENTS']); $table->addOption('comment', $tableOptions['COMMENTS']);
......
...@@ -5,7 +5,6 @@ declare(strict_types=1); ...@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Schema; namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Exception\DriverException; use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
...@@ -42,9 +41,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -42,9 +41,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
*/ */
public function getSchemaNames() : array public function getSchemaNames() : array
{ {
$statement = $this->_conn->executeQuery("SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"); return $this->_conn->fetchColumn("SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'");
return $statement->fetchAll(FetchMode::COLUMN);
} }
/** /**
...@@ -57,7 +54,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -57,7 +54,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
public function getSchemaSearchPaths() : array public function getSchemaSearchPaths() : array
{ {
$params = $this->_conn->getParams(); $params = $this->_conn->getParams();
$schema = explode(',', $this->_conn->fetchColumn('SHOW search_path')); $schema = explode(',', $this->_conn->fetchOne('SHOW search_path'));
if (isset($params['user'])) { if (isset($params['user'])) {
$schema = str_replace('"$user"', $params['user'], $schema); $schema = str_replace('"$user"', $params['user'], $schema);
...@@ -221,8 +218,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -221,8 +218,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
implode(' ,', $colNumbers) implode(' ,', $colNumbers)
); );
$stmt = $this->_conn->executeQuery($columnNameSql); $indexColumns = $this->_conn->fetchAllAssociative($columnNameSql);
$indexColumns = $stmt->fetchAll();
// required for getting the order of the columns right. // required for getting the order of the columns right.
foreach ($colNumbers as $colNum) { foreach ($colNumbers as $colNum) {
...@@ -300,7 +296,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -300,7 +296,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
if (! isset($sequence['increment_by'], $sequence['min_value'])) { if (! isset($sequence['increment_by'], $sequence['min_value'])) {
/** @var string[] $data */ /** @var string[] $data */
$data = $this->_conn->fetchAssoc('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName)); $data = $this->_conn->fetchAssociative('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
$sequence += $data; $sequence += $data;
} }
...@@ -518,7 +514,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -518,7 +514,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
assert($platform instanceof PostgreSQL94Platform); assert($platform instanceof PostgreSQL94Platform);
$sql = $platform->getListTableMetadataSQL($tableName); $sql = $platform->getListTableMetadataSQL($tableName);
$tableOptions = $this->_conn->fetchAssoc($sql); $tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions !== false) { if ($tableOptions !== false) {
$table->addOption('comment', $tableOptions['table_comment']); $table->addOption('comment', $tableOptions['table_comment']);
......
...@@ -261,7 +261,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -261,7 +261,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
$sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
try { try {
$tableIndexes = $this->_conn->fetchAll($sql); $tableIndexes = $this->_conn->fetchAllAssociative($sql);
} catch (PDOException $e) { } catch (PDOException $e) {
if ($e->getCode() === 'IMSSP') { if ($e->getCode() === 'IMSSP') {
return []; return [];
...@@ -284,7 +284,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -284,7 +284,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
if (count($tableDiff->removedColumns) > 0) { if (count($tableDiff->removedColumns) > 0) {
foreach ($tableDiff->removedColumns as $col) { foreach ($tableDiff->removedColumns as $col) {
$columnConstraintSql = $this->getColumnConstraintSQL($tableDiff->name, $col->getName()); $columnConstraintSql = $this->getColumnConstraintSQL($tableDiff->name, $col->getName());
foreach ($this->_conn->fetchAll($columnConstraintSql) as $constraint) { foreach ($this->_conn->fetchAllAssociative($columnConstraintSql) as $constraint) {
$this->_conn->exec( $this->_conn->exec(
sprintf( sprintf(
'ALTER TABLE %s DROP CONSTRAINT %s', 'ALTER TABLE %s DROP CONSTRAINT %s',
...@@ -338,7 +338,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -338,7 +338,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
assert($platform instanceof SQLServer2012Platform); assert($platform instanceof SQLServer2012Platform);
$sql = $platform->getListTableMetadataSQL($tableName); $sql = $platform->getListTableMetadataSQL($tableName);
$tableOptions = $this->_conn->fetchAssoc($sql); $tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions !== false) { if ($tableOptions !== false) {
$table->addOption('comment', $tableOptions['table_comment']); $table->addOption('comment', $tableOptions['table_comment']);
......
...@@ -5,7 +5,6 @@ declare(strict_types=1); ...@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Schema; namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Types\StringType; use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Types\TextType; use Doctrine\DBAL\Types\TextType;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
...@@ -121,7 +120,7 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -121,7 +120,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
} }
$sql = $this->_platform->getListTableForeignKeysSQL($table, $database); $sql = $this->_platform->getListTableForeignKeysSQL($table, $database);
$tableForeignKeys = $this->_conn->fetchAll($sql); $tableForeignKeys = $this->_conn->fetchAllAssociative($sql);
if (! empty($tableForeignKeys)) { if (! empty($tableForeignKeys)) {
$createSql = $this->getCreateTableSQL($table); $createSql = $this->getCreateTableSQL($table);
...@@ -175,11 +174,10 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -175,11 +174,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
$indexBuffer = []; $indexBuffer = [];
// fetch primary // fetch primary
$stmt = $this->_conn->executeQuery(sprintf( $indexArray = $this->_conn->fetchAllAssociative(sprintf(
'PRAGMA TABLE_INFO (%s)', 'PRAGMA TABLE_INFO (%s)',
$this->_conn->quote($tableName) $this->_conn->quote($tableName)
)); ));
$indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
usort($indexArray, static function ($a, $b) { usort($indexArray, static function ($a, $b) {
if ($a['pk'] === $b['pk']) { if ($a['pk'] === $b['pk']) {
...@@ -214,11 +212,10 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -214,11 +212,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
$idx['primary'] = false; $idx['primary'] = false;
$idx['non_unique'] = ! $tableIndex['unique']; $idx['non_unique'] = ! $tableIndex['unique'];
$stmt = $this->_conn->executeQuery(sprintf( $indexArray = $this->_conn->fetchAllAssociative(sprintf(
'PRAGMA INDEX_INFO (%s)', 'PRAGMA INDEX_INFO (%s)',
$this->_conn->quote($keyName) $this->_conn->quote($keyName)
)); ));
$indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
foreach ($indexArray as $indexColumnRow) { foreach ($indexArray as $indexColumnRow) {
$idx['column_name'] = $indexColumnRow['name']; $idx['column_name'] = $indexColumnRow['name'];
...@@ -481,7 +478,7 @@ CREATE\sTABLE # Match "CREATE TABLE" ...@@ -481,7 +478,7 @@ CREATE\sTABLE # Match "CREATE TABLE"
private function getCreateTableSQL(string $table) : string private function getCreateTableSQL(string $table) : string
{ {
$sql = $this->_conn->fetchColumn( $sql = $this->_conn->fetchOne(
<<<'SQL' <<<'SQL'
SELECT sql SELECT sql
FROM ( FROM (
......
...@@ -8,15 +8,15 @@ use Doctrine\DBAL\Driver\DriverException; ...@@ -8,15 +8,15 @@ use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use IteratorAggregate;
use Throwable; use Throwable;
use Traversable;
use function is_string; 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 class Statement implements DriverStatement, ResultStatement
{ {
/** /**
* The SQL statement. * The SQL statement.
...@@ -180,43 +180,140 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -180,43 +180,140 @@ class Statement implements IteratorAggregate, DriverStatement
return $this->stmt->columnCount(); return $this->stmt->columnCount();
} }
public function setFetchMode(int $fetchMode) : void /**
* {@inheritdoc}
*
* @throws DBALException
*/
public function fetchNumeric()
{ {
$this->stmt->setFetchMode($fetchMode); try {
return $this->stmt->fetchNumeric();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
} }
/** /**
* Required by interface IteratorAggregate. * {@inheritdoc}
* *
* @throws DBALException
*/
public function fetchAssociative()
{
try {
return $this->stmt->fetchAssociative();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
}
/**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getIterator() public function fetchOne()
{ {
return $this->stmt; try {
return $this->stmt->fetchOne();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @throws DBALException
*/ */
public function fetch(?int $fetchMode = null) public function fetchAllNumeric() : array
{ {
return $this->stmt->fetch($fetchMode); try {
return $this->stmt->fetchAllNumeric();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*
* @throws DBALException
*/ */
public function fetchAll(?int $fetchMode = null) : array public function fetchAllAssociative() : array
{ {
return $this->stmt->fetchAll($fetchMode); try {
return $this->stmt->fetchAllAssociative();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
} }
/** /**
* {@inheritDoc} * {@inheritdoc}
*
* @throws DBALException
*/ */
public function fetchColumn() public function fetchColumn() : array
{ {
try {
return $this->stmt->fetchColumn(); return $this->stmt->fetchColumn();
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
}
/**
* {@inheritDoc}
*
* @return Traversable<int,array<int,mixed>>
*
* @throws DBALException
*/
public function iterateNumeric() : Traversable
{
try {
while (($row = $this->stmt->fetchNumeric()) !== false) {
yield $row;
}
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
}
/**
* {@inheritDoc}
*
* @return Traversable<int,array<string,mixed>>
*
* @throws DBALException
*/
public function iterateAssociative() : Traversable
{
try {
while (($row = $this->stmt->fetchAssociative()) !== false) {
yield $row;
}
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
}
/**
* {@inheritDoc}
*
* @return Traversable<int,mixed>
*
* @throws DBALException
*/
public function iterateColumn() : Traversable
{
try {
while (($value = $this->stmt->fetchOne()) !== false) {
yield $value;
}
} catch (DriverException $e) {
throw DBALException::driverException($this->conn->getDriver(), $e);
}
} }
/** /**
......
...@@ -88,7 +88,7 @@ EOT ...@@ -88,7 +88,7 @@ EOT
assert(is_bool($forceFetch)); assert(is_bool($forceFetch));
if (stripos($sql, 'select') === 0 || $forceFetch) { if (stripos($sql, 'select') === 0 || $forceFetch) {
$resultSet = $conn->fetchAll($sql); $resultSet = $conn->fetchAllAssociative($sql);
} else { } else {
$resultSet = $conn->executeUpdate($sql); $resultSet = $conn->executeUpdate($sql);
} }
......
...@@ -5,11 +5,8 @@ declare(strict_types=1); ...@@ -5,11 +5,8 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Cache; namespace Doctrine\DBAL\Tests\Cache;
use Doctrine\DBAL\Cache\ArrayStatement; use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function array_values; use function array_values;
use function iterator_to_array;
class ArrayStatementTest extends TestCase class ArrayStatementTest extends TestCase
{ {
...@@ -50,79 +47,33 @@ class ArrayStatementTest extends TestCase ...@@ -50,79 +47,33 @@ class ArrayStatementTest extends TestCase
self::assertSame(2, $statement->rowCount()); self::assertSame(2, $statement->rowCount());
} }
public function testSetFetchMode() : void public function testFetchAssociative() : void
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
$statement->setFetchMode(FetchMode::ASSOCIATIVE); self::assertSame($this->users[0], $statement->fetchAssociative());
self::assertSame($this->users[0], $statement->fetch());
}
public function testGetIterator() : void
{
$statement = $this->createTestArrayStatement();
$statement->setFetchMode(FetchMode::ASSOCIATIVE);
self::assertSame($this->users, iterator_to_array($statement->getIterator()));
} }
public function testFetchModeAssociative() : void public function testFetchNumeric() : void
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
self::assertSame($this->users[0], $statement->fetch(FetchMode::ASSOCIATIVE)); self::assertSame(array_values($this->users[0]), $statement->fetchNumeric());
} }
public function testFetchModeNumeric() : void public function testFetchOne() : void
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
self::assertSame(array_values($this->users[0]), $statement->fetch(FetchMode::NUMERIC)); self::assertSame('jwage', $statement->fetchOne());
} self::assertSame('romanb', $statement->fetchOne());
public function testFetchModeMixed() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame([
'username' => 'jwage',
'active' => true,
0 => 'jwage',
1 => true,
], $statement->fetch(FetchMode::MIXED));
}
public function testFetchModeColumn() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame('jwage', $statement->fetch(FetchMode::COLUMN));
}
public function testFetchThrowsInvalidArgumentException() : void
{
$statement = $this->createTestArrayStatement();
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid fetch mode given for fetching result, 9999 given.');
$statement->fetch(9999);
} }
public function testFetchAll() : void public function testFetchAll() : void
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
self::assertSame($this->users, $statement->fetchAll(FetchMode::ASSOCIATIVE)); self::assertSame($this->users, $statement->fetchAllAssociative());
}
public function testFetchColumn() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame('jwage', $statement->fetchColumn());
self::assertSame('romanb', $statement->fetchColumn());
} }
private function createTestArrayStatement() : ArrayStatement private function createTestArrayStatement() : ArrayStatement
......
...@@ -19,7 +19,6 @@ use Doctrine\DBAL\Driver\Statement; ...@@ -19,7 +19,6 @@ use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Events; use Doctrine\DBAL\Events;
use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Logging\DebugStack; use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
...@@ -494,7 +493,7 @@ class ConnectionTest extends TestCase ...@@ -494,7 +493,7 @@ class ConnectionTest extends TestCase
); );
} }
public function testFetchAssoc() : void public function testFetchAssociative() : void
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
$params = [666]; $params = [666];
...@@ -512,8 +511,7 @@ class ConnectionTest extends TestCase ...@@ -512,8 +511,7 @@ class ConnectionTest extends TestCase
$driverStatementMock = $this->createMock(Statement::class); $driverStatementMock = $this->createMock(Statement::class);
$driverStatementMock->expects(self::once()) $driverStatementMock->expects(self::once())
->method('fetch') ->method('fetchAssociative')
->with(FetchMode::ASSOCIATIVE)
->will(self::returnValue($result)); ->will(self::returnValue($result));
$conn = $this->getMockBuilder(Connection::class) $conn = $this->getMockBuilder(Connection::class)
...@@ -526,10 +524,10 @@ class ConnectionTest extends TestCase ...@@ -526,10 +524,10 @@ class ConnectionTest extends TestCase
->with($statement, $params, $types) ->with($statement, $params, $types)
->will(self::returnValue($driverStatementMock)); ->will(self::returnValue($driverStatementMock));
self::assertSame($result, $conn->fetchAssoc($statement, $params, $types)); self::assertSame($result, $conn->fetchAssociative($statement, $params, $types));
} }
public function testFetchArray() : void public function testFetchNumeric() : void
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
$params = [666]; $params = [666];
...@@ -547,8 +545,7 @@ class ConnectionTest extends TestCase ...@@ -547,8 +545,7 @@ class ConnectionTest extends TestCase
$driverStatementMock = $this->createMock(Statement::class); $driverStatementMock = $this->createMock(Statement::class);
$driverStatementMock->expects(self::once()) $driverStatementMock->expects(self::once())
->method('fetch') ->method('fetchNumeric')
->with(FetchMode::NUMERIC)
->will(self::returnValue($result)); ->will(self::returnValue($result));
$conn = $this->getMockBuilder(Connection::class) $conn = $this->getMockBuilder(Connection::class)
...@@ -561,10 +558,10 @@ class ConnectionTest extends TestCase ...@@ -561,10 +558,10 @@ class ConnectionTest extends TestCase
->with($statement, $params, $types) ->with($statement, $params, $types)
->will(self::returnValue($driverStatementMock)); ->will(self::returnValue($driverStatementMock));
self::assertSame($result, $conn->fetchArray($statement, $params, $types)); self::assertSame($result, $conn->fetchNumeric($statement, $params, $types));
} }
public function testFetchColumn() : void public function testFetchOne() : void
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
$params = [666]; $params = [666];
...@@ -582,7 +579,7 @@ class ConnectionTest extends TestCase ...@@ -582,7 +579,7 @@ class ConnectionTest extends TestCase
$driverStatementMock = $this->createMock(Statement::class); $driverStatementMock = $this->createMock(Statement::class);
$driverStatementMock->expects(self::once()) $driverStatementMock->expects(self::once())
->method('fetchColumn') ->method('fetchOne')
->will(self::returnValue($result)); ->will(self::returnValue($result));
$conn = $this->getMockBuilder(Connection::class) $conn = $this->getMockBuilder(Connection::class)
...@@ -595,10 +592,10 @@ class ConnectionTest extends TestCase ...@@ -595,10 +592,10 @@ class ConnectionTest extends TestCase
->with($statement, $params, $types) ->with($statement, $params, $types)
->will(self::returnValue($driverStatementMock)); ->will(self::returnValue($driverStatementMock));
self::assertSame($result, $conn->fetchColumn($statement, $params, $types)); self::assertSame($result, $conn->fetchOne($statement, $params, $types));
} }
public function testFetchAll() : void public function testFetchAllAssociative() : void
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
$params = [666]; $params = [666];
...@@ -616,7 +613,7 @@ class ConnectionTest extends TestCase ...@@ -616,7 +613,7 @@ class ConnectionTest extends TestCase
$driverStatementMock = $this->createMock(Statement::class); $driverStatementMock = $this->createMock(Statement::class);
$driverStatementMock->expects(self::once()) $driverStatementMock->expects(self::once())
->method('fetchAll') ->method('fetchAllAssociative')
->will(self::returnValue($result)); ->will(self::returnValue($result));
$conn = $this->getMockBuilder(Connection::class) $conn = $this->getMockBuilder(Connection::class)
...@@ -629,7 +626,7 @@ class ConnectionTest extends TestCase ...@@ -629,7 +626,7 @@ class ConnectionTest extends TestCase
->with($statement, $params, $types) ->with($statement, $params, $types)
->will(self::returnValue($driverStatementMock)); ->will(self::returnValue($driverStatementMock));
self::assertSame($result, $conn->fetchAll($statement, $params, $types)); self::assertSame($result, $conn->fetchAllAssociative($statement, $params, $types));
} }
public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() : void public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() : void
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Driver;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Traversable;
class StatementIteratorTest extends TestCase
{
public function testIteratorIterationCallsFetchOncePerStep() : void
{
$stmt = $this->createMock(Statement::class);
$calls = 0;
$this->configureStatement($stmt, $calls);
$stmtIterator = new StatementIterator($stmt);
$this->assertIterationCallsFetchOncePerStep($stmtIterator, $calls);
}
private function configureStatement(MockObject $stmt, int &$calls) : void
{
$values = ['foo', '', 'bar', '0', 'baz', 0, 'qux', null, 'quz', false, 'impossible'];
$calls = 0;
$stmt->expects(self::exactly(10))
->method('fetch')
->willReturnCallback(static function () use ($values, &$calls) {
$value = $values[$calls];
$calls++;
return $value;
});
}
/**
* @param Traversable<int, mixed> $iterator
*/
private function assertIterationCallsFetchOncePerStep(Traversable $iterator, int &$calls) : void
{
foreach ($iterator as $i => $_) {
self::assertEquals($i + 1, $calls);
}
}
}
...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Tests\Functional; ...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Tests\Functional;
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver; use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver; use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
...@@ -160,7 +159,7 @@ class BlobTest extends FunctionalTestCase ...@@ -160,7 +159,7 @@ class BlobTest extends FunctionalTestCase
private function assertBlobContains(string $text) : void private function assertBlobContains(string $text) : void
{ {
$rows = $this->connection->query('SELECT blobfield FROM blob_table')->fetchAll(FetchMode::COLUMN); $rows = $this->connection->query('SELECT blobfield FROM blob_table')->fetchColumn();
self::assertCount(1, $rows); self::assertCount(1, $rows);
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional\Connection;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Tests\TestUtil;
use function iterator_to_array;
class FetchTest extends FunctionalTestCase
{
/** @var string */
private $query;
public function setUp() : void
{
parent::setUp();
$this->query = TestUtil::generateResultSetQuery([
[
'a' => 'foo',
'b' => 1,
],
[
'a' => 'bar',
'b' => 2,
],
[
'a' => 'baz',
'b' => 3,
],
], $this->connection->getDatabasePlatform());
}
public function testFetchNumeric() : void
{
self::assertEquals(['foo', 1], $this->connection->fetchNumeric($this->query));
}
public function testFetchOne() : void
{
self::assertEquals('foo', $this->connection->fetchOne($this->query));
}
public function testFetchAssociative() : void
{
self::assertEquals([
'a' => 'foo',
'b' => 1,
], $this->connection->fetchAssociative($this->query));
}
public function testFetchAllNumeric() : void
{
self::assertEquals([
['foo', 1],
['bar', 2],
['baz', 3],
], $this->connection->fetchAllNumeric($this->query));
}
public function testFetchAllAssociative() : void
{
self::assertEquals([
[
'a' => 'foo',
'b' => 1,
],
[
'a' => 'bar',
'b' => 2,
],
[
'a' => 'baz',
'b' => 3,
],
], $this->connection->fetchAllAssociative($this->query));
}
public function testIterateNumeric() : void
{
self::assertEquals([
['foo', 1],
['bar', 2],
['baz', 3],
], iterator_to_array($this->connection->iterateNumeric($this->query)));
}
public function testIterateAssociative() : void
{
self::assertEquals([
[
'a' => 'foo',
'b' => 1,
],
[
'a' => 'bar',
'b' => 2,
],
[
'a' => 'baz',
'b' => 3,
],
], iterator_to_array($this->connection->iterateAssociative($this->query)));
}
public function testIterateColumn() : void
{
self::assertEquals([
'foo',
'bar',
'baz',
], iterator_to_array($this->connection->iterateColumn($this->query)));
}
}
...@@ -107,7 +107,7 @@ class ConnectionTest extends FunctionalTestCase ...@@ -107,7 +107,7 @@ class ConnectionTest extends FunctionalTestCase
$connection->executeQuery('insert into test_nesting values (33)'); $connection->executeQuery('insert into test_nesting values (33)');
$connection->rollBack(); $connection->rollBack();
self::assertEquals(0, $connection->fetchColumn('select count(*) from test_nesting')); self::assertEquals(0, $connection->fetchOne('select count(*) from test_nesting'));
} }
public function testTransactionNestingBehaviorWithSavepoints() : void public function testTransactionNestingBehaviorWithSavepoints() : void
......
This diff is collapsed.
...@@ -35,7 +35,7 @@ class StatementTest extends FunctionalTestCase ...@@ -35,7 +35,7 @@ class StatementTest extends FunctionalTestCase
{ {
self::assertEquals( self::assertEquals(
$expected, $expected,
$this->connection->executeQuery($query, $params)->fetch() $this->connection->executeQuery($query, $params)->fetchAssociative()
); );
} }
...@@ -54,7 +54,7 @@ class StatementTest extends FunctionalTestCase ...@@ -54,7 +54,7 @@ class StatementTest extends FunctionalTestCase
self::assertEquals( self::assertEquals(
$expected, $expected,
$stmt->fetch() $stmt->fetchAssociative()
); );
} }
......
...@@ -87,7 +87,7 @@ class DriverTest extends AbstractDriverTest ...@@ -87,7 +87,7 @@ class DriverTest extends AbstractDriverTest
$hash = microtime(true); // required to identify the record in the results uniquely $hash = microtime(true); // required to identify the record in the results uniquely
$sql = sprintf('SELECT * FROM pg_stat_activity WHERE %d = %d', $hash, $hash); $sql = sprintf('SELECT * FROM pg_stat_activity WHERE %d = %d', $hash, $hash);
$statement = $connection->query($sql); $statement = $connection->query($sql);
$records = $statement->fetchAll(); $records = $statement->fetchAllAssociative();
foreach ($records as $record) { foreach ($records as $record) {
// The query column is named "current_query" on PostgreSQL < 9.2 // The query column is named "current_query" on PostgreSQL < 9.2
......
...@@ -5,7 +5,6 @@ declare(strict_types=1); ...@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional\Driver; namespace Doctrine\DBAL\Tests\Functional\Driver;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
use function extension_loaded; use function extension_loaded;
...@@ -46,7 +45,7 @@ class PDOPgsqlConnectionTest extends FunctionalTestCase ...@@ -46,7 +45,7 @@ class PDOPgsqlConnectionTest extends FunctionalTestCase
self::assertEquals( self::assertEquals(
$charset, $charset,
$connection->query('SHOW client_encoding') $connection->query('SHOW client_encoding')
->fetch(FetchMode::COLUMN) ->fetchOne()
); );
} }
......
...@@ -59,7 +59,7 @@ class DriverTest extends AbstractDriverTest ...@@ -59,7 +59,7 @@ class DriverTest extends AbstractDriverTest
public function testConnectionOptions() : void public function testConnectionOptions() : void
{ {
$connection = $this->getConnection(['APP' => 'APP_NAME']); $connection = $this->getConnection(['APP' => 'APP_NAME']);
$result = $connection->query('SELECT APP_NAME()')->fetchColumn(); $result = $connection->query('SELECT APP_NAME()')->fetchOne();
self::assertSame('APP_NAME', $result); self::assertSame('APP_NAME', $result);
} }
......
...@@ -25,6 +25,6 @@ final class LikeWildcardsEscapingTest extends FunctionalTestCase ...@@ -25,6 +25,6 @@ final class LikeWildcardsEscapingTest extends FunctionalTestCase
) )
); );
$stmt->execute(); $stmt->execute();
self::assertTrue((bool) $stmt->fetchColumn()); self::assertTrue((bool) $stmt->fetchOne());
} }
} }
...@@ -95,7 +95,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase ...@@ -95,7 +95,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase
self::assertFalse($conn->isConnectedToMaster()); self::assertFalse($conn->isConnectedToMaster());
$clientCharset = $conn->fetchColumn('select @@character_set_client as c'); $clientCharset = $conn->fetchOne('select @@character_set_client as c');
self::assertSame( self::assertSame(
$charset, $charset,
...@@ -120,7 +120,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase ...@@ -120,7 +120,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase
$conn = $this->createMasterSlaveConnection(); $conn = $this->createMasterSlaveConnection();
$sql = 'SELECT count(*) as num FROM master_slave_table'; $sql = 'SELECT count(*) as num FROM master_slave_table';
$data = $conn->fetchAll($sql); $data = $conn->fetchAllAssociative($sql);
$data[0] = array_change_key_case($data[0], CASE_LOWER); $data[0] = array_change_key_case($data[0], CASE_LOWER);
self::assertEquals(1, $data[0]['num']); self::assertEquals(1, $data[0]['num']);
...@@ -135,7 +135,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase ...@@ -135,7 +135,7 @@ class MasterSlaveConnectionTest extends FunctionalTestCase
self::assertTrue($conn->isConnectedToMaster()); self::assertTrue($conn->isConnectedToMaster());
$sql = 'SELECT count(*) as num FROM master_slave_table'; $sql = 'SELECT count(*) as num FROM master_slave_table';
$data = $conn->fetchAll($sql); $data = $conn->fetchAllAssociative($sql);
$data[0] = array_change_key_case($data[0], CASE_LOWER); $data[0] = array_change_key_case($data[0], CASE_LOWER);
self::assertEquals(2, $data[0]['num']); self::assertEquals(2, $data[0]['num']);
...@@ -208,9 +208,8 @@ class MasterSlaveConnectionTest extends FunctionalTestCase ...@@ -208,9 +208,8 @@ class MasterSlaveConnectionTest extends FunctionalTestCase
//Query must be executed only on Master //Query must be executed only on Master
self::assertTrue($conn->isConnectedToMaster()); self::assertTrue($conn->isConnectedToMaster());
$data = $statement->fetchAll(); $data = $statement->fetchAllAssociative();
//Default fetchmode is FetchMode::ASSOCIATIVE
self::assertArrayHasKey(0, $data); self::assertArrayHasKey(0, $data);
self::assertArrayHasKey('num', $data[0]); self::assertArrayHasKey('num', $data[0]);
...@@ -233,9 +232,8 @@ class MasterSlaveConnectionTest extends FunctionalTestCase ...@@ -233,9 +232,8 @@ class MasterSlaveConnectionTest extends FunctionalTestCase
//Query must be executed only on Master, even when we connect to the slave //Query must be executed only on Master, even when we connect to the slave
self::assertTrue($conn->isConnectedToMaster()); self::assertTrue($conn->isConnectedToMaster());
$data = $statement->fetchAll(); $data = $statement->fetchAllAssociative();
//Default fetchmode is FetchMode::ASSOCIATIVE
self::assertArrayHasKey(0, $data); self::assertArrayHasKey(0, $data);
self::assertArrayHasKey('num', $data[0]); self::assertArrayHasKey('num', $data[0]);
......
...@@ -171,7 +171,7 @@ SQL; ...@@ -171,7 +171,7 @@ SQL;
{ {
$p = $this->connection->getDatabasePlatform(); $p = $this->connection->getDatabasePlatform();
$data = []; $data = [];
foreach ($this->connection->fetchAll($p->modifyLimitQuery($sql, $limit, $offset)) as $row) { foreach ($this->connection->fetchAllAssociative($p->modifyLimitQuery($sql, $limit, $offset)) as $row) {
$row = array_change_key_case($row, CASE_LOWER); $row = array_change_key_case($row, CASE_LOWER);
$data[] = $row['test_int']; $data[] = $row['test_int'];
} }
......
...@@ -5,7 +5,6 @@ declare(strict_types=1); ...@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional; namespace Doctrine\DBAL\Tests\Functional;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
...@@ -215,7 +214,7 @@ class NamedParametersTest extends FunctionalTestCase ...@@ -215,7 +214,7 @@ class NamedParametersTest extends FunctionalTestCase
public function testTicket(string $query, array $params, array $types, array $expected) : void public function testTicket(string $query, array $params, array $types, array $expected) : void
{ {
$stmt = $this->connection->executeQuery($query, $params, $types); $stmt = $this->connection->executeQuery($query, $params, $types);
$result = $stmt->fetchAll(FetchMode::ASSOCIATIVE); $result = $stmt->fetchAllAssociative();
foreach ($result as $k => $v) { foreach ($result as $k => $v) {
$result[$k] = array_change_key_case($v, CASE_LOWER); $result[$k] = array_change_key_case($v, CASE_LOWER);
......
...@@ -113,7 +113,7 @@ abstract class ColumnTest extends FunctionalTestCase ...@@ -113,7 +113,7 @@ abstract class ColumnTest extends FunctionalTestCase
self::assertSame(1, $this->connection->insert('column_test', ['val' => $value], [$bindType])); self::assertSame(1, $this->connection->insert('column_test', ['val' => $value], [$bindType]));
self::assertSame($value, Type::getType($type)->convertToPHPValue( self::assertSame($value, Type::getType($type)->convertToPHPValue(
$this->connection->fetchColumn('SELECT val FROM column_test'), $this->connection->fetchOne('SELECT val FROM column_test'),
$this->connection->getDatabasePlatform() $this->connection->getDatabasePlatform()
)); ));
} }
......
...@@ -28,7 +28,7 @@ class DateExpressionTest extends FunctionalTestCase ...@@ -28,7 +28,7 @@ class DateExpressionTest extends FunctionalTestCase
$platform = $this->connection->getDatabasePlatform(); $platform = $this->connection->getDatabasePlatform();
$sql = sprintf('SELECT %s FROM date_expr_test', $platform->getDateDiffExpression('date1', 'date2')); $sql = sprintf('SELECT %s FROM date_expr_test', $platform->getDateDiffExpression('date1', 'date2'));
$diff = $this->connection->query($sql)->fetchColumn(); $diff = $this->connection->query($sql)->fetchOne();
self::assertEquals($expected, $diff); self::assertEquals($expected, $diff);
} }
......
...@@ -4,7 +4,6 @@ declare(strict_types=1); ...@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional\Platform; namespace Doctrine\DBAL\Tests\Functional\Platform;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform; use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\OraclePlatform;
...@@ -71,7 +70,7 @@ class DefaultExpressionTest extends FunctionalTestCase ...@@ -71,7 +70,7 @@ class DefaultExpressionTest extends FunctionalTestCase
[$actualValue, $defaultValue] = $this->connection->query( [$actualValue, $defaultValue] = $this->connection->query(
'SELECT default_value, actual_value FROM default_expr_test' 'SELECT default_value, actual_value FROM default_expr_test'
)->fetch(FetchMode::NUMERIC); )->fetchNumeric();
self::assertEquals($actualValue, $defaultValue); self::assertEquals($actualValue, $defaultValue);
} }
......
...@@ -18,7 +18,7 @@ class QuotingTest extends FunctionalTestCase ...@@ -18,7 +18,7 @@ class QuotingTest extends FunctionalTestCase
$platform->quoteStringLiteral($string) $platform->quoteStringLiteral($string)
); );
self::assertSame($string, $this->connection->fetchColumn($query)); self::assertSame($string, $this->connection->fetchOne($query));
} }
/** /**
......
...@@ -7,7 +7,6 @@ namespace Doctrine\DBAL\Tests\Functional; ...@@ -7,7 +7,6 @@ namespace Doctrine\DBAL\Tests\Functional;
use Doctrine\DBAL\ColumnCase; use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Portability\Connection as ConnectionPortability; use Doctrine\DBAL\Portability\Connection as ConnectionPortability;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
...@@ -78,50 +77,38 @@ class PortabilityTest extends FunctionalTestCase ...@@ -78,50 +77,38 @@ class PortabilityTest extends FunctionalTestCase
public function testFullFetchMode() : void public function testFullFetchMode() : void
{ {
$rows = $this->portableConnection->fetchAll('SELECT * FROM portability_table'); $rows = $this->portableConnection->fetchAllAssociative('SELECT * FROM portability_table');
$this->assertFetchResultRows($rows); $this->assertFetchResultRows($rows);
$stmt = $this->portableConnection->query('SELECT * FROM portability_table'); $stmt = $this->portableConnection->query('SELECT * FROM portability_table');
$stmt->setFetchMode(FetchMode::ASSOCIATIVE);
foreach ($stmt as $row) { while (($row = $stmt->fetchAssociative())) {
$this->assertFetchResultRow($row);
}
$stmt = $this->portableConnection->query('SELECT * FROM portability_table');
while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE))) {
$this->assertFetchResultRow($row); $this->assertFetchResultRow($row);
} }
$stmt = $this->portableConnection->prepare('SELECT * FROM portability_table'); $stmt = $this->portableConnection->prepare('SELECT * FROM portability_table');
$stmt->execute(); $stmt->execute();
while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE))) { while (($row = $stmt->fetchAssociative())) {
$this->assertFetchResultRow($row); $this->assertFetchResultRow($row);
} }
} }
public function testConnFetchMode() : void public function testConnFetchMode() : void
{ {
$this->portableConnection->setFetchMode(FetchMode::ASSOCIATIVE); $conn = $this->getPortableConnection();
$rows = $this->portableConnection->fetchAll('SELECT * FROM portability_table'); $rows = $conn->fetchAllAssociative('SELECT * FROM portability_table');
$this->assertFetchResultRows($rows); $this->assertFetchResultRows($rows);
$stmt = $this->portableConnection->query('SELECT * FROM portability_table'); $stmt = $conn->query('SELECT * FROM portability_table');
foreach ($stmt as $row) { while (($row = $stmt->fetchAssociative())) {
$this->assertFetchResultRow($row);
}
$stmt = $this->portableConnection->query('SELECT * FROM portability_table');
while (($row = $stmt->fetch())) {
$this->assertFetchResultRow($row); $this->assertFetchResultRow($row);
} }
$stmt = $this->portableConnection->prepare('SELECT * FROM portability_table'); $stmt = $this->portableConnection->prepare('SELECT * FROM portability_table');
$stmt->execute(); $stmt->execute();
while (($row = $stmt->fetch())) { while (($row = $stmt->fetchAssociative())) {
$this->assertFetchResultRow($row); $this->assertFetchResultRow($row);
} }
} }
...@@ -156,20 +143,20 @@ class PortabilityTest extends FunctionalTestCase ...@@ -156,20 +143,20 @@ class PortabilityTest extends FunctionalTestCase
/** /**
* @param mixed[] $expected * @param mixed[] $expected
* *
* @dataProvider fetchAllColumnProvider * @dataProvider fetchColumnProvider
*/ */
public function testFetchAllColumn(string $field, array $expected) : void public function testfetchColumn(string $field, array $expected) : void
{ {
$stmt = $this->portableConnection->query('SELECT ' . $field . ' FROM portability_table'); $stmt = $this->portableConnection->query('SELECT ' . $field . ' FROM portability_table');
$column = $stmt->fetchAll(FetchMode::COLUMN); $column = $stmt->fetchColumn();
self::assertEquals($expected, $column); self::assertEquals($expected, $column);
} }
/** /**
* @return iterable<string, array<int, mixed>> * @return iterable<string, array<int, mixed>>
*/ */
public static function fetchAllColumnProvider() : iterable public static function fetchColumnProvider() : iterable
{ {
return [ return [
'int' => [ 'int' => [
...@@ -187,7 +174,7 @@ class PortabilityTest extends FunctionalTestCase ...@@ -187,7 +174,7 @@ class PortabilityTest extends FunctionalTestCase
{ {
$stmt = $this->portableConnection->query('SELECT Test_Null FROM portability_table'); $stmt = $this->portableConnection->query('SELECT Test_Null FROM portability_table');
$column = $stmt->fetchAll(FetchMode::COLUMN); $column = $stmt->fetchColumn();
self::assertSame([null, null], $column); self::assertSame([null, null], $column);
} }
} }
This diff is collapsed.
...@@ -60,7 +60,7 @@ class DefaultValueTest extends FunctionalTestCase ...@@ -60,7 +60,7 @@ class DefaultValueTest extends FunctionalTestCase
*/ */
public function testEscapedDefaultValueCanBeInserted(string $name, ?string $expectedDefault) : void public function testEscapedDefaultValueCanBeInserted(string $name, ?string $expectedDefault) : void
{ {
$value = $this->connection->fetchColumn( $value = $this->connection->fetchOne(
sprintf('SELECT %s FROM default_value', $name) sprintf('SELECT %s FROM default_value', $name)
); );
......
...@@ -468,7 +468,7 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -468,7 +468,7 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
'INSERT INTO test_column_defaults_are_valid () VALUES()' 'INSERT INTO test_column_defaults_are_valid () VALUES()'
); );
$row = $this->connection->fetchAssoc( $row = $this->connection->fetchAssociative(
'SELECT *, DATEDIFF(CURRENT_TIMESTAMP(), col_datetime) as diff_seconds FROM test_column_defaults_are_valid' 'SELECT *, DATEDIFF(CURRENT_TIMESTAMP(), col_datetime) as diff_seconds FROM test_column_defaults_are_valid'
); );
......
...@@ -1236,7 +1236,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase ...@@ -1236,7 +1236,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
assert($query instanceof Statement); assert($query instanceof Statement);
$query->execute(); $query->execute();
$lastUsedIdBeforeDelete = (int) $query->fetchColumn(); $lastUsedIdBeforeDelete = (int) $query->fetchOne();
$this->connection->query('DELETE FROM test_pk_auto_increment'); $this->connection->query('DELETE FROM test_pk_auto_increment');
...@@ -1246,7 +1246,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase ...@@ -1246,7 +1246,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
assert($query instanceof Statement); assert($query instanceof Statement);
$query->execute(); $query->execute();
$lastUsedIdAfterDelete = (int) $query->fetchColumn(); $lastUsedIdAfterDelete = (int) $query->fetchOne();
self::assertGreaterThan($lastUsedIdBeforeDelete, $lastUsedIdAfterDelete); self::assertGreaterThan($lastUsedIdBeforeDelete, $lastUsedIdAfterDelete);
} }
......
...@@ -279,7 +279,7 @@ SQL; ...@@ -279,7 +279,7 @@ SQL;
assert($query instanceof Statement); assert($query instanceof Statement);
$query->execute(); $query->execute();
$lastUsedIdAfterDelete = (int) $query->fetchColumn(); $lastUsedIdAfterDelete = (int) $query->fetchOne();
// with an empty table, non autoincrement rowid is always 1 // with an empty table, non autoincrement rowid is always 1
self::assertEquals(1, $lastUsedIdAfterDelete); self::assertEquals(1, $lastUsedIdAfterDelete);
......
...@@ -11,7 +11,6 @@ use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver; ...@@ -11,7 +11,6 @@ use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSRVDriver; use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSRVDriver;
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSRVDriver; use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSRVDriver;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
...@@ -46,15 +45,15 @@ class StatementTest extends FunctionalTestCase ...@@ -46,15 +45,15 @@ class StatementTest extends FunctionalTestCase
$stmt->execute(); $stmt->execute();
$id = $stmt->fetchColumn(); $id = $stmt->fetchOne();
self::assertEquals(1, $id); self::assertEquals(1, $id);
$stmt->closeCursor(); $stmt->closeCursor();
$stmt->execute(); $stmt->execute();
$id = $stmt->fetchColumn(); $id = $stmt->fetchOne();
self::assertEquals(1, $id); self::assertEquals(1, $id);
$id = $stmt->fetchColumn(); $id = $stmt->fetchOne();
self::assertEquals(2, $id); self::assertEquals(2, $id);
} }
...@@ -80,7 +79,7 @@ class StatementTest extends FunctionalTestCase ...@@ -80,7 +79,7 @@ class StatementTest extends FunctionalTestCase
$stmt->execute(); $stmt->execute();
self::assertEquals([ self::assertEquals([
['param1', 'X'], ['param1', 'X'],
], $stmt->fetchAll(FetchMode::NUMERIC)); ], $stmt->fetchAllNumeric());
$row2 = [ $row2 = [
'param' => 'param2', 'param' => 'param2',
...@@ -92,7 +91,7 @@ class StatementTest extends FunctionalTestCase ...@@ -92,7 +91,7 @@ class StatementTest extends FunctionalTestCase
self::assertEquals([ self::assertEquals([
['param1', 'X'], ['param1', 'X'],
['param2', 'A bit longer value'], ['param2', 'A bit longer value'],
], $stmt->fetchAll(FetchMode::NUMERIC)); ], $stmt->fetchAllNumeric());
} }
public function testFetchLongBlob() : void public function testFetchLongBlob() : void
...@@ -136,7 +135,7 @@ EOF ...@@ -136,7 +135,7 @@ EOF
$stream = Type::getType('blob') $stream = Type::getType('blob')
->convertToPHPValue( ->convertToPHPValue(
$stmt->fetchColumn(), $stmt->fetchOne(),
$this->connection->getDatabasePlatform() $this->connection->getDatabasePlatform()
); );
...@@ -150,14 +149,14 @@ EOF ...@@ -150,14 +149,14 @@ EOF
$stmt1 = $this->connection->prepare('SELECT id FROM stmt_test'); $stmt1 = $this->connection->prepare('SELECT id FROM stmt_test');
$stmt1->execute(); $stmt1->execute();
$stmt1->fetch(); $stmt1->fetchAssociative();
$stmt1->execute(); $stmt1->execute();
// fetching only one record out of two // fetching only one record out of two
$stmt1->fetch(); $stmt1->fetchAssociative();
$stmt2 = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?'); $stmt2 = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?');
$stmt2->execute([1]); $stmt2->execute([1]);
self::assertEquals(1, $stmt2->fetchColumn()); self::assertEquals(1, $stmt2->fetchOne());
} }
public function testReuseStatementAfterClosingCursor() : void public function testReuseStatementAfterClosingCursor() : void
...@@ -172,13 +171,13 @@ EOF ...@@ -172,13 +171,13 @@ EOF
$stmt = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?'); $stmt = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?');
$stmt->execute([1]); $stmt->execute([1]);
$id = $stmt->fetchColumn(); $id = $stmt->fetchOne();
self::assertEquals(1, $id); self::assertEquals(1, $id);
$stmt->closeCursor(); $stmt->closeCursor();
$stmt->execute([2]); $stmt->execute([2]);
$id = $stmt->fetchColumn(); $id = $stmt->fetchOne();
self::assertEquals(2, $id); self::assertEquals(2, $id);
} }
...@@ -192,11 +191,11 @@ EOF ...@@ -192,11 +191,11 @@ EOF
$id = 1; $id = 1;
$stmt->execute(); $stmt->execute();
self::assertEquals(1, $stmt->fetchColumn()); self::assertEquals(1, $stmt->fetchOne());
$id = 2; $id = 2;
$stmt->execute(); $stmt->execute();
self::assertEquals(2, $stmt->fetchColumn()); self::assertEquals(2, $stmt->fetchOne());
} }
public function testReuseStatementWithReboundValue() : void public function testReuseStatementWithReboundValue() : void
...@@ -208,11 +207,11 @@ EOF ...@@ -208,11 +207,11 @@ EOF
$stmt->bindValue(1, 1); $stmt->bindValue(1, 1);
$stmt->execute(); $stmt->execute();
self::assertEquals(1, $stmt->fetchColumn()); self::assertEquals(1, $stmt->fetchOne());
$stmt->bindValue(1, 2); $stmt->bindValue(1, 2);
$stmt->execute(); $stmt->execute();
self::assertEquals(2, $stmt->fetchColumn()); self::assertEquals(2, $stmt->fetchOne());
} }
public function testReuseStatementWithReboundParam() : void public function testReuseStatementWithReboundParam() : void
...@@ -225,12 +224,12 @@ EOF ...@@ -225,12 +224,12 @@ EOF
$x = 1; $x = 1;
$stmt->bindParam(1, $x); $stmt->bindParam(1, $x);
$stmt->execute(); $stmt->execute();
self::assertEquals(1, $stmt->fetchColumn()); self::assertEquals(1, $stmt->fetchOne());
$y = 2; $y = 2;
$stmt->bindParam(1, $y); $stmt->bindParam(1, $y);
$stmt->execute(); $stmt->execute();
self::assertEquals(2, $stmt->fetchColumn()); self::assertEquals(2, $stmt->fetchOne());
} }
/** /**
...@@ -264,7 +263,7 @@ EOF ...@@ -264,7 +263,7 @@ EOF
$stmt = $this->connection->prepare('SELECT name FROM stmt_test'); $stmt = $this->connection->prepare('SELECT name FROM stmt_test');
$stmt->execute(); $stmt->execute();
$stmt->fetch(); $stmt->fetchAssociative();
$stmt->closeCursor(); $stmt->closeCursor();
} }
...@@ -315,19 +314,19 @@ EOF ...@@ -315,19 +314,19 @@ EOF
return [ return [
'fetch' => [ 'fetch' => [
static function (Statement $stmt) { static function (Statement $stmt) {
return $stmt->fetch(); return $stmt->fetchAssociative();
}, },
false, false,
], ],
'fetch-column' => [ 'fetch-column' => [
static function (Statement $stmt) { static function (Statement $stmt) {
return $stmt->fetchColumn(); return $stmt->fetchOne();
}, },
false, false,
], ],
'fetch-all' => [ 'fetch-all' => [
static function (Statement $stmt) : array { static function (Statement $stmt) : array {
return $stmt->fetchAll(); return $stmt->fetchAllAssociative();
}, },
[], [],
], ],
...@@ -338,7 +337,7 @@ EOF ...@@ -338,7 +337,7 @@ EOF
{ {
$platform = $this->connection->getDatabasePlatform(); $platform = $this->connection->getDatabasePlatform();
$query = $platform->getDummySelectSQL(); $query = $platform->getDummySelectSQL();
$result = $this->connection->executeQuery($query)->fetch(FetchMode::COLUMN); $result = $this->connection->executeQuery($query)->fetchOne();
self::assertEquals(1, $result); self::assertEquals(1, $result);
} }
......
...@@ -69,7 +69,7 @@ class TemporaryTableTest extends FunctionalTestCase ...@@ -69,7 +69,7 @@ class TemporaryTableTest extends FunctionalTestCase
$this->connection->rollBack(); $this->connection->rollBack();
$rows = $this->connection->fetchAll('SELECT * FROM nontemporary'); $rows = $this->connection->fetchAllAssociative('SELECT * FROM nontemporary');
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.'); self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.');
} }
...@@ -116,7 +116,7 @@ class TemporaryTableTest extends FunctionalTestCase ...@@ -116,7 +116,7 @@ class TemporaryTableTest extends FunctionalTestCase
} catch (Throwable $e) { } catch (Throwable $e) {
} }
$rows = $this->connection->fetchAll('SELECT * FROM nontemporary'); $rows = $this->connection->fetchAllAssociative('SELECT * FROM nontemporary');
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.'); self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.');
} }
} }
...@@ -38,7 +38,7 @@ class DBAL202Test extends FunctionalTestCase ...@@ -38,7 +38,7 @@ class DBAL202Test extends FunctionalTestCase
$stmt->execute(); $stmt->execute();
$this->connection->rollBack(); $this->connection->rollBack();
self::assertEquals(0, $this->connection->query('SELECT COUNT(1) FROM DBAL202')->fetchColumn()); self::assertEquals(0, $this->connection->query('SELECT COUNT(1) FROM DBAL202')->fetchOne());
} }
public function testStatementCommit() : void public function testStatementCommit() : void
...@@ -48,6 +48,6 @@ class DBAL202Test extends FunctionalTestCase ...@@ -48,6 +48,6 @@ class DBAL202Test extends FunctionalTestCase
$stmt->execute(); $stmt->execute();
$this->connection->commit(); $this->connection->commit();
self::assertEquals(1, $this->connection->query('SELECT COUNT(1) FROM DBAL202')->fetchColumn()); self::assertEquals(1, $this->connection->query('SELECT COUNT(1) FROM DBAL202')->fetchOne());
} }
} }
...@@ -54,7 +54,7 @@ class DBAL630Test extends FunctionalTestCase ...@@ -54,7 +54,7 @@ class DBAL630Test extends FunctionalTestCase
$id = $this->connection->lastInsertId('dbal630_id_seq'); $id = $this->connection->lastInsertId('dbal630_id_seq');
self::assertNotEmpty($id); self::assertNotEmpty($id);
$row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]); $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
self::assertIsArray($row); self::assertIsArray($row);
self::assertFalse($row['bool_col']); self::assertFalse($row['bool_col']);
...@@ -70,7 +70,7 @@ class DBAL630Test extends FunctionalTestCase ...@@ -70,7 +70,7 @@ class DBAL630Test extends FunctionalTestCase
$id = $this->connection->lastInsertId('dbal630_id_seq'); $id = $this->connection->lastInsertId('dbal630_id_seq');
self::assertNotEmpty($id); self::assertNotEmpty($id);
$row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]); $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
self::assertIsArray($row); self::assertIsArray($row);
self::assertFalse($row['bool_col']); self::assertFalse($row['bool_col']);
...@@ -91,7 +91,7 @@ class DBAL630Test extends FunctionalTestCase ...@@ -91,7 +91,7 @@ class DBAL630Test extends FunctionalTestCase
self::assertNotEmpty($id); self::assertNotEmpty($id);
$row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]); $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
self::assertIsArray($row); self::assertIsArray($row);
self::assertFalse($row['bool_col']); self::assertFalse($row['bool_col']);
...@@ -117,7 +117,7 @@ class DBAL630Test extends FunctionalTestCase ...@@ -117,7 +117,7 @@ class DBAL630Test extends FunctionalTestCase
self::assertNotEmpty($id); self::assertNotEmpty($id);
$row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]); $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
self::assertIsArray($row); self::assertIsArray($row);
self::assertSame($databaseConvertedValue, $row['bool_col']); self::assertSame($databaseConvertedValue, $row['bool_col']);
...@@ -147,7 +147,7 @@ class DBAL630Test extends FunctionalTestCase ...@@ -147,7 +147,7 @@ class DBAL630Test extends FunctionalTestCase
self::assertNotEmpty($id); self::assertNotEmpty($id);
$row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]); $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
self::assertIsArray($row); self::assertIsArray($row);
self::assertSame($databaseConvertedValue, $row['bool_col']); self::assertSame($databaseConvertedValue, $row['bool_col']);
......
...@@ -249,7 +249,7 @@ class TypeConversionTest extends FunctionalTestCase ...@@ -249,7 +249,7 @@ class TypeConversionTest extends FunctionalTestCase
$sql = 'SELECT ' . $columnName . ' FROM type_conversion WHERE id = ' . self::$typeCounter; $sql = 'SELECT ' . $columnName . ' FROM type_conversion WHERE id = ' . self::$typeCounter;
return $typeInstance->convertToPHPValue( return $typeInstance->convertToPHPValue(
$this->connection->fetchColumn($sql), $this->connection->fetchOne($sql),
$this->connection->getDatabasePlatform() $this->connection->getDatabasePlatform()
); );
} }
......
...@@ -74,7 +74,7 @@ class BinaryTest extends FunctionalTestCase ...@@ -74,7 +74,7 @@ class BinaryTest extends FunctionalTestCase
*/ */
private function select(string $id) private function select(string $id)
{ {
$value = $this->connection->fetchColumn( $value = $this->connection->fetchOne(
'SELECT val FROM binary_table WHERE id = ?', 'SELECT val FROM binary_table WHERE id = ?',
[$id], [$id],
[ParameterType::BINARY] [ParameterType::BINARY]
......
...@@ -118,10 +118,10 @@ class WriteTest extends FunctionalTestCase ...@@ -118,10 +118,10 @@ class WriteTest extends FunctionalTestCase
$this->insertRows(); $this->insertRows();
self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 2])); self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 2]));
self::assertCount(1, $this->connection->fetchAll('SELECT * FROM write_table')); self::assertCount(1, $this->connection->fetchAllAssociative('SELECT * FROM write_table'));
self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 1])); self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 1]));
self::assertCount(0, $this->connection->fetchAll('SELECT * FROM write_table')); self::assertCount(0, $this->connection->fetchAllAssociative('SELECT * FROM write_table'));
} }
public function testUpdate() : void public function testUpdate() : void
...@@ -163,7 +163,7 @@ class WriteTest extends FunctionalTestCase ...@@ -163,7 +163,7 @@ class WriteTest extends FunctionalTestCase
})); }));
$stmt = $this->connection->query($this->connection->getDatabasePlatform()->getSequenceNextValSQL('write_table_id_seq')); $stmt = $this->connection->query($this->connection->getDatabasePlatform()->getSequenceNextValSQL('write_table_id_seq'));
$nextSequenceVal = $stmt->fetchColumn(); $nextSequenceVal = $stmt->fetchOne();
$lastInsertId = $this->lastInsertId('write_table_id_seq'); $lastInsertId = $this->lastInsertId('write_table_id_seq');
...@@ -194,7 +194,7 @@ class WriteTest extends FunctionalTestCase ...@@ -194,7 +194,7 @@ class WriteTest extends FunctionalTestCase
['test_string' => 'datetime', 'test_int' => 'integer'] ['test_string' => 'datetime', 'test_int' => 'integer']
); );
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchOne('SELECT test_string FROM write_table WHERE test_int = 30');
self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data); self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data);
} }
...@@ -221,7 +221,7 @@ class WriteTest extends FunctionalTestCase ...@@ -221,7 +221,7 @@ class WriteTest extends FunctionalTestCase
['test_string' => 'datetime', 'test_int' => 'integer'] ['test_string' => 'datetime', 'test_int' => 'integer']
); );
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchOne('SELECT test_string FROM write_table WHERE test_int = 30');
self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data); self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data);
} }
...@@ -240,7 +240,7 @@ class WriteTest extends FunctionalTestCase ...@@ -240,7 +240,7 @@ class WriteTest extends FunctionalTestCase
$this->connection->delete('write_table', ['test_int' => 30, 'test_string' => $val], ['test_string' => 'datetime', 'test_int' => 'integer']); $this->connection->delete('write_table', ['test_int' => 30, 'test_string' => $val], ['test_string' => 'datetime', 'test_int' => 'integer']);
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchOne('SELECT test_string FROM write_table WHERE test_int = 30');
self::assertFalse($data); self::assertFalse($data);
} }
...@@ -296,13 +296,13 @@ class WriteTest extends FunctionalTestCase ...@@ -296,13 +296,13 @@ class WriteTest extends FunctionalTestCase
['test_string' => 'string', 'test_int' => 'integer'] ['test_string' => 'string', 'test_int' => 'integer']
); );
$data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchAllAssociative('SELECT * FROM write_table WHERE test_int = 30');
self::assertCount(1, $data); self::assertCount(1, $data);
$this->connection->update('write_table', ['test_int' => 10], ['test_string' => null], ['test_string' => 'string', 'test_int' => 'integer']); $this->connection->update('write_table', ['test_int' => 10], ['test_string' => null], ['test_string' => 'string', 'test_int' => 'integer']);
$data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchAllAssociative('SELECT * FROM write_table WHERE test_int = 30');
self::assertCount(0, $data); self::assertCount(0, $data);
} }
...@@ -315,13 +315,13 @@ class WriteTest extends FunctionalTestCase ...@@ -315,13 +315,13 @@ class WriteTest extends FunctionalTestCase
['test_string' => 'string', 'test_int' => 'integer'] ['test_string' => 'string', 'test_int' => 'integer']
); );
$data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchAllAssociative('SELECT * FROM write_table WHERE test_int = 30');
self::assertCount(1, $data); self::assertCount(1, $data);
$this->connection->delete('write_table', ['test_string' => null], ['test_string' => 'string']); $this->connection->delete('write_table', ['test_string' => null], ['test_string' => 'string']);
$data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchAllAssociative('SELECT * FROM write_table WHERE test_int = 30');
self::assertCount(0, $data); self::assertCount(0, $data);
} }
......
...@@ -10,7 +10,6 @@ use Doctrine\DBAL\Portability\Connection; ...@@ -10,7 +10,6 @@ use Doctrine\DBAL\Portability\Connection;
use Doctrine\DBAL\Portability\Statement; use Doctrine\DBAL\Portability\Statement;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function iterator_to_array;
class StatementTest extends TestCase class StatementTest extends TestCase
{ {
...@@ -93,15 +92,6 @@ class StatementTest extends TestCase ...@@ -93,15 +92,6 @@ class StatementTest extends TestCase
$this->stmt->execute($params); $this->stmt->execute($params);
} }
public function testGetIterator() : void
{
$this->wrappedStmt->expects(self::exactly(3))
->method('fetch')
->willReturnOnConsecutiveCalls('foo', 'bar', false);
self::assertSame(['foo', 'bar'], iterator_to_array($this->stmt->getIterator()));
}
public function testRowCount() : void public function testRowCount() : void
{ {
$rowCount = 666; $rowCount = 666;
......
...@@ -33,7 +33,7 @@ final class DB2SchemaManagerTest extends TestCase ...@@ -33,7 +33,7 @@ final class DB2SchemaManagerTest extends TestCase
$platform = $this->createMock(DB2Platform::class); $platform = $this->createMock(DB2Platform::class);
$this->conn = $this $this->conn = $this
->getMockBuilder(Connection::class) ->getMockBuilder(Connection::class)
->onlyMethods(['fetchAll']) ->onlyMethods(['fetchAllAssociative'])
->setConstructorArgs([['platform' => $platform], $driverMock, new Configuration(), $eventManager]) ->setConstructorArgs([['platform' => $platform], $driverMock, new Configuration(), $eventManager])
->getMock(); ->getMock();
...@@ -50,7 +50,7 @@ final class DB2SchemaManagerTest extends TestCase ...@@ -50,7 +50,7 @@ final class DB2SchemaManagerTest extends TestCase
$this->conn->getConfiguration()->setSchemaAssetsFilter(static function (string $name) : bool { $this->conn->getConfiguration()->setSchemaAssetsFilter(static function (string $name) : bool {
return preg_match('/^(?!T_)/', $name) === 1; return preg_match('/^(?!T_)/', $name) === 1;
}); });
$this->conn->expects(self::once())->method('fetchAll')->will(self::returnValue([ $this->conn->expects(self::once())->method('fetchAllAssociative')->will(self::returnValue([
['name' => 'FOO'], ['name' => 'FOO'],
['name' => 'T_FOO'], ['name' => 'T_FOO'],
['name' => 'BAR'], ['name' => 'BAR'],
...@@ -73,7 +73,7 @@ final class DB2SchemaManagerTest extends TestCase ...@@ -73,7 +73,7 @@ final class DB2SchemaManagerTest extends TestCase
return in_array($assetName, $accepted, true); return in_array($assetName, $accepted, true);
}); });
$this->conn->expects(self::once())->method('fetchAll')->will(self::returnValue([ $this->conn->expects(self::once())->method('fetchAllAssociative')->will(self::returnValue([
['name' => 'FOO'], ['name' => 'FOO'],
['name' => 'T_FOO'], ['name' => 'T_FOO'],
['name' => 'BAR'], ['name' => 'BAR'],
......
...@@ -27,9 +27,13 @@ class MySqlSchemaManagerTest extends TestCase ...@@ -27,9 +27,13 @@ class MySqlSchemaManagerTest extends TestCase
{ {
$eventManager = new EventManager(); $eventManager = new EventManager();
$driverMock = $this->createMock(Driver::class); $driverMock = $this->createMock(Driver::class);
$platform = $this->createMock(MySqlPlatform::class); $platform = $this->createMock(MySqlPlatform::class);
$platform->method('getListTableForeignKeysSQL')
->willReturn('');
$this->conn = $this->getMockBuilder(Connection::class) $this->conn = $this->getMockBuilder(Connection::class)
->onlyMethods(['fetchAll']) ->onlyMethods(['fetchAllAssociative'])
->setConstructorArgs([['platform' => $platform], $driverMock, new Configuration(), $eventManager]) ->setConstructorArgs([['platform' => $platform], $driverMock, new Configuration(), $eventManager])
->getMock(); ->getMock();
$this->manager = new MySqlSchemaManager($this->conn); $this->manager = new MySqlSchemaManager($this->conn);
...@@ -37,7 +41,7 @@ class MySqlSchemaManagerTest extends TestCase ...@@ -37,7 +41,7 @@ class MySqlSchemaManagerTest extends TestCase
public function testCompositeForeignKeys() : void public function testCompositeForeignKeys() : void
{ {
$this->conn->expects(self::once())->method('fetchAll')->will(self::returnValue($this->getFKDefinition())); $this->conn->expects(self::once())->method('fetchAllAssociative')->will(self::returnValue($this->getFKDefinition()));
$fkeys = $this->manager->listTableForeignKeys('dummy'); $fkeys = $this->manager->listTableForeignKeys('dummy');
self::assertCount(1, $fkeys, 'Table has to have one foreign key.'); self::assertCount(1, $fkeys, 'Table has to have one foreign key.');
......
...@@ -6,11 +6,17 @@ namespace Doctrine\DBAL\Tests; ...@@ -6,11 +6,17 @@ namespace Doctrine\DBAL\Tests;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\OraclePlatform;
use InvalidArgumentException; use InvalidArgumentException;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
use function array_keys;
use function array_map;
use function array_values;
use function explode; use function explode;
use function extension_loaded; use function extension_loaded;
use function implode;
use function is_string;
use function unlink; use function unlink;
/** /**
...@@ -222,4 +228,24 @@ class TestUtil ...@@ -222,4 +228,24 @@ class TestUtil
{ {
return DriverManager::getConnection(self::getParamsForTemporaryConnection()); return DriverManager::getConnection(self::getParamsForTemporaryConnection());
} }
/**
* Generates a query that will return the given rows without the need to create a temporary table.
*
* @param array<int,array<string,mixed>> $rows
*/
public static function generateResultSetQuery(array $rows, AbstractPlatform $platform) : string
{
return implode(' UNION ALL ', array_map(static function (array $row) use ($platform) : string {
return $platform->getDummySelectSQL(
implode(', ', array_map(static function (string $column, $value) use ($platform) : string {
if (is_string($value)) {
$value = $platform->quoteStringLiteral($value);
}
return $value . ' ' . $platform->quoteIdentifier($column);
}, array_keys($row), array_values($row)))
);
}, $rows));
}
} }
...@@ -33,7 +33,7 @@ class RunSqlCommandTest extends TestCase ...@@ -33,7 +33,7 @@ class RunSqlCommandTest extends TestCase
$this->commandTester = new CommandTester($this->command); $this->commandTester = new CommandTester($this->command);
$this->connectionMock = $this->createMock(Connection::class); $this->connectionMock = $this->createMock(Connection::class);
$this->connectionMock->method('fetchAll') $this->connectionMock->method('fetchAllAssociative')
->willReturn([[1]]); ->willReturn([[1]]);
$this->connectionMock->method('executeUpdate') $this->connectionMock->method('executeUpdate')
->willReturn(42); ->willReturn(42);
...@@ -67,7 +67,7 @@ class RunSqlCommandTest extends TestCase ...@@ -67,7 +67,7 @@ class RunSqlCommandTest extends TestCase
public function testSelectStatementsPrintsResult() : void public function testSelectStatementsPrintsResult() : void
{ {
$this->expectConnectionFetchAll(); $this->expectConnectionFetchAllAssociative();
$exitCode = $this->commandTester->execute([ $exitCode = $this->commandTester->execute([
'command' => $this->command->getName(), 'command' => $this->command->getName(),
...@@ -99,22 +99,22 @@ class RunSqlCommandTest extends TestCase ...@@ -99,22 +99,22 @@ class RunSqlCommandTest extends TestCase
->method('executeUpdate'); ->method('executeUpdate');
$this->connectionMock $this->connectionMock
->expects(self::exactly(0)) ->expects(self::exactly(0))
->method('fetchAll'); ->method('fetchAllAssociative');
} }
private function expectConnectionFetchAll() : void private function expectConnectionFetchAllAssociative() : void
{ {
$this->connectionMock $this->connectionMock
->expects(self::exactly(0)) ->expects(self::exactly(0))
->method('executeUpdate'); ->method('executeUpdate');
$this->connectionMock $this->connectionMock
->expects(self::exactly(1)) ->expects(self::exactly(1))
->method('fetchAll'); ->method('fetchAllAssociative');
} }
public function testStatementsWithFetchResultPrintsResult() : void public function testStatementsWithFetchResultPrintsResult() : void
{ {
$this->expectConnectionFetchAll(); $this->expectConnectionFetchAllAssociative();
$this->commandTester->execute([ $this->commandTester->execute([
'command' => $this->command->getName(), 'command' => $this->command->getName(),
......
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