Skip to content

Commit

Permalink
Merge pull request #3442 from morozov/phpstan-lvl6
Browse files Browse the repository at this point in the history
PHPStan Level 6
  • Loading branch information
Ocramius authored Jan 29, 2019
2 parents 94cec71 + 000cd9d commit 7f79d04
Show file tree
Hide file tree
Showing 38 changed files with 447 additions and 232 deletions.
51 changes: 24 additions & 27 deletions lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use Exception;
use Throwable;
use function array_key_exists;
use function array_merge;
use function assert;
use function func_get_args;
use function implode;
Expand Down Expand Up @@ -599,33 +598,33 @@ public function isTransactionActive()
}

/**
* Gathers conditions for an update or delete call.
* Adds identifier condition to the query components
*
* @param mixed[] $identifiers Input array of columns to values
* @param mixed[] $identifier Map of key columns to their values
* @param string[] $columns Column names
* @param mixed[] $values Column values
* @param string[] $conditions Key conditions
*
* @return string[][] a triplet with:
* - the first key being the columns
* - the second key being the values
* - the third key being the conditions
* @throws DBALException
*/
private function gatherConditions(array $identifiers)
{
$columns = [];
$values = [];
$conditions = [];
private function addIdentifierCondition(
array $identifier,
array &$columns,
array &$values,
array &$conditions
) : void {
$platform = $this->getDatabasePlatform();

foreach ($identifiers as $columnName => $value) {
foreach ($identifier as $columnName => $value) {
if ($value === null) {
$conditions[] = $this->getDatabasePlatform()->getIsNullExpression($columnName);
$conditions[] = $platform->getIsNullExpression($columnName);
continue;
}

$columns[] = $columnName;
$values[] = $value;
$conditions[] = $columnName . ' = ?';
}

return [$columns, $values, $conditions];
}

/**
Expand All @@ -648,7 +647,9 @@ public function delete($tableExpression, array $identifier, array $types = [])
throw InvalidArgumentException::fromEmptyCriteria();
}

[$columns, $values, $conditions] = $this->gatherConditions($identifier);
$columns = $values = $conditions = [];

$this->addIdentifierCondition($identifier, $columns, $values, $conditions);

return $this->executeUpdate(
'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $conditions),
Expand Down Expand Up @@ -713,19 +714,15 @@ public function getTransactionIsolation()
*/
public function update($tableExpression, array $data, array $identifier, array $types = [])
{
$setColumns = [];
$setValues = [];
$set = [];
$columns = $values = $conditions = $set = [];

foreach ($data as $columnName => $value) {
$setColumns[] = $columnName;
$setValues[] = $value;
$set[] = $columnName . ' = ?';
$columns[] = $columnName;
$values[] = $value;
$set[] = $columnName . ' = ?';
}

[$conditionColumns, $conditionValues, $conditions] = $this->gatherConditions($identifier);
$columns = array_merge($setColumns, $conditionColumns);
$values = array_merge($setValues, $conditionValues);
$this->addIdentifierCondition($identifier, $columns, $values, $conditions);

if (is_string(key($types))) {
$types = $this->extractTypeValues($columns, $types);
Expand Down Expand Up @@ -777,7 +774,7 @@ public function insert($tableExpression, array $data, array $types = [])
/**
* Extract ordered type list from an ordered column list and type map.
*
* @param string[] $columnList
* @param int[]|string[] $columnList
* @param int[]|string[] $types
*
* @return int[]|string[]
Expand Down
9 changes: 6 additions & 3 deletions lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ public function __construct(array $params, $username, $password, $driverOptions
$isPersistent = (isset($params['persistent']) && $params['persistent'] === true);

if ($isPersistent) {
$this->conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
$conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
} else {
$this->conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
$conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
}
if (! $this->conn) {

if ($conn === false) {
throw new DB2Exception(db2_conn_errormsg());
}

$this->conn = $conn;
}

/**
Expand Down
10 changes: 5 additions & 5 deletions lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,16 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
}

/**
* @param int|string $parameter Parameter position or name
* @param mixed $variable
* @param int $position Parameter position
* @param mixed $variable
*
* @throws DB2Exception
*/
private function bind($parameter, &$variable, int $parameterType, int $dataType) : void
private function bind($position, &$variable, int $parameterType, int $dataType) : void
{
$this->bindParam[$parameter] =& $variable;
$this->bindParam[$position] =& $variable;

if (! db2_bind_param($this->stmt, $parameter, 'variable', $parameterType, $dataType)) {
if (! db2_bind_param($this->stmt, $position, 'variable', $parameterType, $dataType)) {
throw new DB2Exception(db2_stmt_errormsg());
}
}
Expand Down
52 changes: 29 additions & 23 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use function fread;
use function get_resource_type;
use function is_array;
use function is_int;
use function is_resource;
use function sprintf;
use function str_repeat;
Expand All @@ -41,7 +42,7 @@ class MysqliStatement implements IteratorAggregate, Statement
/** @var mysqli_stmt */
protected $_stmt;

/** @var string[]|bool|null */
/** @var string[]|false|null */
protected $_columnNames;

/** @var mixed[]|null */
Expand Down Expand Up @@ -78,11 +79,15 @@ class MysqliStatement implements IteratorAggregate, Statement
public function __construct(mysqli $conn, $prepareString)
{
$this->_conn = $conn;
$this->_stmt = $conn->prepare($prepareString);
if ($this->_stmt === false) {

$stmt = $conn->prepare($prepareString);

if ($stmt === false) {
throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno);
}

$this->_stmt = $stmt;

$paramCount = $this->_stmt->param_count;
if (0 >= $paramCount) {
return;
Expand All @@ -97,14 +102,14 @@ public function __construct(mysqli $conn, $prepareString)
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
{
assert(is_int($column));

if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
}

$type = self::$_paramTypeMap[$type];

$this->_bindedValues[$column] =& $variable;
$this->types[$column - 1] = $type;
$this->types[$column - 1] = self::$_paramTypeMap[$type];

return true;
}
Expand All @@ -114,15 +119,15 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
*/
public function bindValue($param, $value, $type = ParameterType::STRING)
{
assert(is_int($param));

if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
}

$type = self::$_paramTypeMap[$type];

$this->_values[$param] = $value;
$this->_bindedValues[$param] =& $this->_values[$param];
$this->types[$param - 1] = $type;
$this->types[$param - 1] = self::$_paramTypeMap[$type];

return true;
}
Expand All @@ -134,15 +139,11 @@ public function execute($params = null)
{
if ($this->_bindedValues !== null) {
if ($params !== null) {
if (! $this->_bindValues($params)) {
if (! $this->bindUntypedValues($params)) {
throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
}
} else {
[$types, $values, $streams] = $this->separateBoundValues();
if (! $this->_stmt->bind_param($types, ...$values)) {
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}
$this->sendLongData($streams);
$this->bindTypedParameters();
}
}

Expand All @@ -153,10 +154,14 @@ public function execute($params = null)
if ($this->_columnNames === null) {
$meta = $this->_stmt->result_metadata();
if ($meta !== false) {
$fields = $meta->fetch_fields();
assert(is_array($fields));

$columnNames = [];
foreach ($meta->fetch_fields() as $col) {
foreach ($fields as $col) {
$columnNames[] = $col->name;
}

$meta->free();

$this->_columnNames = $columnNames;
Expand Down Expand Up @@ -200,12 +205,9 @@ public function execute($params = null)
}

/**
* Split $this->_bindedValues into those values that need to be sent using mysqli::send_long_data()
* and those that can be bound the usual way.
*
* @return array<int, array<int|string, mixed>|string>
* Binds parameters with known types previously bound to the statement
*/
private function separateBoundValues()
private function bindTypedParameters()
{
$streams = $values = [];
$types = $this->types;
Expand All @@ -231,7 +233,11 @@ private function separateBoundValues()
$values[$parameter] = $value;
}

return [$types, $values, $streams];
if (! $this->_stmt->bind_param($types, ...$values)) {
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}

$this->sendLongData($streams);
}

/**
Expand Down Expand Up @@ -263,7 +269,7 @@ private function sendLongData($streams)
*
* @return bool
*/
private function _bindValues($values)
private function bindUntypedValues(array $values)
{
$params = [];
$types = str_repeat('s', count($values));
Expand Down
26 changes: 20 additions & 6 deletions lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@ public function __construct($username, $password, $db, $charset = null, $session
define('OCI_NO_AUTO_COMMIT', 0);
}

$this->dbh = $persistent
$dbh = $persistent
? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
: @oci_connect($username, $password, $db, $charset, $sessionMode);

if (! $this->dbh) {
if ($dbh === false) {
throw OCI8Exception::fromErrorInfo(oci_error());
}

$this->dbh = $dbh;
}

/**
Expand All @@ -71,17 +73,23 @@ public function __construct($username, $password, $db, $charset = null, $session
*/
public function getServerVersion()
{
if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) {
$version = oci_server_version($this->dbh);

if ($version === false) {
throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
}

if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
throw new UnexpectedValueException(
sprintf(
'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
'Please report this database version string to the Doctrine team.',
oci_server_version($this->dbh)
$version
)
);
}

return $version[1];
return $matches[1];
}

/**
Expand Down Expand Up @@ -222,6 +230,12 @@ public function errorCode()
*/
public function errorInfo()
{
return oci_error($this->dbh);
$error = oci_error($this->dbh);

if ($error === false) {
return [];
}

return $error;
}
}
6 changes: 5 additions & 1 deletion lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
class OCI8Exception extends AbstractDriverException
{
/**
* @param mixed[] $error
* @param mixed[]|false $error
*
* @return \Doctrine\DBAL\Driver\OCI8\OCI8Exception
*/
public static function fromErrorInfo($error)
{
if ($error === false) {
return new self('Database error occurred but no error information was retrieved from the driver.');
}

return new self($error['message'], null, $error['code']);
}
}
Loading

0 comments on commit 7f79d04

Please sign in to comment.