Unverified Commit 3caae110 authored by Grégoire Paris's avatar Grégoire Paris Committed by GitHub

Merge pull request #4094 from morozov/psalm-lvl5

Bump Psalm level to 5
parents 78de4498 b2ffff69
......@@ -12,7 +12,6 @@ use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
......@@ -851,7 +850,7 @@ class Connection implements DriverConnection
*
* @param string $statement The SQL statement to prepare.
*
* @return DriverStatement The prepared statement.
* @return Statement The prepared statement.
*
* @throws DBALException
*/
......@@ -1456,6 +1455,8 @@ class Connection implements DriverConnection
{
$this->connect();
assert($this->_conn !== null);
return $this->_conn;
}
......
......@@ -12,6 +12,7 @@ use Doctrine\DBAL\Platforms\MySQL80Platform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\MySqlSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use function assert;
use function preg_match;
use function stripos;
use function version_compare;
......@@ -197,7 +198,15 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
{
$params = $conn->getParams();
return $params['dbname'] ?? $conn->query('SELECT DATABASE()')->fetchColumn();
if (isset($params['dbname'])) {
return $params['dbname'];
}
$database = $conn->query('SELECT DATABASE()')->fetchColumn();
assert($database !== false);
return $database;
}
/**
......
......@@ -13,6 +13,7 @@ use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use function assert;
use function preg_match;
use function strpos;
use function version_compare;
......@@ -119,7 +120,15 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri
{
$params = $conn->getParams();
return $params['dbname'] ?? $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn();
if (isset($params['dbname'])) {
return $params['dbname'];
}
$database = $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn();
assert($database !== false);
return $database;
}
/**
......
......@@ -12,6 +12,7 @@ use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use function assert;
use function preg_match;
use function version_compare;
......@@ -119,7 +120,15 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
{
$params = $conn->getParams();
return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn();
if (isset($params['dbname'])) {
return $params['dbname'];
}
$database = $conn->query('SELECT DB_NAME()')->fetchColumn();
assert($database !== false);
return $database;
}
/**
......
......@@ -11,6 +11,7 @@ use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use function assert;
use function preg_match;
use function version_compare;
......@@ -60,7 +61,15 @@ abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDr
{
$params = $conn->getParams();
return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn();
if (isset($params['dbname'])) {
return $params['dbname'];
}
$database = $conn->query('SELECT DB_NAME()')->fetchColumn();
assert($database !== false);
return $database;
}
/**
......
......@@ -13,6 +13,7 @@ use ReflectionObject;
use ReflectionProperty;
use stdClass;
use function array_change_key_case;
use function assert;
use function db2_bind_param;
use function db2_execute;
use function db2_fetch_array;
......@@ -30,6 +31,7 @@ use function func_get_args;
use function func_num_args;
use function fwrite;
use function gettype;
use function is_int;
use function is_object;
use function is_resource;
use function is_string;
......@@ -91,6 +93,8 @@ class DB2Statement implements IteratorAggregate, Statement
*/
public function bindValue($param, $value, $type = ParameterType::STRING)
{
assert(is_int($param));
return $this->bindParam($param, $value, $type);
}
......@@ -99,6 +103,8 @@ class DB2Statement implements IteratorAggregate, Statement
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
{
assert(is_int($column));
switch ($type) {
case ParameterType::INTEGER:
$this->bind($column, $variable, DB2_PARAM_IN, DB2_LONG);
......
......@@ -222,11 +222,12 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
public function errorCode()
{
$error = oci_error($this->dbh);
if ($error !== false) {
$error = $error['code'];
return $error['code'];
}
return $error;
return null;
}
/**
......
......@@ -38,7 +38,10 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
public function exec($statement)
{
try {
return parent::exec($statement);
$result = parent::exec($statement);
assert($result !== false);
return $result;
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
......
......@@ -12,6 +12,7 @@ use ReflectionClass;
use ReflectionObject;
use stdClass;
use function array_key_exists;
use function assert;
use function func_get_args;
use function func_num_args;
use function gettype;
......@@ -91,6 +92,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
{
assert(is_int($column));
switch ($type) {
case ParameterType::INTEGER:
case ParameterType::BOOLEAN:
......@@ -125,6 +128,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*/
public function bindValue($param, $value, $type = ParameterType::STRING)
{
assert(is_int($param));
return $this->bindParam($param, $value, $type);
}
......
......@@ -190,7 +190,7 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection
return $errors[0]['code'];
}
return false;
return null;
}
/**
......
......@@ -19,12 +19,12 @@ 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 int|string $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.
*
* @return bool TRUE on success or FALSE on failure.
*/
......@@ -44,15 +44,15 @@ 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. To return an INOUT parameter from a stored procedure, use the bitwise
* OR operator to set the PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
* @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 int|string $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. To return an INOUT parameter from a stored procedure, use the bitwise
* OR operator to set the PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
* @param int|null $length You must specify maxlength when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
*
* @return bool TRUE on success or FALSE on failure.
*/
......
......@@ -395,7 +395,7 @@ class QueryBuilder
* Gets the maximum number of results the query object was set to retrieve (the "limit").
* Returns NULL if all results will be returned.
*
* @return int The maximum number of results.
* @return int|null The maximum number of results.
*/
public function getMaxResults()
{
......
......@@ -95,3 +95,8 @@ parameters:
message: '~Method Doctrine\\DBAL\\Driver\\PDOSqlsrv\\Connection\:\:lastInsertId\(\) should return string but returns string\|false\|null\.~'
paths:
- %currentWorkingDirectory%/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php
-
message: '~Method Doctrine\\DBAL\\Portability\\Connection::prepare\(\) should return Doctrine\\DBAL\\Statement but returns Doctrine\\DBAL\\Portability\\Statement\.~'
paths:
- %currentWorkingDirectory%/lib/Doctrine/DBAL/Portability/Connection.php
<?xml version="1.0"?>
<psalm
totallyTyped="false"
errorLevel="6"
errorLevel="5"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
......@@ -32,6 +32,15 @@
<file name="lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php"/>
</errorLevel>
</ConflictingReferenceConstraint>
<FalsableReturnStatement>
<errorLevel type="suppress">
<!--
Fixing these issues requires an API change
-->
<file name="lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php"/>
<file name="lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php"/>
</errorLevel>
</FalsableReturnStatement>
<MethodSignatureMismatch>
<errorLevel type="suppress">
<!--
......@@ -41,6 +50,14 @@
<file name="lib/Doctrine/DBAL/Driver/PDOConnection.php"/>
</errorLevel>
</MethodSignatureMismatch>
<NullableReturnStatement>
<errorLevel type="suppress">
<!--
Fixing this issue requires an API change
-->
<file name="lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php"/>
</errorLevel>
</NullableReturnStatement>
<TooFewArguments>
<errorLevel type="suppress">
<!--
......
......@@ -39,7 +39,7 @@ class DriverTest extends PDOMySQLDriverTest
}
/**
* @return mixed[][]
* {@inheritDoc}
*/
protected function getDatabasePlatformsForVersions() : array
{
......
......@@ -5,12 +5,14 @@ namespace Doctrine\Tests\DBAL\Driver;
use Doctrine\DBAL\Driver\IBMDB2\DB2Statement;
use Doctrine\DBAL\Driver\Mysqli\MysqliStatement;
use Doctrine\DBAL\Driver\OCI8\OCI8Statement;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereStatement;
use Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Portability\Statement as PortabilityStatement;
use Doctrine\Tests\DbalTestCase;
use IteratorIterator;
use PHPUnit\Framework\MockObject\MockObject;
use Traversable;
use function extension_loaded;
......@@ -18,16 +20,19 @@ use function extension_loaded;
class StatementIteratorTest extends DbalTestCase
{
/**
* @param class-string<ResultStatement> $class
*
* @dataProvider statementProvider()
*/
public function testGettingIteratorDoesNotCallFetch(string $class) : void
{
$stmt = $this->createPartialMock($class, ['fetch', 'fetchAll', 'fetchColumn']);
$stmt->expects($this->never())->method('fetch');
$stmt->expects($this->never())->method('fetchAll');
$stmt->expects($this->never())->method('fetchColumn');
$stmt->getIterator();
new IteratorIterator($stmt);
}
public function testIteratorIterationCallsFetchOncePerStep() : void
......
......@@ -3,7 +3,7 @@
namespace Doctrine\Tests\DBAL\Functional\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver;
use Doctrine\Tests\DBAL\Functional\Driver\AbstractDriverTest;
use Doctrine\Tests\TestUtil;
......@@ -40,7 +40,7 @@ class DriverTest extends AbstractDriverTest
/**
* @param int[]|string[] $driverOptions
*/
protected function getConnection(array $driverOptions) : Connection
private function getConnection(array $driverOptions) : PDOConnection
{
$params = TestUtil::getConnectionParams();
......
......@@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Functional\Ticket;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\ParameterType;
use Doctrine\Tests\DbalFunctionalTestCase;
use PDO;
......@@ -38,7 +39,7 @@ class DBAL630Test extends DbalFunctionalTestCase
protected function tearDown() : void
{
if ($this->running) {
$this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
parent::tearDown();
......@@ -72,7 +73,7 @@ class DBAL630Test extends DbalFunctionalTestCase
public function testBooleanConversionBoolParamEmulatedPrepares() : void
{
$this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$this->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
......@@ -96,7 +97,7 @@ class DBAL630Test extends DbalFunctionalTestCase
?bool $statementValue,
?bool $databaseConvertedValue
) : void {
$this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$this->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
......@@ -120,7 +121,7 @@ class DBAL630Test extends DbalFunctionalTestCase
?bool $statementValue,
bool $databaseConvertedValue
) : void {
$this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$this->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
......@@ -170,4 +171,12 @@ class DBAL630Test extends DbalFunctionalTestCase
[null, null],
];
}
private function getWrappedConnection() : PDOConnection
{
$connection = $this->connection->getWrappedConnection();
self::assertInstanceOf(PDOConnection::class, $connection);
return $connection;
}
}
......@@ -152,7 +152,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
}
......
......@@ -250,7 +250,7 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
self::assertEquals($sql, $this->getGenerateForeignKeySql());
}
abstract public function getGenerateForeignKeySql() : string;
abstract protected function getGenerateForeignKeySql() : string;
public function testGeneratesConstraintCreationSql() : void
{
......
......@@ -65,7 +65,7 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE';
}
......
......@@ -181,7 +181,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
return 'CREATE UNIQUE INDEX index_name ON test (test, test2) WHERE test IS NOT NULL AND test2 IS NOT NULL';
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
}
......
......@@ -42,7 +42,7 @@ class DB2PlatformTest extends AbstractPlatformTestCase
];
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
}
......
......@@ -93,7 +93,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
}
/**
* @return mixed[]
* {@inheritDoc}
*/
public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
{
......@@ -234,7 +234,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
}
......@@ -408,7 +408,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
}
/**
* @return mixed[]
* {@inheritDoc}
*/
protected function getQuotedColumnInPrimaryKeySQL() : array
{
......@@ -416,7 +416,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
}
/**
* @return mixed[]
* {@inheritDoc}
*/
protected function getQuotedColumnInIndexSQL() : array
{
......@@ -427,7 +427,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
}
/**
* @return mixed[]
* {@inheritDoc}
*/
protected function getQuotedNameInIndexSQL() : array
{
......@@ -438,7 +438,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
}
/**
* @return mixed[]
* {@inheritDoc}
*/
protected function getQuotedColumnInForeignKeySQL() : array
{
......
......@@ -43,7 +43,7 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
];
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
}
......
......@@ -286,9 +286,9 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
parent::testGeneratesConstraintCreationSql();
}
public function getGenerateForeignKeySql() : string
protected function getGenerateForeignKeySql() : string
{
return null;
return '';
}
public function testModifyLimitQuery() : void
......
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