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

Merge pull request #3552 from morozov/statement-types

Enforced parameter and return value types in Statement classes
parents ac2252d2 94af8191
......@@ -55,7 +55,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return $this->columnCount;
}
......@@ -75,7 +75,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
......@@ -97,7 +97,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
if (! isset($this->data[$this->num])) {
return false;
......@@ -130,7 +130,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$rows = [];
while ($row = $this->fetch($fetchMode, ...$args)) {
......@@ -143,7 +143,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......
......@@ -26,39 +26,27 @@ class QueryCacheProfile
/** @var string|null */
private $cacheKey;
/**
* @param int $lifetime
* @param string|null $cacheKey
*/
public function __construct($lifetime = 0, $cacheKey = null, ?Cache $resultCache = null)
public function __construct(int $lifetime = 0, ?string $cacheKey = null, ?Cache $resultCache = null)
{
$this->lifetime = $lifetime;
$this->cacheKey = $cacheKey;
$this->resultCacheDriver = $resultCache;
}
/**
* @return Cache|null
*/
public function getResultCacheDriver()
public function getResultCacheDriver() : ?Cache
{
return $this->resultCacheDriver;
}
/**
* @return int
*/
public function getLifetime()
public function getLifetime() : int
{
return $this->lifetime;
}
/**
* @return string
*
* @throws CacheException
*/
public function getCacheKey()
public function getCacheKey() : string
{
if ($this->cacheKey === null) {
throw NoCacheKey::new();
......@@ -70,14 +58,13 @@ class QueryCacheProfile
/**
* Generates the real cache key from query, params, types and connection parameters.
*
* @param string $query
* @param mixed[] $params
* @param int[]|string[] $types
* @param mixed[] $connectionParams
*
* @return string[]
*/
public function generateCacheKeys($query, $params, $types, array $connectionParams = [])
public function generateCacheKeys(string $query, array $params, array $types, array $connectionParams = []) : array
{
$realCacheKey = 'query=' . $query .
'&params=' . serialize($params) .
......@@ -94,30 +81,17 @@ class QueryCacheProfile
return [$cacheKey, $realCacheKey];
}
/**
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
public function setResultCacheDriver(Cache $cache)
public function setResultCacheDriver(Cache $cache) : self
{
return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
}
/**
* @param string|null $cacheKey
*
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
public function setCacheKey($cacheKey)
public function setCacheKey(?string $cacheKey) : self
{
return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver);
}
/**
* @param int $lifetime
*
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
public function setLifetime($lifetime)
public function setLifetime(int $lifetime) : self
{
return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver);
}
......
......@@ -60,12 +60,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/** @var int */
private $defaultFetchMode = FetchMode::MIXED;
/**
* @param string $cacheKey
* @param string $realKey
* @param int $lifetime
*/
public function __construct(ResultStatement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime)
public function __construct(ResultStatement $stmt, Cache $resultCache, string $cacheKey, string $realKey, int $lifetime)
{
$this->statement = $stmt;
$this->resultCache = $resultCache;
......@@ -98,7 +93,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return $this->statement->columnCount();
}
......@@ -106,7 +101,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->defaultFetchMode = $fetchMode;
}
......@@ -124,7 +119,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
if ($this->data === null) {
$this->data = [];
......@@ -164,7 +159,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$data = $this->statement->fetchAll($fetchMode, ...$args);
......@@ -183,7 +178,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......
......@@ -22,6 +22,7 @@ use const DB2_PARAM_FILE;
use const DB2_PARAM_IN;
use function array_change_key_case;
use function array_key_exists;
use function assert;
use function count;
use function db2_bind_param;
use function db2_execute;
......@@ -36,6 +37,7 @@ use function error_get_last;
use function fclose;
use function fwrite;
use function gettype;
use function is_int;
use function is_object;
use function is_resource;
use function is_string;
......@@ -89,7 +91,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
$this->bindParam($param, $value, $type);
}
......@@ -97,29 +99,31 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
assert(is_int($param));
switch ($type) {
case ParameterType::INTEGER:
$this->bind($column, $variable, DB2_PARAM_IN, DB2_LONG);
$this->bind($param, $variable, DB2_PARAM_IN, DB2_LONG);
break;
case ParameterType::LARGE_OBJECT:
if (isset($this->lobs[$column])) {
[, $handle] = $this->lobs[$column];
if (isset($this->lobs[$param])) {
[, $handle] = $this->lobs[$param];
fclose($handle);
}
$handle = $this->createTemporaryFile();
$path = stream_get_meta_data($handle)['uri'];
$this->bind($column, $path, DB2_PARAM_FILE, DB2_BINARY);
$this->bind($param, $path, DB2_PARAM_FILE, DB2_BINARY);
$this->lobs[$column] = [&$variable, $handle];
$this->lobs[$param] = [&$variable, $handle];
break;
default:
$this->bind($column, $variable, DB2_PARAM_IN, DB2_CHAR);
$this->bind($param, $variable, DB2_PARAM_IN, DB2_CHAR);
break;
}
}
......@@ -130,7 +134,7 @@ class DB2Statement implements IteratorAggregate, Statement
*
* @throws DB2Exception
*/
private function bind($position, &$variable, int $parameterType, int $dataType) : void
private function bind(int $position, &$variable, int $parameterType, int $dataType) : void
{
$this->bindParam[$position] =& $variable;
......@@ -158,7 +162,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return db2_num_fields($this->stmt) ?: 0;
}
......@@ -166,7 +170,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if ($params === null) {
ksort($this->bindParam);
......@@ -206,7 +210,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->defaultFetchMode = $fetchMode;
......@@ -232,7 +236,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
......@@ -282,7 +286,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$rows = [];
......@@ -309,7 +313,7 @@ class DB2Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......@@ -339,11 +343,9 @@ class DB2Statement implements IteratorAggregate, Statement
* @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 = [])
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) : object
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
......
......@@ -80,15 +80,13 @@ class MysqliStatement implements IteratorAggregate, Statement
private $result = false;
/**
* @param string $prepareString
*
* @throws MysqliException
*/
public function __construct(mysqli $conn, $prepareString)
public function __construct(mysqli $conn, string $sql)
{
$this->_conn = $conn;
$stmt = $conn->prepare($prepareString);
$stmt = $conn->prepare($sql);
if ($stmt === false) {
throw ConnectionError::new($this->_conn);
......@@ -108,22 +106,22 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
assert(is_int($column));
assert(is_int($param));
if (! isset(self::$_paramTypeMap[$type])) {
throw UnknownType::new($type);
}
$this->_bindedValues[$column] =& $variable;
$this->types[$column - 1] = self::$_paramTypeMap[$type];
$this->_bindedValues[$param] =& $variable;
$this->types[$param - 1] = self::$_paramTypeMap[$type];
}
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
assert(is_int($param));
......@@ -139,7 +137,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if ($params !== null && count($params) > 0) {
if (! $this->bindUntypedValues($params)) {
......@@ -209,7 +207,7 @@ class MysqliStatement implements IteratorAggregate, Statement
*
* @throws DriverException
*/
private function bindTypedParameters()
private function bindTypedParameters() : void
{
$streams = $values = [];
$types = $this->types;
......@@ -245,9 +243,11 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* Handle $this->_longData after regular query parameters have been bound
*
* @param resource[] $streams
*
* @throws MysqliException
*/
private function sendLongData($streams)
private function sendLongData(array $streams) : void
{
foreach ($streams as $paramNr => $stream) {
while (! feof($stream)) {
......@@ -268,10 +268,8 @@ class MysqliStatement implements IteratorAggregate, Statement
* Binds a array of values to bound parameters.
*
* @param mixed[] $values
*
* @return bool
*/
private function bindUntypedValues(array $values)
private function bindUntypedValues(array $values) : bool
{
$params = [];
$types = str_repeat('s', count($values));
......@@ -305,7 +303,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
......@@ -355,7 +353,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$fetchMode = $fetchMode ?: $this->_defaultFetchMode;
......@@ -377,7 +375,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......@@ -416,7 +414,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return $this->_stmt->field_count;
}
......@@ -424,7 +422,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->_defaultFetchMode = $fetchMode;
}
......
......@@ -103,7 +103,7 @@ class OCI8Statement implements IteratorAggregate, Statement
* @param resource $dbh The connection handle.
* @param string $query The SQL query.
*/
public function __construct($dbh, $query, OCI8Connection $conn)
public function __construct($dbh, string $query, OCI8Connection $conn)
{
[$query, $paramMap] = self::convertPositionalToNamedPlaceholders($query);
......@@ -137,14 +137,14 @@ class OCI8Statement implements IteratorAggregate, Statement
* @todo extract into utility class in Doctrine\DBAL\Util namespace
* @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements.
*/
public static function convertPositionalToNamedPlaceholders($statement)
public static function convertPositionalToNamedPlaceholders(string $statement) : array
{
$fragmentOffset = $tokenOffset = 0;
$fragments = $paramMap = [];
$currentLiteralDelimiter = null;
do {
if (! $currentLiteralDelimiter) {
if ($currentLiteralDelimiter === null) {
$result = self::findPlaceholderOrOpeningQuote(
$statement,
$tokenOffset,
......@@ -174,24 +174,24 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* Finds next placeholder or opening quote.
*
* @param string $statement The SQL statement to parse
* @param string $tokenOffset The offset to start searching from
* @param int $fragmentOffset The offset to build the next fragment from
* @param string[] $fragments Fragments of the original statement not containing placeholders
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal
* or NULL if not currently in a literal
* @param array<int, string> $paramMap Mapping of the original parameter positions to their named replacements
* @param string $statement The SQL statement to parse
* @param int $tokenOffset The offset to start searching from
* @param int $fragmentOffset The offset to build the next fragment from
* @param string[] $fragments Fragments of the original statement not containing placeholders
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal
* or NULL if not currently in a literal
* @param string[] $paramMap Mapping of the original parameter positions to their named replacements
*
* @return bool Whether the token was found
*/
private static function findPlaceholderOrOpeningQuote(
$statement,
&$tokenOffset,
&$fragmentOffset,
&$fragments,
&$currentLiteralDelimiter,
&$paramMap
) {
string $statement,
int &$tokenOffset,
int &$fragmentOffset,
array &$fragments,
?string &$currentLiteralDelimiter,
array &$paramMap
) : bool {
$token = self::findToken($statement, $tokenOffset, '/[?\'"]/');
if (! $token) {
......@@ -220,16 +220,16 @@ class OCI8Statement implements IteratorAggregate, Statement
* Finds closing quote
*
* @param string $statement The SQL statement to parse
* @param string $tokenOffset The offset to start searching from
* @param int $tokenOffset The offset to start searching from
* @param string $currentLiteralDelimiter The delimiter of the current string literal
*
* @return bool Whether the token was found
*/
private static function findClosingQuote(
$statement,
&$tokenOffset,
&$currentLiteralDelimiter
) {
string $statement,
int &$tokenOffset,
string &$currentLiteralDelimiter
) : bool {
$token = self::findToken(
$statement,
$tokenOffset,
......@@ -240,7 +240,7 @@ class OCI8Statement implements IteratorAggregate, Statement
return false;
}
$currentLiteralDelimiter = false;
$currentLiteralDelimiter = null;
++$tokenOffset;
return true;
......@@ -256,7 +256,7 @@ class OCI8Statement implements IteratorAggregate, Statement
*
* @return string|null Token or NULL if not found
*/
private static function findToken($statement, &$offset, $regex)
private static function findToken(string $statement, int &$offset, string $regex) : ?string
{
if (preg_match($regex, $statement, $matches, PREG_OFFSET_CAPTURE, $offset)) {
$offset = $matches[0][1];
......@@ -270,7 +270,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
$this->bindParam($param, $value, $type, null);
}
......@@ -278,9 +278,9 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
$column = $this->_paramMap[$column];
$param = $this->_paramMap[$param];
if ($type === ParameterType::LARGE_OBJECT) {
$lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
......@@ -293,11 +293,11 @@ class OCI8Statement implements IteratorAggregate, Statement
$variable =& $lob;
}
$this->boundValues[$column] =& $variable;
$this->boundValues[$param] =& $variable;
if (! oci_bind_by_name(
$this->_sth,
$column,
$param,
$variable,
$length ?? -1,
$this->convertParameterType($type)
......@@ -341,7 +341,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return oci_num_fields($this->_sth) ?: 0;
}
......@@ -349,7 +349,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if ($params) {
$hasZeroIndex = array_key_exists(0, $params);
......@@ -376,7 +376,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->_defaultFetchMode = $fetchMode;
}
......@@ -392,7 +392,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
......@@ -423,7 +423,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$fetchMode = $fetchMode ?: $this->_defaultFetchMode;
......@@ -477,7 +477,7 @@ class OCI8Statement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
......
......@@ -16,7 +16,7 @@ class Statement extends PDOStatement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null, $driverOptions = null) : void
{
if (($type === ParameterType::LARGE_OBJECT || $type === ParameterType::BINARY)
&& $driverOptions === null
......@@ -24,13 +24,13 @@ class Statement extends PDOStatement
$driverOptions = PDO::SQLSRV_ENCODING_BINARY;
}
parent::bindParam($column, $variable, $type, $length, $driverOptions);
parent::bindParam($param, $variable, $type, $length, $driverOptions);
}
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
$this->bindParam($param, $value, $type);
}
......
......@@ -53,7 +53,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$fetchMode = $this->convertFetchMode($fetchMode);
......@@ -67,7 +67,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
$type = $this->convertParamType($type);
......@@ -81,7 +81,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null, $driverOptions = null) : void
{
$type = $this->convertParamType($type);
$extraParameters = array_slice(func_get_args(), 3);
......@@ -91,7 +91,7 @@ class PDOStatement implements IteratorAggregate, Statement
}
try {
$this->stmt->bindParam($column, $variable, $type, ...$extraParameters);
$this->stmt->bindParam($param, $variable, $type, ...$extraParameters);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
......@@ -108,7 +108,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return $this->stmt->columnCount();
}
......@@ -116,7 +116,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
try {
$this->stmt->execute($params);
......@@ -136,7 +136,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
try {
if ($fetchMode === null) {
......@@ -154,7 +154,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
try {
if ($fetchMode === null) {
......@@ -177,7 +177,7 @@ class PDOStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
try {
$value = $this->stmt->fetchColumn($columnIndex);
......
......@@ -20,10 +20,10 @@ interface ResultStatement extends Traversable
* Returns the number of columns in the result set
*
* @return int The number of columns in the result set represented
* by the PDOStatement object. If there is no result set,
* this method should return 0.
* by the statement. If there is no result set,
* this method should return 0.
*/
public function columnCount();
public function columnCount() : int;
/**
* Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
......@@ -43,7 +43,7 @@ interface ResultStatement extends Traversable
* 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($fetchMode, ...$args) : void;
public function setFetchMode(int $fetchMode, ...$args) : void;
/**
* Returns the next row of a result set.
......@@ -56,7 +56,7 @@ interface ResultStatement extends Traversable
* @return mixed The return value of this method on success depends on the fetch mode. In all cases, FALSE is
* returned on failure.
*/
public function fetch($fetchMode = null, ...$args);
public function fetch(?int $fetchMode = null, ...$args);
/**
* Returns an array containing all of the result set rows.
......@@ -73,7 +73,7 @@ interface ResultStatement extends Traversable
*
* @return mixed[]
*/
public function fetchAll($fetchMode = null, ...$args);
public function fetchAll(?int $fetchMode = null, ...$args) : array;
/**
* Returns a single column from the next row of a result set or FALSE if there are no more rows.
......@@ -83,5 +83,5 @@ interface ResultStatement extends Traversable
*
* @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(int $columnIndex = 0);
}
......@@ -16,6 +16,7 @@ use ReflectionObject;
use stdClass;
use const SASQL_BOTH;
use function array_key_exists;
use function assert;
use function count;
use function func_get_args;
use function is_array;
......@@ -70,7 +71,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*
* @throws SQLAnywhereException
*/
public function __construct($conn, $sql)
public function __construct($conn, string $sql)
{
if (! is_resource($conn)) {
throw new SQLAnywhereException(sprintf(
......@@ -92,8 +93,10 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*
* @throws SQLAnywhereException
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
assert(is_int($param));
switch ($type) {
case ParameterType::INTEGER:
case ParameterType::BOOLEAN:
......@@ -114,9 +117,9 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
throw new SQLAnywhereException(sprintf('Unknown type %d.', $type));
}
$this->boundValues[$column] =& $variable;
$this->boundValues[$param] =& $variable;
if (! sasql_stmt_bind_param_ex($this->stmt, $column - 1, $variable, $type, $variable === null)) {
if (! sasql_stmt_bind_param_ex($this->stmt, $param - 1, $variable, $type, $variable === null)) {
throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt);
}
}
......@@ -124,7 +127,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
$this->bindParam($param, $value, $type);
}
......@@ -140,7 +143,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return sasql_stmt_field_count($this->stmt);
}
......@@ -150,7 +153,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*
* @throws SQLAnywhereException
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if (is_array($params)) {
$hasZeroIndex = array_key_exists(0, $params);
......@@ -176,7 +179,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*
* @throws SQLAnywhereException
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
if (! is_resource($this->result)) {
return false;
......@@ -225,7 +228,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$rows = [];
......@@ -254,7 +257,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......@@ -265,6 +268,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
if (! array_key_exists($columnIndex, $row)) {
throw InvalidColumnIndex::new($columnIndex, count($row));
}
return $row[$columnIndex];
}
/**
......@@ -286,7 +291,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->defaultFetchMode = $fetchMode;
......@@ -308,11 +313,9 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
* @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 = [])
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) : object
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
......
......@@ -16,10 +16,10 @@ use const SQLSRV_FETCH_BOTH;
use const SQLSRV_FETCH_NUMERIC;
use const SQLSRV_PARAM_IN;
use function array_key_exists;
use function assert;
use function count;
use function in_array;
use function is_int;
use function is_numeric;
use function sqlsrv_execute;
use function sqlsrv_fetch;
use function sqlsrv_fetch_array;
......@@ -129,9 +129,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* @param resource $conn
* @param string $sql
*/
public function __construct($conn, $sql, ?LastInsertId $lastInsertId = null)
public function __construct($conn, string $sql, ?LastInsertId $lastInsertId = null)
{
$this->conn = $conn;
$this->sql = $sql;
......@@ -147,13 +146,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
if (! is_numeric($param)) {
throw new SQLSrvException(
'sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.'
);
}
assert(is_int($param));
$this->variables[$param] = $value;
$this->types[$param] = $type;
......@@ -162,14 +157,12 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
if (! is_numeric($column)) {
throw new SQLSrvException('sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.');
}
assert(is_int($param));
$this->variables[$column] =& $variable;
$this->types[$column] = $type;
$this->variables[$param] =& $variable;
$this->types[$param] = $type;
// unset the statement resource if it exists as the new one will need to be bound to the new variable
$this->stmt = null;
......@@ -189,7 +182,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
// @link http://php.net/manual/en/pdostatement.closecursor.php
// @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075
// deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them
while (sqlsrv_fetch($this->stmt)) {
while (sqlsrv_fetch($this->stmt) !== false) {
}
$this->result = false;
......@@ -198,7 +191,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
if ($this->stmt === null) {
return 0;
......@@ -210,7 +203,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if ($params) {
$hasZeroIndex = array_key_exists(0, $params);
......@@ -289,7 +282,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->defaultFetchMode = $fetchMode;
......@@ -317,7 +310,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*
* @throws SQLSrvException
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
......@@ -353,7 +346,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$rows = [];
......@@ -382,7 +375,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$row = $this->fetch(FetchMode::NUMERIC);
......
......@@ -21,16 +21,16 @@ interface Statement extends ResultStatement
* As mentioned above, the named parameters are not natively supported by the mysqli driver, use executeQuery(),
* fetchAll(), fetchArray(), fetchColumn(), fetchAssoc() methods to have the named parameter emulated by doctrine.
*
* @param mixed $param Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement
* using question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $value The value to bind to the parameter.
* @param int $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType}
* constants.
* @param string|int $param Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement
* using question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $value The value to bind to the parameter.
* @param int $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType}
* constants.
*
* @throws DriverException
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void;
public function bindValue($param, $value, int $type = ParameterType::STRING) : void;
/**
* Binds a PHP variable to a corresponding named (not supported by mysqli driver, see comment below) or question
......@@ -46,18 +46,18 @@ interface Statement extends ResultStatement
* of stored procedures that return data as output parameters, and some also as input/output
* parameters that both send in data and are updated to receive it.
*
* @param mixed $column Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement using
* question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
* @param int $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType}
* constants.
* @param int|null $length You must specify maxlength when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
* @param string|int $param Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement using
* question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $variable The variable to bind to the parameter.
* @param int $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType}
* constants.
* @param int|null $length You must specify maxlength when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
*
* @throws DriverException
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void;
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void;
/**
* Executes a prepared statement
......@@ -73,5 +73,5 @@ interface Statement extends ResultStatement
*
* @throws DriverException
*/
public function execute($params = null) : void;
public function execute(?array $params = null) : void;
}
......@@ -47,17 +47,17 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
assert($this->stmt instanceof DriverStatement);
$this->stmt->bindParam($column, $variable, $type, $length);
$this->stmt->bindParam($param, $variable, $type, $length);
}
/**
* {@inheritdoc}
*/
public function bindValue($param, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, int $type = ParameterType::STRING) : void
{
assert($this->stmt instanceof DriverStatement);
......@@ -75,7 +75,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function columnCount()
public function columnCount() : int
{
return $this->stmt->columnCount();
}
......@@ -83,7 +83,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
assert($this->stmt instanceof DriverStatement);
......@@ -93,7 +93,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->defaultFetchMode = $fetchMode;
......@@ -111,13 +111,13 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
$row = $this->stmt->fetch($fetchMode, ...$args);
$iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM);
$iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
$fixCase = $this->case !== null
&& ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED)
&& ($this->portability & Connection::PORTABILITY_FIX_CASE);
......@@ -130,13 +130,13 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
$rows = $this->stmt->fetchAll($fetchMode, ...$args);
$iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM);
$iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
$fixCase = $this->case !== null
&& ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED)
&& ($this->portability & Connection::PORTABILITY_FIX_CASE);
......@@ -166,12 +166,10 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* @param mixed $row
* @param int $iterateRow
* @param bool $fixCase
*
* @return mixed
*/
protected function fixRow($row, $iterateRow, $fixCase)
protected function fixRow($row, bool $iterateRow, bool $fixCase)
{
if (! $row) {
return $row;
......@@ -197,7 +195,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
$value = $this->stmt->fetchColumn($columnIndex);
......
......@@ -36,14 +36,14 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* The parameter types.
*
* @var int[]|string[]
* @var int[]|string[]|Type[]
*/
protected $types = [];
/**
* The underlying driver statement.
*
* @var \Doctrine\DBAL\Driver\Statement
* @var DriverStatement
*/
protected $stmt;
......@@ -67,7 +67,7 @@ class Statement implements IteratorAggregate, DriverStatement
* @param string $sql The SQL of the statement.
* @param Connection $conn The connection on which the statement should be executed.
*/
public function __construct($sql, Connection $conn)
public function __construct(string $sql, Connection $conn)
{
$this->sql = $sql;
$this->stmt = $conn->getWrappedConnection()->prepare($sql);
......@@ -83,17 +83,21 @@ class Statement implements IteratorAggregate, DriverStatement
* type and the value undergoes the conversion routines of the mapping type before
* being bound.
*
* @param string|int $name The name or position of the parameter.
* @param mixed $value The value of the parameter.
* @param mixed $type Either a PDO binding type or a DBAL mapping type name or instance.
* @param string|int $param Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement
* using question mark placeholders, this will be the 1-indexed position
* of the parameter.
* @param mixed $value The value to bind to the parameter.
* @param string|int|Type $type Either one of the constants defined in {@link \Doctrine\DBAL\ParameterType}
* or a DBAL mapping type name or instance.
*
* @throws DBALException
* @throws DriverException
*/
public function bindValue($name, $value, $type = ParameterType::STRING) : void
public function bindValue($param, $value, $type = ParameterType::STRING) : void
{
$this->params[$name] = $value;
$this->types[$name] = $type;
$this->params[$param] = $value;
$this->types[$param] = $type;
if (is_string($type)) {
$type = Type::getType($type);
......@@ -106,7 +110,7 @@ class Statement implements IteratorAggregate, DriverStatement
$bindingType = $type;
}
$this->stmt->bindValue($name, $value, $bindingType);
$this->stmt->bindValue($param, $value, $bindingType);
}
/**
......@@ -114,20 +118,23 @@ class Statement implements IteratorAggregate, DriverStatement
*
* Binding a parameter by reference does not support DBAL mapping types.
*
* @param string|int $name The name or position of the parameter.
* @param mixed $var The reference to the variable to bind.
* @param int $type The PDO binding type.
* @param int|null $length Must be specified when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
* @param string|int $param Parameter identifier. For a prepared statement using named placeholders,
* this will be a parameter name of the form :name. For a prepared statement
* using question mark placeholders, this will be the 1-indexed position
* of the parameter.
* @param mixed $variable The variable to bind to the parameter.
* @param int $type The PDO binding type.
* @param int|null $length Must be specified when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
*
* @throws DriverException
*/
public function bindParam($name, &$var, $type = ParameterType::STRING, $length = null) : void
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
{
$this->params[$name] = $var;
$this->types[$name] = $type;
$this->params[$param] = $variable;
$this->types[$param] = $type;
$this->stmt->bindParam($name, $var, $type, $length);
$this->stmt->bindParam($param, $variable, $type, $length);
}
/**
......@@ -135,7 +142,7 @@ class Statement implements IteratorAggregate, DriverStatement
*
* @throws DBALException
*/
public function execute($params = null) : void
public function execute(?array $params = null) : void
{
if (is_array($params)) {
$this->params = $params;
......@@ -171,10 +178,8 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* Returns the number of columns in the result set.
*
* @return int
*/
public function columnCount()
public function columnCount() : int
{
return $this->stmt->columnCount();
}
......@@ -182,7 +187,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function setFetchMode($fetchMode, ...$args) : void
public function setFetchMode(int $fetchMode, ...$args) : void
{
$this->stmt->setFetchMode($fetchMode, ...$args);
}
......@@ -200,7 +205,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function fetch($fetchMode = null, ...$args)
public function fetch(?int $fetchMode = null, ...$args)
{
return $this->stmt->fetch($fetchMode, ...$args);
}
......@@ -208,7 +213,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritdoc}
*/
public function fetchAll($fetchMode = null, ...$args)
public function fetchAll(?int $fetchMode = null, ...$args) : array
{
return $this->stmt->fetchAll($fetchMode, ...$args);
}
......@@ -216,7 +221,7 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* {@inheritDoc}
*/
public function fetchColumn($columnIndex = 0)
public function fetchColumn(int $columnIndex = 0)
{
return $this->stmt->fetchColumn($columnIndex);
}
......@@ -233,10 +238,8 @@ class Statement implements IteratorAggregate, DriverStatement
/**
* Gets the wrapped driver statement.
*
* @return \Doctrine\DBAL\Driver\Statement
*/
public function getWrappedStatement()
public function getWrappedStatement() : DriverStatement
{
return $this->stmt;
}
......
......@@ -52,8 +52,7 @@ class OCI8StatementTest extends DbalTestCase
->with(
$this->equalTo($index + 1),
$this->equalTo($value)
)
->willReturn(true);
);
}
// can't pass to constructor since we don't have a real database handle,
......
......@@ -184,7 +184,7 @@ class ResultCacheTest extends DbalFunctionalTestCase
$query = $this->connection->getDatabasePlatform()
->getDummySelectSQL('1');
$qcp = new QueryCacheProfile(0, 0, new ArrayCache());
$qcp = new QueryCacheProfile(0, null, new ArrayCache());
$stmt = $this->connection->executeCacheQuery($query, [], [], $qcp);
$stmt->fetchAll(FetchMode::COLUMN);
......
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