Unverified Commit e6349bab authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3070 from morozov/stmt-fetch-mode-args-cleanup

Dropped support of fetching objects and non-zero column
parents 438befbc aa6ae1d6
# 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.
......
...@@ -98,12 +98,6 @@ parameters: ...@@ -98,12 +98,6 @@ parameters:
- %currentWorkingDirectory%/src/Query/QueryBuilder.php - %currentWorkingDirectory%/src/Query/QueryBuilder.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 .*~'
......
...@@ -60,12 +60,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -60,12 +60,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode()');
}
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
return true; return true;
...@@ -84,7 +80,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -84,7 +80,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($fetchMode = null)
{ {
if (! isset($this->data[$this->num])) { if (! isset($this->data[$this->num])) {
return false; return false;
...@@ -115,10 +111,10 @@ class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -115,10 +111,10 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$rows = []; $rows = [];
while ($row = $this->fetch($fetchMode, ...$args)) { while ($row = $this->fetch($fetchMode)) {
$rows[] = $row; $rows[] = $row;
} }
...@@ -128,11 +124,11 @@ class ArrayStatement implements IteratorAggregate, ResultStatement ...@@ -128,11 +124,11 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
// TODO: verify that return false is the correct behavior // TODO: verify that return false is the correct behavior
return $row[$columnIndex] ?? false; return $row[0] ?? false;
} }
} }
...@@ -104,7 +104,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -104,7 +104,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
...@@ -124,7 +124,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -124,7 +124,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($fetchMode = null)
{ {
if ($this->data === null) { if ($this->data === null) {
$this->data = []; $this->data = [];
...@@ -164,9 +164,9 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -164,9 +164,9 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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) {
...@@ -183,12 +183,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement ...@@ -183,12 +183,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
// TODO: verify that return false is the correct behavior // TODO: verify that return false is the correct behavior
return $row[$columnIndex] ?? false; return $row[0] ?? false;
} }
/** /**
......
...@@ -570,16 +570,15 @@ class Connection implements DriverConnection ...@@ -570,16 +570,15 @@ class Connection implements DriverConnection
* *
* @param string $statement The SQL query to be executed. * @param string $statement The SQL query to be executed.
* @param mixed[] $params The prepared statement params. * @param mixed[] $params The prepared statement params.
* @param int $column The 0-indexed column number to retrieve.
* @param int[]|string[] $types The query parameter types. * @param 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($statement, array $params = [], $column = 0, array $types = []) public function fetchColumn($statement, array $params = [], array $types = [])
{ {
return $this->executeQuery($statement, $params, $types)->fetchColumn($column); return $this->executeQuery($statement, $params, $types)->fetchColumn();
} }
/** /**
......
...@@ -7,25 +7,17 @@ use Doctrine\DBAL\Driver\StatementIterator; ...@@ -7,25 +7,17 @@ use Doctrine\DBAL\Driver\StatementIterator;
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 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;
use const DB2_PARAM_FILE; use const DB2_PARAM_FILE;
use const DB2_PARAM_IN; use const DB2_PARAM_IN;
use function array_change_key_case;
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;
...@@ -34,16 +26,11 @@ use function db2_stmt_errormsg; ...@@ -34,16 +26,11 @@ use function db2_stmt_errormsg;
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;
class DB2Statement implements IteratorAggregate, Statement class DB2Statement implements IteratorAggregate, Statement
...@@ -62,12 +49,6 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -62,12 +49,6 @@ 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;
...@@ -237,18 +218,10 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -237,18 +218,10 @@ class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (isset($args[1])) {
$this->defaultFetchClassCtorArgs = (array) $args[1];
}
return true; return true;
} }
...@@ -263,7 +236,7 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -263,7 +236,7 @@ class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($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
...@@ -282,29 +255,9 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -282,29 +255,9 @@ 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.');
} }
...@@ -313,16 +266,11 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -313,16 +266,11 @@ class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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;
...@@ -340,7 +288,7 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -340,7 +288,7 @@ class DB2Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -348,7 +296,7 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -348,7 +296,7 @@ class DB2Statement implements IteratorAggregate, Statement
return false; return false;
} }
return $row[$columnIndex] ?? null; return $row[0] ?? null;
} }
/** /**
...@@ -359,71 +307,6 @@ class DB2Statement implements IteratorAggregate, Statement ...@@ -359,71 +307,6 @@ class DB2Statement implements IteratorAggregate, Statement
return @db2_num_rows($this->stmt); return @db2_num_rows($this->stmt);
} }
/**
* 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.
*
* @return object
*
* @throws DB2Exception
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = [])
{
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
* *
......
...@@ -306,7 +306,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -306,7 +306,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($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
...@@ -345,9 +345,6 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -345,9 +345,6 @@ 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 new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode)); throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
} }
...@@ -356,7 +353,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -356,7 +353,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$fetchMode = $fetchMode ?? $this->_defaultFetchMode; $fetchMode = $fetchMode ?? $this->_defaultFetchMode;
...@@ -378,7 +375,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -378,7 +375,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -386,7 +383,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -386,7 +383,7 @@ class MysqliStatement implements IteratorAggregate, Statement
return false; return false;
} }
return $row[$columnIndex] ?? null; return $row[0] ?? null;
} }
/** /**
...@@ -439,7 +436,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -439,7 +436,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->_defaultFetchMode = $fetchMode; $this->_defaultFetchMode = $fetchMode;
......
...@@ -33,7 +33,6 @@ use function oci_error; ...@@ -33,7 +33,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;
...@@ -411,7 +410,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -411,7 +410,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->_defaultFetchMode = $fetchMode; $this->_defaultFetchMode = $fetchMode;
...@@ -429,7 +428,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -429,7 +428,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($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
...@@ -443,10 +442,6 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -443,10 +442,6 @@ 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('Invalid fetch style: ' . $fetchMode); throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
} }
...@@ -460,20 +455,12 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -460,20 +455,12 @@ class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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('Invalid fetch style: ' . $fetchMode); throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
} }
...@@ -514,7 +501,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -514,7 +501,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($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
...@@ -528,7 +515,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -528,7 +515,7 @@ class OCI8Statement implements IteratorAggregate, Statement
return false; return false;
} }
return $row[$columnIndex] ?? null; return $row[0] ?? null;
} }
/** /**
......
...@@ -28,12 +28,10 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -28,12 +28,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 */
...@@ -47,12 +45,12 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -47,12 +45,12 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$fetchMode = $this->convertFetchMode($fetchMode); $fetchMode = $this->convertFetchMode($fetchMode);
try { try {
return $this->stmt->setFetchMode($fetchMode, ...$args); return $this->stmt->setFetchMode($fetchMode);
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
...@@ -141,7 +139,7 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -141,7 +139,7 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($fetchMode = null)
{ {
try { try {
if ($fetchMode === null) { if ($fetchMode === null) {
...@@ -149,8 +147,7 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -149,8 +147,7 @@ class PDOStatement implements IteratorAggregate, Statement
} }
return $this->stmt->fetch( return $this->stmt->fetch(
$this->convertFetchMode($fetchMode), $this->convertFetchMode($fetchMode)
...$args
); );
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
...@@ -160,15 +157,14 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -160,15 +157,14 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
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) {
...@@ -183,10 +179,10 @@ class PDOStatement implements IteratorAggregate, Statement ...@@ -183,10 +179,10 @@ class PDOStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
try { try {
return $this->stmt->fetchColumn($columnIndex); return $this->stmt->fetchColumn();
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
......
...@@ -28,13 +28,12 @@ interface ResultStatement extends Traversable ...@@ -28,13 +28,12 @@ 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()}).
* *
* @return bool * @return bool
*/ */
public function setFetchMode($fetchMode, ...$args); public function setFetchMode($fetchMode);
/** /**
* Returns the next row of a result set. * Returns the next row of a result set.
...@@ -42,12 +41,11 @@ interface ResultStatement extends Traversable ...@@ -42,12 +41,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($fetchMode = null, ...$args); public function fetch($fetchMode = null);
/** /**
* Returns an array containing all of the result set rows. * Returns an array containing all of the result set rows.
...@@ -55,24 +53,15 @@ interface ResultStatement extends Traversable ...@@ -55,24 +53,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 class name of the object to be created,
* 2. Array of constructor arguments
* *
* @return mixed[] * @return mixed[]
*/ */
public function fetchAll($fetchMode = null, ...$args); public function fetchAll($fetchMode = null);
/** /**
* 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($columnIndex = 0); public function fetchColumn();
} }
...@@ -7,21 +7,13 @@ use Doctrine\DBAL\Driver\StatementIterator; ...@@ -7,21 +7,13 @@ use Doctrine\DBAL\Driver\StatementIterator;
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 const SASQL_BOTH; use const SASQL_BOTH;
use function array_key_exists; use function array_key_exists;
use function assert; use function assert;
use function count;
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 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;
...@@ -32,7 +24,6 @@ use function sasql_stmt_execute; ...@@ -32,7 +24,6 @@ use function sasql_stmt_execute;
use function sasql_stmt_field_count; 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;
/** /**
* SAP SQL Anywhere implementation of the Statement interface. * SAP SQL Anywhere implementation of the Statement interface.
...@@ -42,12 +33,6 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -42,12 +33,6 @@ 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;
...@@ -199,7 +184,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -199,7 +184,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
* *
* @throws SQLAnywhereException * @throws SQLAnywhereException
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($fetchMode = null)
{ {
if (! is_resource($this->result)) { if (! is_resource($this->result)) {
return false; return false;
...@@ -217,29 +202,9 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -217,29 +202,9 @@ 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('Fetch mode is not supported: ' . $fetchMode); throw new SQLAnywhereException('Fetch mode is not supported: ' . $fetchMode);
} }
...@@ -248,17 +213,11 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -248,17 +213,11 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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;
...@@ -277,7 +236,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -277,7 +236,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -285,7 +244,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -285,7 +244,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
return false; return false;
} }
return $row[$columnIndex] ?? null; return $row[0] ?? null;
} }
/** /**
...@@ -307,65 +266,10 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -307,65 +266,10 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (isset($args[1])) {
$this->defaultFetchClassCtorArgs = (array) $args[1];
}
return true; return true;
} }
/**
* 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.
*
* @return object
*
* @throws SQLAnywhereException
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = [])
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
throw new SQLAnywhereException(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);
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;
}
} }
...@@ -14,15 +14,12 @@ use const SQLSRV_FETCH_BOTH; ...@@ -14,15 +14,12 @@ 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;
use function array_key_exists; use function array_key_exists;
use function count;
use function in_array;
use function is_int; use function is_int;
use function is_numeric; use function is_numeric;
use function sqlsrv_errors; use function sqlsrv_errors;
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;
...@@ -84,20 +81,6 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -84,20 +81,6 @@ 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.
* *
...@@ -322,18 +305,10 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -322,18 +305,10 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
if (isset($args[0])) {
$this->defaultFetchClass = $args[0];
}
if (isset($args[1])) {
$this->defaultFetchClassCtorArgs = (array) $args[1];
}
return true; return true;
} }
...@@ -350,7 +325,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -350,7 +325,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
* *
* @throws SQLSrvException * @throws SQLSrvException
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($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
...@@ -368,35 +343,17 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -368,35 +343,17 @@ 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($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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;
...@@ -415,7 +372,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -415,7 +372,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
$row = $this->fetch(FetchMode::NUMERIC); $row = $this->fetch(FetchMode::NUMERIC);
...@@ -423,7 +380,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -423,7 +380,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
return false; return false;
} }
return $row[$columnIndex] ?? null; return $row[0] ?? null;
} }
/** /**
......
...@@ -35,15 +35,6 @@ final class FetchMode ...@@ -35,15 +35,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.
...@@ -52,14 +43,6 @@ final class FetchMode ...@@ -52,14 +43,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.
*/ */
......
...@@ -111,11 +111,11 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -111,11 +111,11 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
$this->defaultFetchMode = $fetchMode; $this->defaultFetchMode = $fetchMode;
return $this->stmt->setFetchMode($fetchMode, ...$args); return $this->stmt->setFetchMode($fetchMode);
} }
/** /**
...@@ -129,11 +129,11 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -129,11 +129,11 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($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
...@@ -148,11 +148,11 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -148,11 +148,11 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
$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
...@@ -215,9 +215,9 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -215,9 +215,9 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchColumn($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;
......
...@@ -211,9 +211,9 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -211,9 +211,9 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setFetchMode($fetchMode, ...$args) public function setFetchMode($fetchMode)
{ {
return $this->stmt->setFetchMode($fetchMode, ...$args); return $this->stmt->setFetchMode($fetchMode);
} }
/** /**
...@@ -229,25 +229,25 @@ class Statement implements IteratorAggregate, DriverStatement ...@@ -229,25 +229,25 @@ class Statement implements IteratorAggregate, DriverStatement
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetch($fetchMode = null, ...$args) public function fetch($fetchMode = null)
{ {
return $this->stmt->fetch($fetchMode, ...$args); return $this->stmt->fetch($fetchMode);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function fetchAll($fetchMode = null, ...$args) public function fetchAll($fetchMode = null)
{ {
return $this->stmt->fetchAll($fetchMode, ...$args); return $this->stmt->fetchAll($fetchMode);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function fetchColumn($columnIndex = 0) public function fetchColumn()
{ {
return $this->stmt->fetchColumn($columnIndex); return $this->stmt->fetchColumn();
} }
/** /**
......
...@@ -627,7 +627,6 @@ class ConnectionTest extends TestCase ...@@ -627,7 +627,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);
...@@ -642,7 +641,6 @@ class ConnectionTest extends TestCase ...@@ -642,7 +641,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 */
...@@ -656,7 +654,7 @@ class ConnectionTest extends TestCase ...@@ -656,7 +654,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
......
...@@ -6,9 +6,6 @@ use DateTime; ...@@ -6,9 +6,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;
...@@ -18,7 +15,6 @@ use Doctrine\DBAL\Schema\Table; ...@@ -18,7 +15,6 @@ use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Statement; use Doctrine\DBAL\Statement;
use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use PDO;
use const CASE_LOWER; use const CASE_LOWER;
use function array_change_key_case; use function array_change_key_case;
use function array_filter; use function array_filter;
...@@ -27,7 +23,6 @@ use function count; ...@@ -27,7 +23,6 @@ use function count;
use function date; use function date;
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;
...@@ -376,13 +371,13 @@ class DataAccessTest extends FunctionalTestCase ...@@ -376,13 +371,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);
} }
...@@ -392,15 +387,14 @@ class DataAccessTest extends FunctionalTestCase ...@@ -392,15 +387,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);
} }
...@@ -418,7 +412,7 @@ class DataAccessTest extends FunctionalTestCase ...@@ -418,7 +412,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]);
} }
/** /**
...@@ -635,7 +629,7 @@ class DataAccessTest extends FunctionalTestCase ...@@ -635,7 +629,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);
} }
...@@ -738,62 +732,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -738,62 +732,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,
MyFetchClass::class
);
self::assertCount(1, $results);
self::assertInstanceOf(MyFetchClass::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
*/ */
...@@ -811,53 +749,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -811,53 +749,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, MyFetchClass::class);
$results = $stmt->fetchAll();
self::assertCount(1, $results);
self::assertInstanceOf(MyFetchClass::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, MyFetchClass::class);
$results = [];
while ($row = $stmt->fetch()) {
$results[] = $row;
}
self::assertCount(1, $results);
self::assertInstanceOf(MyFetchClass::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
*/ */
...@@ -898,21 +789,6 @@ class DataAccessTest extends FunctionalTestCase ...@@ -898,21 +789,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
*/ */
...@@ -922,48 +798,4 @@ class DataAccessTest extends FunctionalTestCase ...@@ -922,48 +798,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);
}
}
class MyFetchClass
{
/** @var int */
public $test_int;
/** @var string */
public $test_string;
/** @var string */
public $test_datetime;
} }
...@@ -78,7 +78,6 @@ class BinaryTest extends FunctionalTestCase ...@@ -78,7 +78,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]
); );
......
...@@ -3,13 +3,11 @@ ...@@ -3,13 +3,11 @@
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
...@@ -122,25 +120,6 @@ class StatementTest extends TestCase ...@@ -122,25 +120,6 @@ class StatementTest extends TestCase
self::assertTrue($this->stmt->execute($params)); self::assertTrue($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));
self::assertTrue($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))
......
...@@ -8,7 +8,6 @@ use Doctrine\DBAL\DBALException; ...@@ -8,7 +8,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;
...@@ -149,15 +148,4 @@ class StatementTest extends TestCase ...@@ -149,15 +148,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']);
}
} }
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