Unverified Commit 18908c39 authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3948 from morozov/master

Manually merge 3.0.x into master
parents 1eba78d6 d2288393
...@@ -269,6 +269,14 @@ The Doctrine\DBAL\Version class is no longer available: please refrain from chec ...@@ -269,6 +269,14 @@ The Doctrine\DBAL\Version class is no longer available: please refrain from chec
# Upgrade to 3.0 # Upgrade to 3.0
## 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.
## BC BREAK: Dropped support for the `$columnIndex` argument in `ResultStatement::fetchColumn()`, other `ResultStatement::fetch*()` methods invoked with `FetchMode::COLUMN` and `Connection::fetchColumn()`.
In order to fetch a column with an index other than `0`, use `FetchMode::NUMERIC` and the array element with the corresponding index.
## BC BREAK: Removed `EchoSQLLogger` ## BC BREAK: Removed `EchoSQLLogger`
`EchoSQLLogger` is no longer available as part of the package. `EchoSQLLogger` is no longer available as part of the package.
......
...@@ -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": "d33d9fbc27c8a727a565ef5524bbbcda", "content-hash": "c4f3212f2eb936c849f99146f9ad2d9c",
"packages": [ "packages": [
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
...@@ -1299,16 +1299,16 @@ ...@@ -1299,16 +1299,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.0.1", "version": "9.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "68d7e5b17a6b9461e17c00446caa409863154f76" "reference": "848f6521c906500e66229668768576d35de0227e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/68d7e5b17a6b9461e17c00446caa409863154f76", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/848f6521c906500e66229668768576d35de0227e",
"reference": "68d7e5b17a6b9461e17c00446caa409863154f76", "reference": "848f6521c906500e66229668768576d35de0227e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -1324,14 +1324,15 @@ ...@@ -1324,14 +1324,15 @@
"phar-io/version": "^2.0.1", "phar-io/version": "^2.0.1",
"php": "^7.3", "php": "^7.3",
"phpspec/prophecy": "^1.8.1", "phpspec/prophecy": "^1.8.1",
"phpunit/php-code-coverage": "^8.0", "phpunit/php-code-coverage": "^8.0.1",
"phpunit/php-file-iterator": "^3.0", "phpunit/php-file-iterator": "^3.0",
"phpunit/php-invoker": "^3.0", "phpunit/php-invoker": "^3.0",
"phpunit/php-text-template": "^2.0", "phpunit/php-text-template": "^2.0",
"phpunit/php-timer": "^3.0", "phpunit/php-timer": "^3.0",
"sebastian/code-unit": "^1.0",
"sebastian/comparator": "^4.0", "sebastian/comparator": "^4.0",
"sebastian/diff": "^4.0", "sebastian/diff": "^4.0",
"sebastian/environment": "^5.0", "sebastian/environment": "^5.0.1",
"sebastian/exporter": "^4.0", "sebastian/exporter": "^4.0",
"sebastian/global-state": "^4.0", "sebastian/global-state": "^4.0",
"sebastian/object-enumerator": "^4.0", "sebastian/object-enumerator": "^4.0",
...@@ -1352,7 +1353,7 @@ ...@@ -1352,7 +1353,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "9.0-dev" "dev-master": "9.1-dev"
} }
}, },
"autoload": { "autoload": {
...@@ -1381,7 +1382,7 @@ ...@@ -1381,7 +1382,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2020-02-13T07:30:12+00:00" "time": "2020-04-03T14:40:04+00:00"
}, },
{ {
"name": "psr/log", "name": "psr/log",
...@@ -1430,6 +1431,52 @@ ...@@ -1430,6 +1431,52 @@
], ],
"time": "2020-03-23T09:12:05+00:00" "time": "2020-03-23T09:12:05+00:00"
}, },
{
"name": "sebastian/code-unit",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit.git",
"reference": "8d8f09bd47c75159921e6e84fdef146343962866"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/8d8f09bd47c75159921e6e84fdef146343962866",
"reference": "8d8f09bd47c75159921e6e84fdef146343962866",
"shasum": ""
},
"require": {
"php": "^7.3"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Collection of value objects that represent the PHP code units",
"homepage": "https://github.com/sebastianbergmann/code-unit",
"time": "2020-03-30T11:59:20+00:00"
},
{ {
"name": "sebastian/code-unit-reverse-lookup", "name": "sebastian/code-unit-reverse-lookup",
"version": "2.0.0", "version": "2.0.0",
...@@ -1597,16 +1644,16 @@ ...@@ -1597,16 +1644,16 @@
}, },
{ {
"name": "sebastian/environment", "name": "sebastian/environment",
"version": "5.0.1", "version": "5.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/environment.git", "url": "https://github.com/sebastianbergmann/environment.git",
"reference": "9bffdefa7810031a165ddd6275da6a2c1f6f2dfb" "reference": "c39c1db0a5cffc98173f3de5a17d489d1043fd7b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/9bffdefa7810031a165ddd6275da6a2c1f6f2dfb", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/c39c1db0a5cffc98173f3de5a17d489d1043fd7b",
"reference": "9bffdefa7810031a165ddd6275da6a2c1f6f2dfb", "reference": "c39c1db0a5cffc98173f3de5a17d489d1043fd7b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -1646,7 +1693,7 @@ ...@@ -1646,7 +1693,7 @@
"environment", "environment",
"hhvm" "hhvm"
], ],
"time": "2020-02-19T13:40:20+00:00" "time": "2020-03-31T12:14:15+00:00"
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
...@@ -2338,16 +2385,16 @@ ...@@ -2338,16 +2385,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.14.0", "version": "v1.15.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38" "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
"reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -2359,7 +2406,7 @@ ...@@ -2359,7 +2406,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.14-dev" "dev-master": "1.15-dev"
} }
}, },
"autoload": { "autoload": {
...@@ -2392,7 +2439,21 @@ ...@@ -2392,7 +2439,21 @@
"polyfill", "polyfill",
"portable" "portable"
], ],
"time": "2020-01-13T11:15:53+00:00" "funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-02-27T09:26:54+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
......
...@@ -70,12 +70,6 @@ parameters: ...@@ -70,12 +70,6 @@ parameters:
- %currentWorkingDirectory%/src/Platforms/*Platform.php - %currentWorkingDirectory%/src/Platforms/*Platform.php
- %currentWorkingDirectory%/src/Schema/*SchemaManager.php - %currentWorkingDirectory%/src/Schema/*SchemaManager.php
# FetchMode::CUSTOM_OBJECT requires variable property access
-
message: '~^Variable property access on object\.~'
paths:
- %currentWorkingDirectory%/src/Driver/*/*Statement.php
# Some APIs use variable method calls internally # Some APIs use variable method calls internally
- -
message: '~^Variable method call on .*~' message: '~^Variable method call on .*~'
......
...@@ -6,11 +6,9 @@ namespace Doctrine\DBAL\Cache; ...@@ -6,11 +6,9 @@ namespace Doctrine\DBAL\Cache;
use ArrayIterator; use ArrayIterator;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use function array_key_exists;
use function array_merge; use function array_merge;
use function array_values; use function array_values;
use function count; use function count;
...@@ -59,15 +57,8 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -59,15 +57,8 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
return count($this->data); return count($this->data);
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
}
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
} }
...@@ -84,7 +75,7 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -84,7 +75,7 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
if (! isset($this->data[$this->num])) { if (! isset($this->data[$this->num])) {
return false; return false;
...@@ -117,10 +108,10 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -117,10 +108,10 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$rows = []; $rows = [];
while ($row = $this->fetch($fetchMode, ...$args)) { while ($row = $this->fetch($fetchMode)) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -130,7 +121,7 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -130,7 +121,7 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -138,10 +129,6 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -138,10 +129,6 @@ final class ArrayStatement implements IteratorAggregate, ResultStatement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
} }
...@@ -7,14 +7,11 @@ namespace Doctrine\DBAL\Cache; ...@@ -7,14 +7,11 @@ namespace Doctrine\DBAL\Cache;
use ArrayIterator; use ArrayIterator;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use function array_key_exists;
use function array_merge; use function array_merge;
use function array_values; use function array_values;
use function count;
use function reset; use function reset;
/** /**
...@@ -93,10 +90,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -93,10 +90,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
return $this->statement->columnCount(); return $this->statement->columnCount();
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
} }
...@@ -114,7 +108,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -114,7 +108,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
if ($this->data === null) { if ($this->data === null) {
$this->data = []; $this->data = [];
...@@ -154,9 +148,9 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -154,9 +148,9 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$data = $this->statement->fetchAll($fetchMode, ...$args); $data = $this->statement->fetchAll($fetchMode);
if ($fetchMode === FetchMode::COLUMN) { if ($fetchMode === FetchMode::COLUMN) {
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
...@@ -173,7 +167,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -173,7 +167,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -181,11 +175,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -181,11 +175,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
/** /**
......
...@@ -494,16 +494,15 @@ class Connection implements DriverConnection ...@@ -494,16 +494,15 @@ class Connection implements DriverConnection
* *
* @param string $query The SQL query to be executed. * @param string $query The SQL query to be executed.
* @param array<int, mixed>|array<string, mixed> $params The prepared statement params. * @param array<int, mixed>|array<string, mixed> $params The prepared statement params.
* @param int $column The 0-indexed column number to retrieve.
* @param array<int, int|string>|array<string, int|string> $types The query parameter types. * @param array<int, int|string>|array<string, int|string> $types The query parameter types.
* *
* @return mixed|false False is returned if no rows are found. * @return mixed|false False is returned if no rows are found.
* *
* @throws DBALException * @throws DBALException
*/ */
public function fetchColumn(string $query, array $params = [], int $column = 0, array $types = []) public function fetchColumn(string $query, array $params = [], array $types = [])
{ {
return $this->executeQuery($query, $params, $types)->fetchColumn($column); return $this->executeQuery($query, $params, $types)->fetchColumn();
} }
/** /**
......
...@@ -6,42 +6,27 @@ namespace Doctrine\DBAL\Driver\IBMDB2; ...@@ -6,42 +6,27 @@ namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use ReflectionClass;
use ReflectionObject;
use ReflectionProperty;
use stdClass;
use function array_change_key_case;
use function array_key_exists;
use function assert; use function assert;
use function count;
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_fetch_both;
use function db2_fetch_object;
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;
use function error_get_last; use function error_get_last;
use function fclose; use function fclose;
use function fwrite; use function fwrite;
use function gettype;
use function is_int; use function is_int;
use function is_object;
use function is_resource; use function is_resource;
use function is_string;
use function ksort; use function ksort;
use function sprintf;
use function stream_copy_to_stream; use function stream_copy_to_stream;
use function stream_get_meta_data; use function stream_get_meta_data;
use function strtolower;
use function tmpfile; use function tmpfile;
use const CASE_LOWER;
use const DB2_BINARY; use const DB2_BINARY;
use const DB2_CHAR; use const DB2_CHAR;
use const DB2_LONG; use const DB2_LONG;
...@@ -64,12 +49,6 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -64,12 +49,6 @@ final class DB2Statement implements IteratorAggregate, Statement
*/ */
private $lobs = []; private $lobs = [];
/** @var string Name of the default class to instantiate when fetching class instances. */
private $defaultFetchClass = '\stdClass';
/** @var mixed[] Constructor arguments for the default class to instantiate when fetching class instances. */
private $defaultFetchClassCtorArgs = [];
/** @var int */ /** @var int */
private $defaultFetchMode = FetchMode::MIXED; private $defaultFetchMode = FetchMode::MIXED;
...@@ -192,22 +171,9 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -192,22 +171,9 @@ final class DB2Statement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (! isset($args[1])) {
return;
}
$this->defaultFetchClassCtorArgs = (array) $args[2];
} }
/** /**
...@@ -221,7 +187,7 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -221,7 +187,7 @@ final class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
// 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 result
// in order to prevent exceptional situation // in order to prevent exceptional situation
...@@ -240,29 +206,9 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -240,29 +206,9 @@ final class DB2Statement implements IteratorAggregate, Statement
case FetchMode::ASSOCIATIVE: case FetchMode::ASSOCIATIVE:
return db2_fetch_assoc($this->stmt); return db2_fetch_assoc($this->stmt);
case FetchMode::CUSTOM_OBJECT:
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
if (count($args) > 0) {
$className = $args[0];
$ctorArgs = $args[1] ?? [];
}
$result = db2_fetch_object($this->stmt);
if ($result instanceof stdClass) {
$result = $this->castObject($result, $className, $ctorArgs);
}
return $result;
case FetchMode::NUMERIC: case FetchMode::NUMERIC:
return db2_fetch_array($this->stmt); return db2_fetch_array($this->stmt);
case FetchMode::STANDARD_OBJECT:
return db2_fetch_object($this->stmt);
default: default:
throw new DB2Exception('Given Fetch-Style ' . $fetchMode . ' is not supported.'); throw new DB2Exception('Given Fetch-Style ' . $fetchMode . ' is not supported.');
} }
...@@ -271,18 +217,11 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -271,18 +217,11 @@ final class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$rows = []; $rows = [];
switch ($fetchMode) { switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
while (($row = $this->fetch($fetchMode, ...$args)) !== false) {
$rows[] = $row;
}
break;
case FetchMode::COLUMN: case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) { while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row; $rows[] = $row;
...@@ -302,7 +241,7 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -302,7 +241,7 @@ final class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -310,11 +249,7 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -310,11 +249,7 @@ final class DB2Statement implements IteratorAggregate, Statement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
public function rowCount() : int public function rowCount() : int
...@@ -337,69 +272,6 @@ final class DB2Statement implements IteratorAggregate, Statement ...@@ -337,69 +272,6 @@ final class DB2Statement implements IteratorAggregate, Statement
} }
} }
/**
* Casts a stdClass object to the given class name mapping its' properties.
*
* @param stdClass $sourceObject Object to cast from.
* @param string|object $destinationClass Name of the class or class instance to cast to.
* @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance.
*
* @throws DB2Exception
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) : object
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
throw new DB2Exception(sprintf(
'Destination class has to be of type string or object, %s given.',
gettype($destinationClass)
));
}
} else {
$destinationClass = new ReflectionClass($destinationClass);
$destinationClass = $destinationClass->newInstanceArgs($ctorArgs);
}
$sourceReflection = new ReflectionObject($sourceObject);
$destinationClassReflection = new ReflectionObject($destinationClass);
/** @var ReflectionProperty[] $destinationProperties */
$destinationProperties = array_change_key_case($destinationClassReflection->getProperties(), CASE_LOWER);
foreach ($sourceReflection->getProperties() as $sourceProperty) {
$sourceProperty->setAccessible(true);
$name = $sourceProperty->getName();
$value = $sourceProperty->getValue($sourceObject);
// Try to find a case-matching property.
if ($destinationClassReflection->hasProperty($name)) {
$destinationProperty = $destinationClassReflection->getProperty($name);
$destinationProperty->setAccessible(true);
$destinationProperty->setValue($destinationClass, $value);
continue;
}
$name = strtolower($name);
// Try to find a property without matching case.
// Fallback for the driver returning either all uppercase or all lowercase column names.
if (isset($destinationProperties[$name])) {
$destinationProperty = $destinationProperties[$name];
$destinationProperty->setAccessible(true);
$destinationProperty->setValue($destinationClass, $value);
continue;
}
$destinationClass->$name = $value;
}
return $destinationClass;
}
/** /**
* @return resource * @return resource
* *
......
...@@ -13,7 +13,6 @@ use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType; ...@@ -13,7 +13,6 @@ 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\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
...@@ -22,7 +21,6 @@ use mysqli_stmt; ...@@ -22,7 +21,6 @@ use mysqli_stmt;
use stdClass; use stdClass;
use function array_combine; use function array_combine;
use function array_fill; use function array_fill;
use function array_key_exists;
use function array_map; use function array_map;
use function assert; use function assert;
use function count; use function count;
...@@ -328,7 +326,7 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -328,7 +326,7 @@ final class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
// 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 result
// in order to prevent exceptional situation // in order to prevent exceptional situation
...@@ -366,9 +364,6 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -366,9 +364,6 @@ final class MysqliStatement implements IteratorAggregate, Statement
case FetchMode::MIXED: case FetchMode::MIXED:
return $assoc + $values; return $assoc + $values;
case FetchMode::STANDARD_OBJECT:
return (object) $assoc;
default: default:
throw UnknownFetchMode::new($fetchMode); throw UnknownFetchMode::new($fetchMode);
} }
...@@ -377,7 +372,7 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -377,7 +372,7 @@ final class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; $fetchMode = $fetchMode ?? $this->defaultFetchMode;
...@@ -399,7 +394,7 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -399,7 +394,7 @@ final class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -407,11 +402,7 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -407,11 +402,7 @@ final class MysqliStatement implements IteratorAggregate, Statement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
public function closeCursor() : void public function closeCursor() : void
...@@ -434,10 +425,7 @@ final class MysqliStatement implements IteratorAggregate, Statement ...@@ -434,10 +425,7 @@ final class MysqliStatement implements IteratorAggregate, Statement
return $this->stmt->field_count; return $this->stmt->field_count;
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
} }
......
...@@ -6,14 +6,11 @@ namespace Doctrine\DBAL\Driver\OCI8; ...@@ -6,14 +6,11 @@ namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use InvalidArgumentException; use InvalidArgumentException;
use IteratorAggregate; use IteratorAggregate;
use function array_key_exists;
use function assert; use function assert;
use function count;
use function is_int; use function is_int;
use function is_resource; use function is_resource;
use function oci_bind_by_name; use function oci_bind_by_name;
...@@ -22,7 +19,6 @@ use function oci_error; ...@@ -22,7 +19,6 @@ use function oci_error;
use function oci_execute; use function oci_execute;
use function oci_fetch_all; use function oci_fetch_all;
use function oci_fetch_array; use function oci_fetch_array;
use function oci_fetch_object;
use function oci_new_descriptor; use function oci_new_descriptor;
use function oci_num_fields; use function oci_num_fields;
use function oci_num_rows; use function oci_num_rows;
...@@ -224,10 +220,7 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -224,10 +220,7 @@ final class OCI8Statement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->_defaultFetchMode = $fetchMode; $this->_defaultFetchMode = $fetchMode;
} }
...@@ -243,7 +236,7 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -243,7 +236,7 @@ final class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
// 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 result
// in order to prevent exceptional situation // in order to prevent exceptional situation
...@@ -257,10 +250,6 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -257,10 +250,6 @@ final class OCI8Statement implements IteratorAggregate, Statement
return $this->fetchColumn(); return $this->fetchColumn();
} }
if ($fetchMode === FetchMode::STANDARD_OBJECT) {
return oci_fetch_object($this->_sth);
}
if (! isset(self::$fetchModeMap[$fetchMode])) { if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode)); throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
} }
...@@ -274,20 +263,12 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -274,20 +263,12 @@ final class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$fetchMode = $fetchMode ?? $this->_defaultFetchMode; $fetchMode = $fetchMode ?? $this->_defaultFetchMode;
$result = []; $result = [];
if ($fetchMode === FetchMode::STANDARD_OBJECT) {
while ($row = $this->fetch($fetchMode)) {
$result[] = $row;
}
return $result;
}
if (! isset(self::$fetchModeMap[$fetchMode])) { if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode)); throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
} }
...@@ -328,7 +309,7 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -328,7 +309,7 @@ final class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
// 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 result
// in order to prevent exceptional situation // in order to prevent exceptional situation
...@@ -342,11 +323,7 @@ final class OCI8Statement implements IteratorAggregate, Statement ...@@ -342,11 +323,7 @@ final class OCI8Statement implements IteratorAggregate, Statement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
public function rowCount() : int public function rowCount() : int
......
...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Driver; ...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Exception\UnknownFetchMode; use Doctrine\DBAL\Driver\Exception\UnknownFetchMode;
use Doctrine\DBAL\Driver\Exception\UnknownParamType; use Doctrine\DBAL\Driver\Exception\UnknownParamType;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
...@@ -33,12 +32,10 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -33,12 +32,10 @@ class PDOStatement implements IteratorAggregate, Statement
]; ];
private const FETCH_MODE_MAP = [ private const FETCH_MODE_MAP = [
FetchMode::ASSOCIATIVE => PDO::FETCH_ASSOC, FetchMode::ASSOCIATIVE => PDO::FETCH_ASSOC,
FetchMode::NUMERIC => PDO::FETCH_NUM, FetchMode::NUMERIC => PDO::FETCH_NUM,
FetchMode::MIXED => PDO::FETCH_BOTH, FetchMode::MIXED => PDO::FETCH_BOTH,
FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ, FetchMode::COLUMN => PDO::FETCH_COLUMN,
FetchMode::COLUMN => PDO::FETCH_COLUMN,
FetchMode::CUSTOM_OBJECT => PDO::FETCH_CLASS,
]; ];
/** @var \PDOStatement */ /** @var \PDOStatement */
...@@ -49,15 +46,12 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -49,15 +46,12 @@ class PDOStatement implements IteratorAggregate, Statement
$this->stmt = $stmt; $this->stmt = $stmt;
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$fetchMode = $this->convertFetchMode($fetchMode); $fetchMode = $this->convertFetchMode($fetchMode);
try { try {
$this->stmt->setFetchMode($fetchMode, ...$args); $this->stmt->setFetchMode($fetchMode);
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
...@@ -128,16 +122,16 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -128,16 +122,16 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
try { try {
if ($fetchMode === null) { if ($fetchMode === null) {
return $this->stmt->fetch(); return $this->stmt->fetch();
} }
$fetchMode = $this->convertFetchMode($fetchMode); return $this->stmt->fetch(
$this->convertFetchMode($fetchMode)
return $this->stmt->fetch($fetchMode, ...$args); );
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
...@@ -146,15 +140,14 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -146,15 +140,14 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
try { try {
if ($fetchMode === null) { if ($fetchMode === null) {
$data = $this->stmt->fetchAll(); $data = $this->stmt->fetchAll();
} else { } else {
$data = $this->stmt->fetchAll( $data = $this->stmt->fetchAll(
$this->convertFetchMode($fetchMode), $this->convertFetchMode($fetchMode)
...$args
); );
} }
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
...@@ -169,20 +162,10 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -169,20 +162,10 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
try { try {
$value = $this->stmt->fetchColumn($columnIndex); return $this->stmt->fetchColumn();
if ($value === null) {
$columnCount = $this->columnCount();
if ($columnIndex < 0 || $columnIndex >= $columnCount) {
throw InvalidColumnIndex::new($columnIndex, $columnCount);
}
}
return $value;
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
......
...@@ -39,11 +39,10 @@ interface ResultStatement extends Traversable ...@@ -39,11 +39,10 @@ interface ResultStatement extends Traversable
/** /**
* Sets the fetch mode to use while iterating this statement. * Sets the fetch mode to use while iterating this statement.
* *
* @param int $fetchMode Controls how the next row will be returned to the caller. * @param int $fetchMode Controls how the next row will be returned to the caller.
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants. * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants.
* @param mixed ...$args Optional mode-specific arguments (see {@link self::fetchAll()}).
*/ */
public function setFetchMode(int $fetchMode, ...$args) : void; public function setFetchMode(int $fetchMode) : void;
/** /**
* Returns the next row of a result set. * Returns the next row of a result set.
...@@ -51,12 +50,11 @@ interface ResultStatement extends Traversable ...@@ -51,12 +50,11 @@ interface ResultStatement extends Traversable
* @param int|null $fetchMode Controls how the next row will be returned to the caller. * @param int|null $fetchMode Controls how the next row will be returned to the caller.
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants, * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
* defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}. * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
* @param mixed ...$args Optional mode-specific arguments (see {@link self::fetchAll()}).
* *
* @return mixed The return value of this method on success depends on the fetch mode. In all cases, FALSE is * @return mixed The return value of this method on success depends on the fetch mode. In all cases, FALSE is
* returned on failure. * returned on failure.
*/ */
public function fetch(?int $fetchMode = null, ...$args); public function fetch(?int $fetchMode = null);
/** /**
* Returns an array containing all of the result set rows. * Returns an array containing all of the result set rows.
...@@ -64,24 +62,15 @@ interface ResultStatement extends Traversable ...@@ -64,24 +62,15 @@ interface ResultStatement extends Traversable
* @param int|null $fetchMode Controls how the next row will be returned to the caller. * @param int|null $fetchMode Controls how the next row will be returned to the caller.
* The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants, * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
* defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}. * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
* @param mixed ...$args Optional mode-specific arguments. Supported modes:
* * {@link \Doctrine\DBAL\FetchMode::COLUMN}
* 1. The 0-indexed column to be returned.
* * {@link \Doctrine\DBAL\FetchMode::CUSTOM_OBJECT}
* 1. The classname of the object to be created,
* 2. Array of constructor arguments
* *
* @return mixed[] * @return mixed[]
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array; public function fetchAll(?int $fetchMode = null) : array;
/** /**
* Returns a single column from the next row of a result set or FALSE if there are no more rows. * Returns a single column from the next row of a result set or FALSE if there are no more rows.
* *
* @param int $columnIndex 0-indexed number of the column you wish to retrieve from the row.
* If no value is supplied, fetches the first column.
*
* @return mixed|false A single column in the next row of a result set, or FALSE if there are no more rows. * @return mixed|false A single column in the next row of a result set, or FALSE if there are no more rows.
*/ */
public function fetchColumn(int $columnIndex = 0); public function fetchColumn();
} }
...@@ -7,23 +7,15 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere; ...@@ -7,23 +7,15 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\GetVariableType; use Doctrine\DBAL\Exception\GetVariableType;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use ReflectionClass;
use ReflectionObject;
use stdClass;
use function array_key_exists; use function array_key_exists;
use function assert; use function assert;
use function count;
use function is_int; use function is_int;
use function is_object;
use function is_resource; use function is_resource;
use function is_string;
use function sasql_fetch_array; use function sasql_fetch_array;
use function sasql_fetch_assoc; use function sasql_fetch_assoc;
use function sasql_fetch_object;
use function sasql_fetch_row; use function sasql_fetch_row;
use function sasql_prepare; use function sasql_prepare;
use function sasql_stmt_affected_rows; use function sasql_stmt_affected_rows;
...@@ -43,12 +35,6 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -43,12 +35,6 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
/** @var resource The connection resource. */ /** @var resource The connection resource. */
private $conn; private $conn;
/** @var string Name of the default class to instantiate when fetching class instances. */
private $defaultFetchClass = '\stdClass';
/** @var mixed[] Constructor arguments for the default class to instantiate when fetching class instances. */
private $defaultFetchClassCtorArgs = [];
/** @var int Default fetch mode to use. */ /** @var int Default fetch mode to use. */
private $defaultFetchMode = FetchMode::MIXED; private $defaultFetchMode = FetchMode::MIXED;
...@@ -171,7 +157,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -171,7 +157,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
* *
* @throws SQLAnywhereException * @throws SQLAnywhereException
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
if (! is_resource($this->result)) { if (! is_resource($this->result)) {
return false; return false;
...@@ -189,29 +175,9 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -189,29 +175,9 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
case FetchMode::MIXED: case FetchMode::MIXED:
return sasql_fetch_array($this->result, SASQL_BOTH); return sasql_fetch_array($this->result, SASQL_BOTH);
case FetchMode::CUSTOM_OBJECT:
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
if (count($args) > 0) {
$className = $args[0];
$ctorArgs = $args[1] ?? [];
}
$result = sasql_fetch_object($this->result);
if ($result instanceof stdClass) {
$result = $this->castObject($result, $className, $ctorArgs);
}
return $result;
case FetchMode::NUMERIC: case FetchMode::NUMERIC:
return sasql_fetch_row($this->result); return sasql_fetch_row($this->result);
case FetchMode::STANDARD_OBJECT:
return sasql_fetch_object($this->result);
default: default:
throw new SQLAnywhereException(sprintf('Fetch mode is not supported %d.', $fetchMode)); throw new SQLAnywhereException(sprintf('Fetch mode is not supported %d.', $fetchMode));
} }
...@@ -220,18 +186,11 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -220,18 +186,11 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$rows = []; $rows = [];
switch ($fetchMode) { switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
while (($row = $this->fetch($fetchMode, ...$args)) !== false) {
$rows[] = $row;
}
break;
case FetchMode::COLUMN: case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) { while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row; $rows[] = $row;
...@@ -251,7 +210,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -251,7 +210,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -259,11 +218,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -259,11 +218,7 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
/** /**
...@@ -279,66 +234,8 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -279,66 +234,8 @@ final class SQLAnywhereStatement implements IteratorAggregate, Statement
return sasql_stmt_affected_rows($this->stmt); return sasql_stmt_affected_rows($this->stmt);
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (! isset($args[1])) {
return;
}
$this->defaultFetchClassCtorArgs = (array) $args[1];
}
/**
* Casts a stdClass object to the given class name mapping its' properties.
*
* @param stdClass $sourceObject Object to cast from.
* @param string|object $destinationClass Name of the class or class instance to cast to.
* @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance.
*
* @throws SQLAnywhereException
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) : object
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
throw new SQLAnywhereException(sprintf(
'Destination class has to be of type string or object, "%s" given.',
(new GetVariableType())->__invoke($destinationClass)
));
}
} else {
$destinationClass = new ReflectionClass($destinationClass);
$destinationClass = $destinationClass->newInstanceArgs($ctorArgs);
}
$sourceReflection = new ReflectionObject($sourceObject);
$destinationClassReflection = new ReflectionObject($destinationClass);
foreach ($sourceReflection->getProperties() as $sourceProperty) {
$sourceProperty->setAccessible(true);
$name = $sourceProperty->getName();
$value = $sourceProperty->getValue($sourceObject);
if ($destinationClassReflection->hasProperty($name)) {
$destinationProperty = $destinationClassReflection->getProperty($name);
$destinationProperty->setAccessible(true);
$destinationProperty->setValue($destinationClass, $value);
} else {
$destinationClass->$name = $value;
}
}
return $destinationClass;
} }
} }
...@@ -6,19 +6,14 @@ namespace Doctrine\DBAL\Driver\SQLSrv; ...@@ -6,19 +6,14 @@ namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator; use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use IteratorAggregate; use IteratorAggregate;
use function array_key_exists;
use function assert; use function assert;
use function count;
use function in_array;
use function is_int; use function is_int;
use function sqlsrv_execute; use function sqlsrv_execute;
use function sqlsrv_fetch; use function sqlsrv_fetch;
use function sqlsrv_fetch_array; use function sqlsrv_fetch_array;
use function sqlsrv_fetch_object;
use function sqlsrv_get_field; use function sqlsrv_get_field;
use function sqlsrv_next_result; use function sqlsrv_next_result;
use function sqlsrv_num_fields; use function sqlsrv_num_fields;
...@@ -85,20 +80,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -85,20 +80,6 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
FetchMode::NUMERIC => SQLSRV_FETCH_NUMERIC, FetchMode::NUMERIC => SQLSRV_FETCH_NUMERIC,
]; ];
/**
* The name of the default class to instantiate when fetching class instances.
*
* @var string
*/
private $defaultFetchClass = '\stdClass';
/**
* The constructor arguments for the default class to instantiate when fetching class instances.
*
* @var mixed[]
*/
private $defaultFetchClassCtorArgs = [];
/** /**
* The fetch style. * The fetch style.
* *
...@@ -230,22 +211,9 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -230,22 +211,9 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (! isset($args[1])) {
return;
}
$this->defaultFetchClassCtorArgs = (array) $args[1];
} }
/** /**
...@@ -261,7 +229,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -261,7 +229,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
* *
* @throws SQLSrvException * @throws SQLSrvException
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
// 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 result
// in order to prevent exceptional situation // in order to prevent exceptional situation
...@@ -279,36 +247,17 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -279,36 +247,17 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]) ?? false; return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]) ?? false;
} }
if (in_array($fetchMode, [FetchMode::STANDARD_OBJECT, FetchMode::CUSTOM_OBJECT], true)) {
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
if (count($args) > 0) {
$className = $args[0];
$ctorArgs = $args[1] ?? [];
}
return sqlsrv_fetch_object($this->stmt, $className, $ctorArgs) ?? false;
}
throw new SQLSrvException('Fetch mode is not supported.'); throw new SQLSrvException('Fetch mode is not supported.');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$rows = []; $rows = [];
switch ($fetchMode) { switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
while (($row = $this->fetch($fetchMode, ...$args)) !== false) {
$rows[] = $row;
}
break;
case FetchMode::COLUMN: case FetchMode::COLUMN:
while (($row = $this->fetchColumn()) !== false) { while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row; $rows[] = $row;
...@@ -328,7 +277,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -328,7 +277,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -336,11 +285,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -336,11 +285,7 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
return false; return false;
} }
if (! array_key_exists($columnIndex, $row)) { return $row[0];
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
} }
public function rowCount() : int public function rowCount() : int
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Exception;
use Doctrine\DBAL\DBALException;
use function sprintf;
final class InvalidColumnIndex extends DBALException
{
public static function new(int $index, int $count) : self
{
return new self(sprintf(
'Invalid column index %d. The statement result contains %d column%s.',
$index,
$count,
$count === 1 ? '' : 's'
));
}
}
...@@ -37,15 +37,6 @@ final class FetchMode ...@@ -37,15 +37,6 @@ final class FetchMode
*/ */
public const MIXED = 4; public const MIXED = 4;
/**
* Specifies that the fetch method shall return each row as an object with
* property names that correspond to the column names returned in the result
* set.
*
* @see \PDO::FETCH_OBJ
*/
public const STANDARD_OBJECT = 5;
/** /**
* Specifies that the fetch method shall return only a single requested * Specifies that the fetch method shall return only a single requested
* column from the next row in the result set. * column from the next row in the result set.
...@@ -54,14 +45,6 @@ final class FetchMode ...@@ -54,14 +45,6 @@ final class FetchMode
*/ */
public const COLUMN = 7; public const COLUMN = 7;
/**
* Specifies that the fetch method shall return a new instance of the
* requested class, mapping the columns to named properties in the class.
*
* @see \PDO::FETCH_CLASS
*/
public const CUSTOM_OBJECT = 8;
/** /**
* This class cannot be instantiated. * This class cannot be instantiated.
*/ */
......
...@@ -84,14 +84,11 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -84,14 +84,11 @@ final class Statement implements IteratorAggregate, DriverStatement
$this->stmt->execute($params); $this->stmt->execute($params);
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
$this->stmt->setFetchMode($fetchMode, ...$args); $this->stmt->setFetchMode($fetchMode);
} }
/** /**
...@@ -105,11 +102,11 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -105,11 +102,11 @@ final class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; $fetchMode = $fetchMode ?? $this->defaultFetchMode;
$row = $this->stmt->fetch($fetchMode, ...$args); $row = $this->stmt->fetch($fetchMode);
$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 = $this->case !== null
...@@ -124,11 +121,11 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -124,11 +121,11 @@ final class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
$fetchMode = $fetchMode ?? $this->defaultFetchMode; $fetchMode = $fetchMode ?? $this->defaultFetchMode;
$rows = $this->stmt->fetchAll($fetchMode, ...$args); $rows = $this->stmt->fetchAll($fetchMode);
$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 = $this->case !== null
...@@ -161,9 +158,9 @@ final class Statement implements IteratorAggregate, DriverStatement ...@@ -161,9 +158,9 @@ final class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
$value = $this->stmt->fetchColumn($columnIndex); $value = $this->stmt->fetchColumn();
if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $value === '') { if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $value === '') {
$value = null; $value = null;
......
...@@ -180,12 +180,9 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -180,12 +180,9 @@ class Statement implements IteratorAggregate, DriverStatement
return $this->stmt->columnCount(); return $this->stmt->columnCount();
} }
/** public function setFetchMode(int $fetchMode) : void
* {@inheritdoc}
*/
public function setFetchMode(int $fetchMode, ...$args) : void
{ {
$this->stmt->setFetchMode($fetchMode, ...$args); $this->stmt->setFetchMode($fetchMode);
} }
/** /**
...@@ -201,25 +198,25 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -201,25 +198,25 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch(?int $fetchMode = null, ...$args) public function fetch(?int $fetchMode = null)
{ {
return $this->stmt->fetch($fetchMode, ...$args); return $this->stmt->fetch($fetchMode);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll(?int $fetchMode = null, ...$args) : array public function fetchAll(?int $fetchMode = null) : array
{ {
return $this->stmt->fetchAll($fetchMode, ...$args); return $this->stmt->fetchAll($fetchMode);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function fetchColumn(int $columnIndex = 0) public function fetchColumn()
{ {
return $this->stmt->fetchColumn($columnIndex); return $this->stmt->fetchColumn();
} }
/** /**
......
...@@ -59,16 +59,6 @@ class ArrayStatementTest extends TestCase ...@@ -59,16 +59,6 @@ class ArrayStatementTest extends TestCase
self::assertSame($this->users[0], $statement->fetch()); self::assertSame($this->users[0], $statement->fetch());
} }
public function testSetFetchModeThrowsInvalidArgumentException() : void
{
$statement = $this->createTestArrayStatement();
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Caching layer does not support 2nd/3rd argument to setFetchMode().');
$statement->setFetchMode(FetchMode::ASSOCIATIVE, 'arg1', 'arg2');
}
public function testGetIterator() : void public function testGetIterator() : void
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
...@@ -131,13 +121,8 @@ class ArrayStatementTest extends TestCase ...@@ -131,13 +121,8 @@ class ArrayStatementTest extends TestCase
{ {
$statement = $this->createTestArrayStatement(); $statement = $this->createTestArrayStatement();
self::assertSame('jwage', $statement->fetchColumn(0)); self::assertSame('jwage', $statement->fetchColumn());
self::assertSame('romanb', $statement->fetchColumn(0)); self::assertSame('romanb', $statement->fetchColumn());
$statement = $this->createTestArrayStatement();
self::assertTrue($statement->fetchColumn(1));
self::assertFalse($statement->fetchColumn(1));
} }
private function createTestArrayStatement() : ArrayStatement private function createTestArrayStatement() : ArrayStatement
......
...@@ -573,7 +573,6 @@ class ConnectionTest extends TestCase ...@@ -573,7 +573,6 @@ class ConnectionTest extends TestCase
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
$params = [666]; $params = [666];
$types = [ParameterType::INTEGER]; $types = [ParameterType::INTEGER];
$column = 0;
$result = []; $result = [];
$driverMock = $this->createMock(Driver::class); $driverMock = $this->createMock(Driver::class);
...@@ -588,7 +587,6 @@ class ConnectionTest extends TestCase ...@@ -588,7 +587,6 @@ class ConnectionTest extends TestCase
$driverStatementMock->expects(self::once()) $driverStatementMock->expects(self::once())
->method('fetchColumn') ->method('fetchColumn')
->with($column)
->will(self::returnValue($result)); ->will(self::returnValue($result));
/** @var Connection|MockObject $conn */ /** @var Connection|MockObject $conn */
...@@ -602,7 +600,7 @@ class ConnectionTest extends TestCase ...@@ -602,7 +600,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->fetchColumn($statement, $params, $column, $types)); self::assertSame($result, $conn->fetchColumn($statement, $params, $types));
} }
public function testFetchAll() : void public function testFetchAll() : void
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Exception;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use PHPUnit\Framework\TestCase;
class InvalidColumnIndexTest extends TestCase
{
public function testNew() : void
{
$exception = InvalidColumnIndex::new(5, 1);
self::assertSame('Invalid column index 5. The statement result contains 1 column.', $exception->getMessage());
}
public function testNewPlural() : void
{
$exception = InvalidColumnIndex::new(5, 2);
self::assertSame('Invalid column index 5. The statement result contains 2 columns.', $exception->getMessage());
}
}
...@@ -8,9 +8,6 @@ use DateTime; ...@@ -8,9 +8,6 @@ use DateTime;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Mysqli\Driver as MySQLiDriver; use Doctrine\DBAL\Driver\Mysqli\Driver as MySQLiDriver;
use Doctrine\DBAL\Driver\OCI8\Driver as Oci8Driver;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver;
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver; use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
...@@ -19,11 +16,9 @@ use Doctrine\DBAL\Platforms\SqlitePlatform; ...@@ -19,11 +16,9 @@ use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Platforms\TrimMode; use Doctrine\DBAL\Platforms\TrimMode;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Statement; use Doctrine\DBAL\Statement;
use Doctrine\DBAL\Tests\Functional\DataAccess\FetchClass;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use InvalidArgumentException; use InvalidArgumentException;
use PDO;
use function array_change_key_case; use function array_change_key_case;
use function array_filter; use function array_filter;
use function array_keys; use function array_keys;
...@@ -33,7 +28,6 @@ use function date; ...@@ -33,7 +28,6 @@ use function date;
use function is_array; use function is_array;
use function is_numeric; use function is_numeric;
use function json_encode; use function json_encode;
use function property_exists;
use function sprintf; use function sprintf;
use function strtotime; use function strtotime;
use const CASE_LOWER; use const CASE_LOWER;
...@@ -384,13 +378,13 @@ class DataAccessTest extends FunctionalTestCase ...@@ -384,13 +378,13 @@ class DataAccessTest extends FunctionalTestCase
public function testFetchColumn() : void public function testFetchColumn() : void
{ {
$sql = 'SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?'; $sql = 'SELECT test_int FROM fetch_table WHERE test_int = ? AND test_string = ?';
$testInt = $this->connection->fetchColumn($sql, [1, 'foo'], 0); $testInt = $this->connection->fetchColumn($sql, [1, 'foo']);
self::assertEquals(1, $testInt); self::assertEquals(1, $testInt);
$sql = 'SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?'; $sql = 'SELECT test_string FROM fetch_table WHERE test_int = ? AND test_string = ?';
$testString = $this->connection->fetchColumn($sql, [1, 'foo'], 1); $testString = $this->connection->fetchColumn($sql, [1, 'foo']);
self::assertEquals('foo', $testString); self::assertEquals('foo', $testString);
} }
...@@ -400,15 +394,14 @@ class DataAccessTest extends FunctionalTestCase ...@@ -400,15 +394,14 @@ class DataAccessTest extends FunctionalTestCase
$datetimeString = '2010-01-01 10:10:10'; $datetimeString = '2010-01-01 10:10:10';
$datetime = new DateTime($datetimeString); $datetime = new DateTime($datetimeString);
$sql = 'SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?'; $sql = 'SELECT test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?';
$column = $this->connection->fetchColumn( $column = $this->connection->fetchColumn(
$sql, $sql,
[1, $datetime], [1, $datetime],
1,
[ParameterType::STRING, Types::DATETIME_MUTABLE] [ParameterType::STRING, Types::DATETIME_MUTABLE]
); );
self::assertNotFalse($column); self::assertIsString($column);
self::assertStringStartsWith($datetimeString, $column); self::assertStringStartsWith($datetimeString, $column);
} }
...@@ -426,7 +419,7 @@ class DataAccessTest extends FunctionalTestCase ...@@ -426,7 +419,7 @@ class DataAccessTest extends FunctionalTestCase
$this->expectException(DBALException::class); $this->expectException(DBALException::class);
$this->connection->fetchColumn($sql, [1, $datetime], 1); $this->connection->fetchColumn($sql, [1, $datetime]);
} }
/** /**
...@@ -913,7 +906,7 @@ class DataAccessTest extends FunctionalTestCase ...@@ -913,7 +906,7 @@ class DataAccessTest extends FunctionalTestCase
$sql = 'SELECT COUNT(*) FROM fetch_table_date_math WHERE '; $sql = 'SELECT COUNT(*) FROM fetch_table_date_math WHERE ';
$sql .= $platform->getDateSubDaysExpression('test_date', 'test_days') . " < '2010-05-12'"; $sql .= $platform->getDateSubDaysExpression('test_date', 'test_days') . " < '2010-05-12'";
$rowCount = $this->connection->fetchColumn($sql, [], 0); $rowCount = $this->connection->fetchColumn($sql);
self::assertEquals(1, $rowCount); self::assertEquals(1, $rowCount);
} }
...@@ -1059,62 +1052,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -1059,62 +1052,6 @@ class DataAccessTest extends FunctionalTestCase
}), 'should be no non-numerical elements in the result.'); }), 'should be no non-numerical elements in the result.');
} }
/**
* @group DBAL-1091
*/
public function testFetchAllStyleObject() : void
{
$this->setupFixture();
$sql = 'SELECT test_int, test_string, test_datetime FROM fetch_table';
$stmt = $this->connection->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll(FetchMode::STANDARD_OBJECT);
self::assertCount(1, $results);
self::assertInstanceOf('stdClass', $results[0]);
self::assertEquals(
1,
property_exists($results[0], 'test_int') ? $results[0]->test_int : $results[0]->TEST_INT
);
self::assertEquals(
'foo',
property_exists($results[0], 'test_string') ? $results[0]->test_string : $results[0]->TEST_STRING
);
self::assertStringStartsWith(
'2010-01-01 10:10:10',
property_exists($results[0], 'test_datetime') ? $results[0]->test_datetime : $results[0]->TEST_DATETIME
);
}
/**
* @group DBAL-196
*/
public function testFetchAllSupportFetchClass() : void
{
$this->beforeFetchClassTest();
$this->setupFixture();
$sql = 'SELECT test_int, test_string, test_datetime FROM fetch_table';
$stmt = $this->connection->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll(
FetchMode::CUSTOM_OBJECT,
FetchClass::class
);
self::assertCount(1, $results);
self::assertInstanceOf(FetchClass::class, $results[0]);
self::assertEquals(1, $results[0]->test_int);
self::assertEquals('foo', $results[0]->test_string);
self::assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
}
/** /**
* @group DBAL-241 * @group DBAL-241
*/ */
...@@ -1132,53 +1069,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -1132,53 +1069,6 @@ class DataAccessTest extends FunctionalTestCase
self::assertEquals([1, 10], $rows); self::assertEquals([1, 10], $rows);
} }
/**
* @group DBAL-214
*/
public function testSetFetchModeClassFetchAll() : void
{
$this->beforeFetchClassTest();
$this->setupFixture();
$sql = 'SELECT * FROM fetch_table';
$stmt = $this->connection->query($sql);
$stmt->setFetchMode(FetchMode::CUSTOM_OBJECT, FetchClass::class);
$results = $stmt->fetchAll();
self::assertCount(1, $results);
self::assertInstanceOf(FetchClass::class, $results[0]);
self::assertEquals(1, $results[0]->test_int);
self::assertEquals('foo', $results[0]->test_string);
self::assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
}
/**
* @group DBAL-214
*/
public function testSetFetchModeClassFetch() : void
{
$this->beforeFetchClassTest();
$this->setupFixture();
$sql = 'SELECT * FROM fetch_table';
$stmt = $this->connection->query($sql);
$stmt->setFetchMode(FetchMode::CUSTOM_OBJECT, FetchClass::class);
$results = [];
while ($row = $stmt->fetch()) {
$results[] = $row;
}
self::assertCount(1, $results);
self::assertInstanceOf(FetchClass::class, $results[0]);
self::assertEquals(1, $results[0]->test_int);
self::assertEquals('foo', $results[0]->test_string);
self::assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
}
/** /**
* @group DBAL-257 * @group DBAL-257
*/ */
...@@ -1219,21 +1109,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -1219,21 +1109,6 @@ class DataAccessTest extends FunctionalTestCase
self::assertEquals([], $rows); self::assertEquals([], $rows);
} }
/**
* @group DBAL-1028
*/
public function testFetchColumnNullValue() : void
{
$this->connection->executeUpdate(
'INSERT INTO fetch_table (test_int, test_string) VALUES (?, ?)',
[2, 'foo']
);
self::assertNull(
$this->connection->fetchColumn('SELECT test_datetime FROM fetch_table WHERE test_int = ?', [2])
);
}
/** /**
* @group DBAL-1028 * @group DBAL-1028
*/ */
...@@ -1243,36 +1118,4 @@ class DataAccessTest extends FunctionalTestCase ...@@ -1243,36 +1118,4 @@ class DataAccessTest extends FunctionalTestCase
$this->connection->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1]) $this->connection->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1])
); );
} }
private function setupFixture() : void
{
$this->connection->exec('DELETE FROM fetch_table');
$this->connection->insert('fetch_table', [
'test_int' => 1,
'test_string' => 'foo',
'test_datetime' => '2010-01-01 10:10:10',
]);
}
private function beforeFetchClassTest() : void
{
$driver = $this->connection->getDriver();
if ($driver instanceof Oci8Driver) {
self::markTestSkipped('Not supported by OCI8');
}
if ($driver instanceof MySQLiDriver) {
self::markTestSkipped('Mysqli driver dont support this feature.');
}
if (! $driver instanceof PDOOracleDriver) {
return;
}
/** @var PDOConnection $connection */
$connection = $this->connection
->getWrappedConnection();
$connection->getWrappedConnection()->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
}
} }
...@@ -25,7 +25,10 @@ class SQLAnywhereSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -25,7 +25,10 @@ class SQLAnywhereSchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertCount(1, $views, 'Database has to have one view.'); self::assertCount(1, $views, 'Database has to have one view.');
self::assertEquals($name, $views[$name]->getName()); self::assertEquals($name, $views[$name]->getName());
self::assertRegExp('/^SELECT \* from "?DBA"?\."?view_test_table"?$/', $views[$name]->getSql()); self::assertMatchesRegularExpression(
'/^SELECT \* from "?DBA"?\."?view_test_table"?$/',
$views[$name]->getSql()
);
} }
public function testDropAndCreateAdvancedIndex() : void public function testDropAndCreateAdvancedIndex() : void
......
...@@ -37,7 +37,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -37,7 +37,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->createDatabase($path); $this->schemaManager->createDatabase($path);
self::assertFileExists($path); self::assertFileExists($path);
$this->schemaManager->dropDatabase($path); $this->schemaManager->dropDatabase($path);
self::assertFileNotExists($path); self::assertFileDoesNotExist($path);
} }
/** /**
...@@ -59,7 +59,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -59,7 +59,7 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->dropDatabase('test_drop_database'); $this->schemaManager->dropDatabase('test_drop_database');
self::assertFileNotExists('test_drop_database'); self::assertFileDoesNotExist('test_drop_database');
unset($connection); unset($connection);
} }
......
...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Tests\Functional; ...@@ -6,7 +6,6 @@ namespace Doctrine\DBAL\Tests\Functional;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver; use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySQLDriver; use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySQLDriver;
use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver; use Doctrine\DBAL\Driver\PDOOracle\Driver as PDOOracleDriver;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSRVDriver; use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSRVDriver;
...@@ -377,34 +376,4 @@ EOF ...@@ -377,34 +376,4 @@ EOF
$this->expectException(DBALException::class); $this->expectException(DBALException::class);
$stmt->execute([null]); $stmt->execute([null]);
} }
/**
* @throws DBALException
*
* @dataProvider nonExistingIndexProvider
*/
public function testFetchColumnNonExistingIndex(int $index) : void
{
if ($this->connection->getWrappedConnection() instanceof PDOConnection) {
self::markTestSkipped('PDO supports this behavior natively but throws a different exception');
}
$platform = $this->connection->getDatabasePlatform();
$query = $platform->getDummySelectSQL();
$stmt = $this->connection->query($query);
$this->expectException(DBALException::class);
$stmt->fetchColumn($index);
}
/**
* @return mixed[][]
*/
public static function nonExistingIndexProvider() : iterable
{
return [
[1],
[-1],
];
}
} }
...@@ -77,7 +77,6 @@ class BinaryTest extends FunctionalTestCase ...@@ -77,7 +77,6 @@ class BinaryTest extends FunctionalTestCase
$value = $this->connection->fetchColumn( $value = $this->connection->fetchColumn(
'SELECT val FROM binary_table WHERE id = ?', 'SELECT val FROM binary_table WHERE id = ?',
[$id], [$id],
0,
[ParameterType::BINARY] [ParameterType::BINARY]
); );
......
...@@ -5,13 +5,11 @@ declare(strict_types=1); ...@@ -5,13 +5,11 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Portability; namespace Doctrine\DBAL\Tests\Portability;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Portability\Connection; 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 ReflectionProperty;
use function iterator_to_array; use function iterator_to_array;
class StatementTest extends TestCase class StatementTest extends TestCase
...@@ -95,25 +93,6 @@ class StatementTest extends TestCase ...@@ -95,25 +93,6 @@ class StatementTest extends TestCase
$this->stmt->execute($params); $this->stmt->execute($params);
} }
public function testSetFetchMode() : void
{
$fetchMode = FetchMode::CUSTOM_OBJECT;
$arg1 = 'MyClass';
$arg2 = [1, 2];
$this->wrappedStmt->expects(self::once())
->method('setFetchMode')
->with($fetchMode, $arg1, $arg2)
->will(self::returnValue(true));
$re = new ReflectionProperty($this->stmt, 'defaultFetchMode');
$re->setAccessible(true);
self::assertSame(FetchMode::MIXED, $re->getValue($this->stmt));
$this->stmt->setFetchMode($fetchMode, $arg1, $arg2);
self::assertSame($fetchMode, $re->getValue($this->stmt));
}
public function testGetIterator() : void public function testGetIterator() : void
{ {
$this->wrappedStmt->expects(self::exactly(3)) $this->wrappedStmt->expects(self::exactly(3))
......
...@@ -10,7 +10,6 @@ use Doctrine\DBAL\DBALException; ...@@ -10,7 +10,6 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection; use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Logging\SQLLogger; use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Statement; use Doctrine\DBAL\Statement;
...@@ -151,15 +150,4 @@ class StatementTest extends TestCase ...@@ -151,15 +150,4 @@ class StatementTest extends TestCase
$statement->execute(); $statement->execute();
} }
public function testPDOCustomClassConstructorArgs() : void
{
$statement = new Statement('', $this->conn);
$this->driverStatement->expects(self::once())
->method('fetchAll')
->with(self::equalTo(FetchMode::CUSTOM_OBJECT), self::equalTo('Example'), self::equalTo(['arg1']));
$statement->fetchAll(FetchMode::CUSTOM_OBJECT, 'Example', ['arg1']);
}
} }
...@@ -75,8 +75,8 @@ class RunSqlCommandTest extends TestCase ...@@ -75,8 +75,8 @@ class RunSqlCommandTest extends TestCase
]); ]);
self::assertSame(0, $exitCode); self::assertSame(0, $exitCode);
self::assertRegExp('@int.*1.*@', $this->commandTester->getDisplay()); self::assertMatchesRegularExpression('@int.*1.*@', $this->commandTester->getDisplay());
self::assertRegExp('@array.*1.*@', $this->commandTester->getDisplay()); self::assertMatchesRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
} }
public function testUpdateStatementsPrintsAffectedLines() : void public function testUpdateStatementsPrintsAffectedLines() : void
...@@ -88,8 +88,8 @@ class RunSqlCommandTest extends TestCase ...@@ -88,8 +88,8 @@ class RunSqlCommandTest extends TestCase
'sql' => 'UPDATE foo SET bar = 42', 'sql' => 'UPDATE foo SET bar = 42',
]); ]);
self::assertRegExp('@int.*42.*@', $this->commandTester->getDisplay()); self::assertMatchesRegularExpression('@int.*42.*@', $this->commandTester->getDisplay());
self::assertNotRegExp('@array.*1.*@', $this->commandTester->getDisplay()); self::assertDoesNotMatchRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
} }
private function expectConnectionExecuteUpdate() : void private function expectConnectionExecuteUpdate() : void
...@@ -122,7 +122,7 @@ class RunSqlCommandTest extends TestCase ...@@ -122,7 +122,7 @@ class RunSqlCommandTest extends TestCase
'--force-fetch' => true, '--force-fetch' => true,
]); ]);
self::assertRegExp('@int.*1.*@', $this->commandTester->getDisplay()); self::assertMatchesRegularExpression('@int.*1.*@', $this->commandTester->getDisplay());
self::assertRegExp('@array.*1.*@', $this->commandTester->getDisplay()); self::assertMatchesRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
} }
} }
...@@ -14,7 +14,7 @@ class TypeAlreadyRegisteredTest extends TestCase ...@@ -14,7 +14,7 @@ class TypeAlreadyRegisteredTest extends TestCase
{ {
$exception = TypeAlreadyRegistered::new(Type::getType('string')); $exception = TypeAlreadyRegistered::new(Type::getType('string'));
self::assertRegExp( self::assertMatchesRegularExpression(
'/Type of the class Doctrine\\\DBAL\\\Types\\\StringType@([0-9a-zA-Z]+) is already registered./', '/Type of the class Doctrine\\\DBAL\\\Types\\\StringType@([0-9a-zA-Z]+) is already registered./',
$exception->getMessage() $exception->getMessage()
); );
......
...@@ -14,7 +14,7 @@ class TypeNotRegisteredTest extends TestCase ...@@ -14,7 +14,7 @@ class TypeNotRegisteredTest extends TestCase
{ {
$exception = TypeNotRegistered::new(Type::getType('string')); $exception = TypeNotRegistered::new(Type::getType('string'));
self::assertRegExp( self::assertMatchesRegularExpression(
'/Type of the class Doctrine\\\DBAL\\\Types\\\StringType@([0-9a-zA-Z]+) is not registered./', '/Type of the class Doctrine\\\DBAL\\\Types\\\StringType@([0-9a-zA-Z]+) is not registered./',
$exception->getMessage() $exception->getMessage()
); );
......
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