diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 9165fce083f..8f3c16d7391 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -12,7 +12,6 @@ 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 @@ public function fetchAll($sql, array $params = [], $types = []) * * @param string $statement The SQL statement to prepare. * - * @return DriverStatement The prepared statement. + * @return Statement The prepared statement. * * @throws DBALException */ @@ -1456,6 +1455,8 @@ public function getWrappedConnection() { $this->connect(); + assert($this->_conn !== null); + return $this->_conn; } diff --git a/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php index b89e2d74c02..2fa71494ad2 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php @@ -12,6 +12,7 @@ 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 @@ public function getDatabase(Connection $conn) { $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; } /** diff --git a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php index e5753fcf76b..8a02dc225b9 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php @@ -13,6 +13,7 @@ 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 @@ public function getDatabase(Connection $conn) { $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; } /** diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php index 60cfb046ee6..2379ae8f5cc 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php @@ -12,6 +12,7 @@ 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 @@ public function getDatabase(Connection $conn) { $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; } /** diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php index 421d82b3951..9cbf25b4b57 100644 --- a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php +++ b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php @@ -11,6 +11,7 @@ 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 @@ public function getDatabase(Connection $conn) { $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; } /** diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php index 6222facf1e4..60652060c5c 100644 --- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php +++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php @@ -13,6 +13,7 @@ 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_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 @@ public function __construct($stmt) */ public function bindValue($param, $value, $type = ParameterType::STRING) { + assert(is_int($param)); + return $this->bindParam($param, $value, $type); } @@ -99,6 +103,8 @@ public function bindValue($param, $value, $type = ParameterType::STRING) */ 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); diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php index 490895f4cda..36376bc731b 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -222,11 +222,12 @@ public function rollBack() public function errorCode() { $error = oci_error($this->dbh); + if ($error !== false) { - $error = $error['code']; + return $error['code']; } - return $error; + return null; } /** diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php index e3d586edb8d..0248e65c2c4 100644 --- a/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -38,7 +38,10 @@ public function __construct($dsn, $user = null, $password = null, ?array $option 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); } diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php index bac9abf7850..7850d704171 100644 --- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php +++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php @@ -12,6 +12,7 @@ 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 @@ public function __construct($conn, $sql) */ 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 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l */ public function bindValue($param, $value, $type = ParameterType::STRING) { + assert(is_int($param)); + return $this->bindParam($param, $value, $type); } diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php index ca7ce0c9ad3..5f3f1a8f524 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php @@ -190,7 +190,7 @@ public function errorCode() return $errors[0]['code']; } - return false; + return null; } /** diff --git a/lib/Doctrine/DBAL/Driver/Statement.php b/lib/Doctrine/DBAL/Driver/Statement.php index 388983e46a6..6b1e162f529 100644 --- a/lib/Doctrine/DBAL/Driver/Statement.php +++ b/lib/Doctrine/DBAL/Driver/Statement.php @@ -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 @@ public function bindValue($param, $value, $type = ParameterType::STRING); * 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. */ diff --git a/lib/Doctrine/DBAL/Query/QueryBuilder.php b/lib/Doctrine/DBAL/Query/QueryBuilder.php index 6d1d1ff740b..669c1dba7c1 100644 --- a/lib/Doctrine/DBAL/Query/QueryBuilder.php +++ b/lib/Doctrine/DBAL/Query/QueryBuilder.php @@ -395,7 +395,7 @@ public function setMaxResults($maxResults) * 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() { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 88ad9e321d2..d1e9bcdd481 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -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 diff --git a/psalm.xml b/psalm.xml index a6e0a0c0558..8256a541406 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,7 +1,7 @@ + + + + + + + + + +