PHPStan Level 7

parent 30b9231c
...@@ -459,11 +459,11 @@ class Connection implements DriverConnection ...@@ -459,11 +459,11 @@ class Connection implements DriverConnection
*/ */
private function getServerVersion() private function getServerVersion()
{ {
$connection = $this->getWrappedConnection();
// Automatic platform version detection. // Automatic platform version detection.
if ($this->_conn instanceof ServerInfoAwareConnection && if ($connection instanceof ServerInfoAwareConnection && ! $connection->requiresQueryForServerVersion()) {
! $this->_conn->requiresQueryForServerVersion() return $connection->getServerVersion();
) {
return $this->_conn->getServerVersion();
} }
// Unable to detect platform version. // Unable to detect platform version.
...@@ -810,20 +810,15 @@ class Connection implements DriverConnection ...@@ -810,20 +810,15 @@ class Connection implements DriverConnection
} }
/** /**
* Quotes a given input parameter. * {@inheritDoc}
*
* @param mixed $input The parameter to be quoted.
* @param int|null $type The type of the parameter.
*
* @return string The quoted parameter.
*/ */
public function quote($input, $type = null) public function quote($input, $type = null)
{ {
$this->connect(); $connection = $this->getWrappedConnection();
[$value, $bindingType] = $this->getBindingInfo($input, $type); [$value, $bindingType] = $this->getBindingInfo($input, $type);
return $this->_conn->quote($value, $bindingType); return $connection->quote($value, $bindingType);
} }
/** /**
...@@ -883,7 +878,7 @@ class Connection implements DriverConnection ...@@ -883,7 +878,7 @@ class Connection implements DriverConnection
return $this->executeCacheQuery($query, $params, $types, $qcp); return $this->executeCacheQuery($query, $params, $types, $qcp);
} }
$this->connect(); $connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger(); $logger = $this->_config->getSQLLogger();
if ($logger) { if ($logger) {
...@@ -894,7 +889,7 @@ class Connection implements DriverConnection ...@@ -894,7 +889,7 @@ class Connection implements DriverConnection
if ($params) { if ($params) {
[$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types);
$stmt = $this->_conn->prepare($query); $stmt = $connection->prepare($query);
if ($types) { if ($types) {
$this->_bindTypedValues($stmt, $params, $types); $this->_bindTypedValues($stmt, $params, $types);
$stmt->execute(); $stmt->execute();
...@@ -902,7 +897,7 @@ class Connection implements DriverConnection ...@@ -902,7 +897,7 @@ class Connection implements DriverConnection
$stmt->execute($params); $stmt->execute($params);
} }
} else { } else {
$stmt = $this->_conn->query($query); $stmt = $connection->query($query);
} }
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types));
...@@ -931,8 +926,9 @@ class Connection implements DriverConnection ...@@ -931,8 +926,9 @@ class Connection implements DriverConnection
*/ */
public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp)
{ {
$resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl(); $resultCache = $qcp->getResultCacheDriver() ?? $this->_config->getResultCacheImpl();
if (! $resultCache) {
if ($resultCache === null) {
throw CacheException::noResultDriverConfigured(); throw CacheException::noResultDriverConfigured();
} }
...@@ -994,7 +990,7 @@ class Connection implements DriverConnection ...@@ -994,7 +990,7 @@ class Connection implements DriverConnection
*/ */
public function query() public function query()
{ {
$this->connect(); $connection = $this->getWrappedConnection();
$args = func_get_args(); $args = func_get_args();
...@@ -1004,7 +1000,7 @@ class Connection implements DriverConnection ...@@ -1004,7 +1000,7 @@ class Connection implements DriverConnection
} }
try { try {
$statement = $this->_conn->query(...$args); $statement = $connection->query(...$args);
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]); throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]);
} }
...@@ -1034,7 +1030,7 @@ class Connection implements DriverConnection ...@@ -1034,7 +1030,7 @@ class Connection implements DriverConnection
*/ */
public function executeUpdate($query, array $params = [], array $types = []) public function executeUpdate($query, array $params = [], array $types = [])
{ {
$this->connect(); $connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger(); $logger = $this->_config->getSQLLogger();
if ($logger) { if ($logger) {
...@@ -1045,7 +1041,8 @@ class Connection implements DriverConnection ...@@ -1045,7 +1041,8 @@ class Connection implements DriverConnection
if ($params) { if ($params) {
[$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types);
$stmt = $this->_conn->prepare($query); $stmt = $connection->prepare($query);
if ($types) { if ($types) {
$this->_bindTypedValues($stmt, $params, $types); $this->_bindTypedValues($stmt, $params, $types);
$stmt->execute(); $stmt->execute();
...@@ -1054,7 +1051,7 @@ class Connection implements DriverConnection ...@@ -1054,7 +1051,7 @@ class Connection implements DriverConnection
} }
$result = $stmt->rowCount(); $result = $stmt->rowCount();
} else { } else {
$result = $this->_conn->exec($query); $result = $connection->exec($query);
} }
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types));
...@@ -1078,7 +1075,7 @@ class Connection implements DriverConnection ...@@ -1078,7 +1075,7 @@ class Connection implements DriverConnection
*/ */
public function exec($statement) public function exec($statement)
{ {
$this->connect(); $connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger(); $logger = $this->_config->getSQLLogger();
if ($logger) { if ($logger) {
...@@ -1086,7 +1083,7 @@ class Connection implements DriverConnection ...@@ -1086,7 +1083,7 @@ class Connection implements DriverConnection
} }
try { try {
$result = $this->_conn->exec($statement); $result = $connection->exec($statement);
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement); throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement);
} }
...@@ -1115,9 +1112,7 @@ class Connection implements DriverConnection ...@@ -1115,9 +1112,7 @@ class Connection implements DriverConnection
*/ */
public function errorCode() public function errorCode()
{ {
$this->connect(); return $this->getWrappedConnection()->errorCode();
return $this->_conn->errorCode();
} }
/** /**
...@@ -1125,9 +1120,7 @@ class Connection implements DriverConnection ...@@ -1125,9 +1120,7 @@ class Connection implements DriverConnection
*/ */
public function errorInfo() public function errorInfo()
{ {
$this->connect(); return $this->getWrappedConnection()->errorInfo();
return $this->_conn->errorInfo();
} }
/** /**
...@@ -1144,9 +1137,7 @@ class Connection implements DriverConnection ...@@ -1144,9 +1137,7 @@ class Connection implements DriverConnection
*/ */
public function lastInsertId($seqName = null) public function lastInsertId($seqName = null)
{ {
$this->connect(); return $this->getWrappedConnection()->lastInsertId($seqName);
return $this->_conn->lastInsertId($seqName);
} }
/** /**
...@@ -1228,7 +1219,7 @@ class Connection implements DriverConnection ...@@ -1228,7 +1219,7 @@ class Connection implements DriverConnection
*/ */
public function beginTransaction() public function beginTransaction()
{ {
$this->connect(); $connection = $this->getWrappedConnection();
++$this->transactionNestingLevel; ++$this->transactionNestingLevel;
...@@ -1238,7 +1229,9 @@ class Connection implements DriverConnection ...@@ -1238,7 +1229,9 @@ class Connection implements DriverConnection
if ($logger) { if ($logger) {
$logger->startQuery('"START TRANSACTION"'); $logger->startQuery('"START TRANSACTION"');
} }
$this->_conn->beginTransaction();
$connection->beginTransaction();
if ($logger) { if ($logger) {
$logger->stopQuery(); $logger->stopQuery();
} }
...@@ -1270,7 +1263,7 @@ class Connection implements DriverConnection ...@@ -1270,7 +1263,7 @@ class Connection implements DriverConnection
throw ConnectionException::commitFailedRollbackOnly(); throw ConnectionException::commitFailedRollbackOnly();
} }
$this->connect(); $connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger(); $logger = $this->_config->getSQLLogger();
...@@ -1278,7 +1271,9 @@ class Connection implements DriverConnection ...@@ -1278,7 +1271,9 @@ class Connection implements DriverConnection
if ($logger) { if ($logger) {
$logger->startQuery('"COMMIT"'); $logger->startQuery('"COMMIT"');
} }
$this->_conn->commit();
$connection->commit();
if ($logger) { if ($logger) {
$logger->stopQuery(); $logger->stopQuery();
} }
...@@ -1332,7 +1327,7 @@ class Connection implements DriverConnection ...@@ -1332,7 +1327,7 @@ class Connection implements DriverConnection
throw ConnectionException::noActiveTransaction(); throw ConnectionException::noActiveTransaction();
} }
$this->connect(); $connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger(); $logger = $this->_config->getSQLLogger();
...@@ -1341,7 +1336,7 @@ class Connection implements DriverConnection ...@@ -1341,7 +1336,7 @@ class Connection implements DriverConnection
$logger->startQuery('"ROLLBACK"'); $logger->startQuery('"ROLLBACK"');
} }
$this->transactionNestingLevel = 0; $this->transactionNestingLevel = 0;
$this->_conn->rollBack(); $connection->rollBack();
$this->isRollbackOnly = false; $this->isRollbackOnly = false;
if ($logger) { if ($logger) {
$logger->stopQuery(); $logger->stopQuery();
...@@ -1380,7 +1375,7 @@ class Connection implements DriverConnection ...@@ -1380,7 +1375,7 @@ class Connection implements DriverConnection
throw ConnectionException::savepointsNotSupported(); throw ConnectionException::savepointsNotSupported();
} }
$this->_conn->exec($this->platform->createSavePoint($savepoint)); $this->getWrappedConnection()->exec($this->platform->createSavePoint($savepoint));
} }
/** /**
...@@ -1402,7 +1397,7 @@ class Connection implements DriverConnection ...@@ -1402,7 +1397,7 @@ class Connection implements DriverConnection
return; return;
} }
$this->_conn->exec($this->platform->releaseSavePoint($savepoint)); $this->getWrappedConnection()->exec($this->platform->releaseSavePoint($savepoint));
} }
/** /**
...@@ -1420,17 +1415,18 @@ class Connection implements DriverConnection ...@@ -1420,17 +1415,18 @@ class Connection implements DriverConnection
throw ConnectionException::savepointsNotSupported(); throw ConnectionException::savepointsNotSupported();
} }
$this->_conn->exec($this->platform->rollbackSavePoint($savepoint)); $this->getWrappedConnection()->exec($this->platform->rollbackSavePoint($savepoint));
} }
/** /**
* Gets the wrapped driver connection. * Gets the wrapped driver connection.
* *
* @return \Doctrine\DBAL\Driver\Connection * @return DriverConnection
*/ */
public function getWrappedConnection() public function getWrappedConnection()
{ {
$this->connect(); $this->connect();
assert($this->_conn instanceof DriverConnection);
return $this->_conn; return $this->_conn;
} }
...@@ -1559,7 +1555,7 @@ class Connection implements DriverConnection ...@@ -1559,7 +1555,7 @@ class Connection implements DriverConnection
* Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type. * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type.
* *
* @param mixed $value The value to bind. * @param mixed $value The value to bind.
* @param int|string $type The type to bind (PDO or DBAL). * @param int|string|null $type The type to bind (PDO or DBAL).
* *
* @return mixed[] [0] => the (escaped) value, [1] => the binding type. * @return mixed[] [0] => the (escaped) value, [1] => the binding type.
*/ */
...@@ -1658,10 +1654,10 @@ class Connection implements DriverConnection ...@@ -1658,10 +1654,10 @@ class Connection implements DriverConnection
*/ */
public function ping() public function ping()
{ {
$this->connect(); $connection = $this->getWrappedConnection();
if ($this->_conn instanceof PingableConnection) { if ($connection instanceof PingableConnection) {
return $this->_conn->ping(); return $connection->ping();
} }
try { try {
......
...@@ -11,6 +11,7 @@ use Doctrine\DBAL\Event\ConnectionEventArgs; ...@@ -11,6 +11,7 @@ use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events; use Doctrine\DBAL\Events;
use InvalidArgumentException; use InvalidArgumentException;
use function array_rand; use function array_rand;
use function assert;
use function count; use function count;
use function func_get_args; use function func_get_args;
...@@ -344,6 +345,7 @@ class MasterSlaveConnection extends Connection ...@@ -344,6 +345,7 @@ class MasterSlaveConnection extends Connection
public function query() public function query()
{ {
$this->connect('master'); $this->connect('master');
assert($this->_conn instanceof DriverConnection);
$args = func_get_args(); $args = func_get_args();
......
...@@ -17,8 +17,8 @@ use function is_object; ...@@ -17,8 +17,8 @@ use function is_object;
use function is_resource; use function is_resource;
use function is_string; use function is_string;
use function json_encode; use function json_encode;
use function preg_replace;
use function sprintf; use function sprintf;
use function str_split;
class DBALException extends Exception class DBALException extends Exception
{ {
...@@ -186,7 +186,7 @@ class DBALException extends Exception ...@@ -186,7 +186,7 @@ class DBALException extends Exception
if (! is_string($json) || $json === 'null' && is_string($param)) { if (! is_string($json) || $json === 'null' && is_string($param)) {
// JSON encoding failed, this is not a UTF-8 string. // JSON encoding failed, this is not a UTF-8 string.
return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"'; return sprintf('"%s"', preg_replace('/.{2}/', '\\x$0', bin2hex($param)));
} }
return $json; return $json;
......
...@@ -34,7 +34,7 @@ class DB2Driver extends AbstractDB2Driver ...@@ -34,7 +34,7 @@ class DB2Driver extends AbstractDB2Driver
$password = null; $password = null;
} }
return new DB2Connection($params, $username, $password, $driverOptions); return new DB2Connection($params, (string) $username, (string) $password, $driverOptions);
} }
/** /**
......
...@@ -13,7 +13,7 @@ class Driver extends AbstractMySQLDriver ...@@ -13,7 +13,7 @@ class Driver extends AbstractMySQLDriver
public function connect(array $params, $username = null, $password = null, array $driverOptions = []) public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
{ {
try { try {
return new MysqliConnection($params, $username, $password, $driverOptions); return new MysqliConnection($params, (string) $username, (string) $password, $driverOptions);
} catch (MysqliException $e) { } catch (MysqliException $e) {
throw DBALException::driverException($this, $e); throw DBALException::driverException($this, $e);
} }
......
...@@ -45,8 +45,8 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -45,8 +45,8 @@ class MysqliStatement implements IteratorAggregate, Statement
/** @var string[]|false|null */ /** @var string[]|false|null */
protected $_columnNames; protected $_columnNames;
/** @var mixed[]|null */ /** @var mixed[] */
protected $_rowBindedValues; protected $_rowBindedValues = [];
/** @var mixed[] */ /** @var mixed[] */
protected $_bindedValues; protected $_bindedValues;
...@@ -318,6 +318,7 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -318,6 +318,7 @@ class MysqliStatement implements IteratorAggregate, Statement
} }
$values = $this->_fetch(); $values = $this->_fetch();
if ($values === null) { if ($values === null) {
return false; return false;
} }
......
...@@ -18,10 +18,10 @@ class Driver extends AbstractOracleDriver ...@@ -18,10 +18,10 @@ class Driver extends AbstractOracleDriver
{ {
try { try {
return new OCI8Connection( return new OCI8Connection(
$username, (string) $username,
$password, (string) $password,
$this->_constructDsn($params), $this->_constructDsn($params),
$params['charset'] ?? null, $params['charset'] ?? '',
$params['sessionMode'] ?? OCI_DEFAULT, $params['sessionMode'] ?? OCI_DEFAULT,
$params['persistent'] ?? false $params['persistent'] ?? false
); );
......
...@@ -10,8 +10,6 @@ use const OCI_COMMIT_ON_SUCCESS; ...@@ -10,8 +10,6 @@ use const OCI_COMMIT_ON_SUCCESS;
use const OCI_DEFAULT; use const OCI_DEFAULT;
use const OCI_NO_AUTO_COMMIT; use const OCI_NO_AUTO_COMMIT;
use function addcslashes; use function addcslashes;
use function define;
use function defined;
use function func_get_args; use function func_get_args;
use function is_float; use function is_float;
use function is_int; use function is_int;
...@@ -42,18 +40,20 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection ...@@ -42,18 +40,20 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
* @param string $username * @param string $username
* @param string $password * @param string $password
* @param string $db * @param string $db
* @param string|null $charset * @param string $charset
* @param int $sessionMode * @param int $sessionMode
* @param bool $persistent * @param bool $persistent
* *
* @throws OCI8Exception * @throws OCI8Exception
*/ */
public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT, $persistent = false) public function __construct(
{ $username,
if (! defined('OCI_NO_AUTO_COMMIT')) { $password,
define('OCI_NO_AUTO_COMMIT', 0); $db,
} $charset = '',
$sessionMode = OCI_DEFAULT,
$persistent = false
) {
$dbh = $persistent $dbh = $persistent
? @oci_pconnect($username, $password, $db, $charset, $sessionMode) ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
: @oci_connect($username, $password, $db, $charset, $sessionMode); : @oci_connect($username, $password, $db, $charset, $sessionMode);
......
...@@ -215,8 +215,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -215,8 +215,7 @@ class OCI8Statement implements IteratorAggregate, Statement
* *
* @param string $statement The SQL statement to parse * @param string $statement The SQL statement to parse
* @param string $tokenOffset The offset to start searching from * @param string $tokenOffset The offset to start searching from
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal * @param string $currentLiteralDelimiter The delimiter of the current string literal
* or NULL if not currently in a literal
* *
* @return bool Whether the token was found * @return bool Whether the token was found
*/ */
...@@ -274,7 +273,7 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -274,7 +273,7 @@ class OCI8Statement implements IteratorAggregate, Statement
*/ */
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
{ {
$column = $this->_paramMap[$column] ?? $column; $column = $this->_paramMap[$column];
if ($type === ParameterType::LARGE_OBJECT) { if ($type === ParameterType::LARGE_OBJECT) {
$lob = oci_new_descriptor($this->_dbh, OCI_D_LOB); $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
......
...@@ -24,7 +24,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection ...@@ -24,7 +24,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
public function __construct($dsn, $user = null, $password = null, ?array $options = null) public function __construct($dsn, $user = null, $password = null, ?array $options = null)
{ {
try { try {
parent::__construct($dsn, $user, $password, $options); parent::__construct($dsn, (string) $user, (string) $password, (array) $options);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
...@@ -95,6 +95,10 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection ...@@ -95,6 +95,10 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
public function lastInsertId($name = null) public function lastInsertId($name = null)
{ {
try { try {
if ($name === null) {
return parent::lastInsertId();
}
return parent::lastInsertId($name); return parent::lastInsertId($name);
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
......
...@@ -6,7 +6,9 @@ use Doctrine\DBAL\FetchMode; ...@@ -6,7 +6,9 @@ use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\ParameterType;
use PDO; use PDO;
use const E_USER_DEPRECATED; use const E_USER_DEPRECATED;
use function array_slice;
use function assert; use function assert;
use function func_get_args;
use function is_array; use function is_array;
use function sprintf; use function sprintf;
use function trigger_error; use function trigger_error;
...@@ -90,7 +92,7 @@ class PDOStatement extends \PDOStatement implements Statement ...@@ -90,7 +92,7 @@ class PDOStatement extends \PDOStatement implements Statement
$type = $this->convertParamType($type); $type = $this->convertParamType($type);
try { try {
return parent::bindParam($column, $variable, $type, $length, $driverOptions); return parent::bindParam($column, $variable, $type, ...array_slice(func_get_args(), 3));
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
...@@ -127,22 +129,14 @@ class PDOStatement extends \PDOStatement implements Statement ...@@ -127,22 +129,14 @@ class PDOStatement extends \PDOStatement implements Statement
*/ */
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
{ {
$fetchMode = $this->convertFetchMode($fetchMode); $args = func_get_args();
try {
if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
return parent::fetch();
}
if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
return parent::fetch($fetchMode);
}
if ($cursorOffset === 0) { if (isset($args[0])) {
return parent::fetch($fetchMode, $cursorOrientation); $args[0] = $this->convertFetchMode($args[0]);
} }
return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset); try {
return parent::fetch(...$args);
} catch (\PDOException $exception) { } catch (\PDOException $exception) {
throw new PDOException($exception); throw new PDOException($exception);
} }
...@@ -153,7 +147,11 @@ class PDOStatement extends \PDOStatement implements Statement ...@@ -153,7 +147,11 @@ class PDOStatement extends \PDOStatement implements Statement
*/ */
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
{ {
$fetchMode = $this->convertFetchMode($fetchMode); $args = func_get_args();
if (isset($args[0])) {
$args[0] = $this->convertFetchMode($args[0]);
}
if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) {
$args = []; $args = [];
...@@ -210,14 +208,10 @@ class PDOStatement extends \PDOStatement implements Statement ...@@ -210,14 +208,10 @@ class PDOStatement extends \PDOStatement implements Statement
/** /**
* Converts DBAL fetch mode to PDO fetch mode * Converts DBAL fetch mode to PDO fetch mode
* *
* @param int|null $fetchMode Fetch mode * @param int $fetchMode Fetch mode
*/ */
private function convertFetchMode(?int $fetchMode) : ?int private function convertFetchMode(int $fetchMode) : int
{ {
if ($fetchMode === null) {
return null;
}
if (! isset(self::FETCH_MODE_MAP[$fetchMode])) { if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
// TODO: next major: throw an exception // TODO: next major: throw an exception
@trigger_error(sprintf( @trigger_error(sprintf(
......
...@@ -190,6 +190,6 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection ...@@ -190,6 +190,6 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection
*/ */
public function errorInfo() public function errorInfo()
{ {
return sqlsrv_errors(SQLSRV_ERR_ERRORS); return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS);
} }
} }
...@@ -16,12 +16,11 @@ class SQLSrvException extends AbstractDriverException ...@@ -16,12 +16,11 @@ class SQLSrvException extends AbstractDriverException
*/ */
public static function fromSqlSrvErrors() public static function fromSqlSrvErrors()
{ {
$errors = sqlsrv_errors(SQLSRV_ERR_ERRORS);
$message = ''; $message = '';
$sqlState = null; $sqlState = null;
$errorCode = null; $errorCode = null;
foreach ($errors as $error) { foreach ((array) sqlsrv_errors(SQLSRV_ERR_ERRORS) as $error) {
$message .= 'SQLSTATE [' . $error['SQLSTATE'] . ', ' . $error['code'] . ']: ' . $error['message'] . "\n"; $message .= 'SQLSTATE [' . $error['SQLSTATE'] . ', ' . $error['code'] . ']: ' . $error['message'] . "\n";
if ($sqlState === null) { if ($sqlState === null) {
...@@ -34,6 +33,7 @@ class SQLSrvException extends AbstractDriverException ...@@ -34,6 +33,7 @@ class SQLSrvException extends AbstractDriverException
$errorCode = $error['code']; $errorCode = $error['code'];
} }
if (! $message) { if (! $message) {
$message = 'SQL Server error occurred but no error message was retrieved from driver.'; $message = 'SQL Server error occurred but no error message was retrieved from driver.';
} }
......
...@@ -180,7 +180,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -180,7 +180,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
public function closeCursor() public function closeCursor()
{ {
// not having the result means there's nothing to close // not having the result means there's nothing to close
if (! $this->result) { if ($this->stmt === null || ! $this->result) {
return true; return true;
} }
...@@ -226,7 +226,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -226,7 +226,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/ */
public function errorInfo() public function errorInfo()
{ {
return sqlsrv_errors(SQLSRV_ERR_ERRORS); return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS);
} }
/** /**
...@@ -337,7 +337,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -337,7 +337,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
{ {
// 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
if (! $this->result) { if ($this->stmt === null || ! $this->result) {
return false; return false;
} }
......
...@@ -48,7 +48,7 @@ interface Statement extends ResultStatement ...@@ -48,7 +48,7 @@ interface Statement extends ResultStatement
* this will be a parameter name of the form :name. For a prepared statement using * 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. * 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 mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
* @param int|null $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType} * @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 * 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. * 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 * @param int|null $length You must specify maxlength when using an OUT bind
......
...@@ -27,12 +27,14 @@ use Doctrine\DBAL\TransactionIsolationLevel; ...@@ -27,12 +27,14 @@ use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types; use Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use InvalidArgumentException; use InvalidArgumentException;
use UnexpectedValueException;
use const E_USER_DEPRECATED; use const E_USER_DEPRECATED;
use function addcslashes; use function addcslashes;
use function array_map; use function array_map;
use function array_merge; use function array_merge;
use function array_unique; use function array_unique;
use function array_values; use function array_values;
use function assert;
use function count; use function count;
use function explode; use function explode;
use function func_get_arg; use function func_get_arg;
...@@ -486,6 +488,8 @@ abstract class AbstractPlatform ...@@ -486,6 +488,8 @@ abstract class AbstractPlatform
$this->initializeCommentedDoctrineTypes(); $this->initializeCommentedDoctrineTypes();
} }
assert(is_array($this->doctrineTypeComments));
return in_array($doctrineType->getName(), $this->doctrineTypeComments); return in_array($doctrineType->getName(), $this->doctrineTypeComments);
} }
...@@ -502,6 +506,8 @@ abstract class AbstractPlatform ...@@ -502,6 +506,8 @@ abstract class AbstractPlatform
$this->initializeCommentedDoctrineTypes(); $this->initializeCommentedDoctrineTypes();
} }
assert(is_array($this->doctrineTypeComments));
$this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType; $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType;
} }
...@@ -1419,7 +1425,13 @@ abstract class AbstractPlatform ...@@ -1419,7 +1425,13 @@ abstract class AbstractPlatform
$this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs);
if ($eventArgs->isDefaultPrevented()) { if ($eventArgs->isDefaultPrevented()) {
return $eventArgs->getSql(); $sql = $eventArgs->getSql();
if ($sql === null) {
throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL');
}
return $sql;
} }
} }
......
...@@ -6,7 +6,6 @@ use Doctrine\DBAL\DBALException; ...@@ -6,7 +6,6 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\Identifier; use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use function array_merge; use function array_merge;
...@@ -571,7 +570,7 @@ class DB2Platform extends AbstractPlatform ...@@ -571,7 +570,7 @@ class DB2Platform extends AbstractPlatform
} }
} }
$this->gatherAlterColumnSQL($diff->fromTable, $columnDiff, $sql, $queryParts); $this->gatherAlterColumnSQL($diff->getName($this), $columnDiff, $sql, $queryParts);
} }
foreach ($diff->renamedColumns as $oldColumnName => $column) { foreach ($diff->renamedColumns as $oldColumnName => $column) {
...@@ -622,12 +621,12 @@ class DB2Platform extends AbstractPlatform ...@@ -622,12 +621,12 @@ class DB2Platform extends AbstractPlatform
/** /**
* Gathers the table alteration SQL for a given column diff. * Gathers the table alteration SQL for a given column diff.
* *
* @param Table $table The table to gather the SQL for. * @param Identifier $table The table to gather the SQL for.
* @param ColumnDiff $columnDiff The column diff to evaluate. * @param ColumnDiff $columnDiff The column diff to evaluate.
* @param string[] $sql The sequence of table alteration statements to fill. * @param string[] $sql The sequence of table alteration statements to fill.
* @param mixed[] $queryParts The sequence of column alteration clauses to fill. * @param mixed[] $queryParts The sequence of column alteration clauses to fill.
*/ */
private function gatherAlterColumnSQL(Table $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts) private function gatherAlterColumnSQL(Identifier $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts)
{ {
$alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff);
......
...@@ -47,9 +47,7 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -47,9 +47,7 @@ class DrizzlePlatform extends AbstractPlatform
*/ */
public function getConcatExpression() public function getConcatExpression()
{ {
$args = func_get_args(); return 'CONCAT(' . implode(', ', func_get_args()) . ')';
return 'CONCAT(' . implode(', ', (array) $args) . ')';
} }
/** /**
......
...@@ -23,7 +23,7 @@ use function func_get_args; ...@@ -23,7 +23,7 @@ use function func_get_args;
use function get_class; use function get_class;
use function implode; use function implode;
use function is_string; use function is_string;
use function preg_replace; use function preg_match;
use function sprintf; use function sprintf;
use function strlen; use function strlen;
use function strpos; use function strpos;
...@@ -1312,9 +1312,15 @@ SQL ...@@ -1312,9 +1312,15 @@ SQL
{ {
$limitOffsetClause = $this->getTopClauseSQL($limit, $offset); $limitOffsetClause = $this->getTopClauseSQL($limit, $offset);
return $limitOffsetClause === '' if ($limitOffsetClause === '') {
? $query return $query;
: preg_replace('/^\s*(SELECT\s+(DISTINCT\s+)?)/i', '\1' . $limitOffsetClause . ' ', $query); }
if (! preg_match('/^\s*(SELECT\s+(DISTINCT\s+)?)(.*)/i', $query, $matches)) {
return $query;
}
return $matches[1] . $limitOffsetClause . ' ' . $matches[3];
} }
private function getTopClauseSQL(?int $limit, ?int $offset) : string private function getTopClauseSQL(?int $limit, ?int $offset) : string
......
...@@ -26,7 +26,6 @@ use function is_bool; ...@@ -26,7 +26,6 @@ use function is_bool;
use function is_numeric; use function is_numeric;
use function is_string; use function is_string;
use function preg_match; use function preg_match;
use function preg_replace;
use function sprintf; use function sprintf;
use function str_replace; use function str_replace;
use function stripos; use function stripos;
...@@ -343,7 +342,7 @@ SQL ...@@ -343,7 +342,7 @@ SQL
* *
* @param string $tableName The quoted table name to which the column belongs. * @param string $tableName The quoted table name to which the column belongs.
* @param string $columnName The quoted column name to create the comment for. * @param string $columnName The quoted column name to create the comment for.
* @param string $comment The column's comment. * @param string|null $comment The column's comment.
* *
* @return string * @return string
*/ */
...@@ -702,7 +701,7 @@ SQL ...@@ -702,7 +701,7 @@ SQL
* *
* @param string $tableName The quoted table name to which the column belongs. * @param string $tableName The quoted table name to which the column belongs.
* @param string $columnName The quoted column name to alter the comment for. * @param string $columnName The quoted column name to alter the comment for.
* @param string $comment The column's comment. * @param string|null $comment The column's comment.
* *
* @return string * @return string
*/ */
...@@ -808,10 +807,10 @@ SQL ...@@ -808,10 +807,10 @@ SQL
$level2Name = null $level2Name = null
) { ) {
return 'EXEC sp_addextendedproperty ' . return 'EXEC sp_addextendedproperty ' .
'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
} }
/** /**
...@@ -840,9 +839,9 @@ SQL ...@@ -840,9 +839,9 @@ SQL
) { ) {
return 'EXEC sp_dropextendedproperty ' . return 'EXEC sp_dropextendedproperty ' .
'N' . $this->quoteStringLiteral($name) . ', ' . 'N' . $this->quoteStringLiteral($name) . ', ' .
'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
} }
/** /**
...@@ -872,10 +871,10 @@ SQL ...@@ -872,10 +871,10 @@ SQL
$level2Name = null $level2Name = null
) { ) {
return 'EXEC sp_updateextendedproperty ' . return 'EXEC sp_updateextendedproperty ' .
'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
} }
/** /**
...@@ -1279,9 +1278,11 @@ SQL ...@@ -1279,9 +1278,11 @@ SQL
// Even if the TOP n is very large, the use of a CTE will // Even if the TOP n is very large, the use of a CTE will
// allow the SQL Server query planner to optimize it so it doesn't // allow the SQL Server query planner to optimize it so it doesn't
// actually scan the entire range covered by the TOP clause. // actually scan the entire range covered by the TOP clause.
$selectPattern = '/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im'; if (! preg_match('/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im', $query, $matches)) {
$replacePattern = sprintf('$1%s $2', $top); return $query;
$query = preg_replace($selectPattern, $replacePattern, $query); }
$query = $matches[1] . $top . ' ' . $matches[2];
if (stristr($query, 'ORDER BY')) { if (stristr($query, 'ORDER BY')) {
// Inner order by is not valid in SQL Server for our purposes // Inner order by is not valid in SQL Server for our purposes
......
...@@ -121,9 +121,9 @@ class Connection extends \Doctrine\DBAL\Connection ...@@ -121,9 +121,9 @@ class Connection extends \Doctrine\DBAL\Connection
*/ */
public function query() public function query()
{ {
$this->connect(); $connection = $this->getWrappedConnection();
$stmt = $this->_conn->query(...func_get_args()); $stmt = $connection->query(...func_get_args());
$stmt = new Statement($stmt, $this); $stmt = new Statement($stmt, $this);
$stmt->setFetchMode($this->defaultFetchMode); $stmt->setFetchMode($this->defaultFetchMode);
......
...@@ -84,7 +84,7 @@ abstract class AbstractAsset ...@@ -84,7 +84,7 @@ abstract class AbstractAsset
* The shortest name is stripped of the default namespace. All other * The shortest name is stripped of the default namespace. All other
* namespaced elements are returned as full-qualified names. * namespaced elements are returned as full-qualified names.
* *
* @param string $defaultNamespaceName * @param string|null $defaultNamespaceName
* *
* @return string * @return string
*/ */
......
...@@ -188,7 +188,7 @@ abstract class AbstractSchemaManager ...@@ -188,7 +188,7 @@ abstract class AbstractSchemaManager
/** /**
* Returns true if all the given tables exist. * Returns true if all the given tables exist.
* *
* @param string[] $tableNames * @param string|string[] $tableNames
* *
* @return bool * @return bool
*/ */
...@@ -1098,28 +1098,32 @@ abstract class AbstractSchemaManager ...@@ -1098,28 +1098,32 @@ abstract class AbstractSchemaManager
* Given a table comment this method tries to extract a typehint for Doctrine Type, or returns * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
* the type given as default. * the type given as default.
* *
* @param string $comment * @param string|null $comment
* @param string $currentType * @param string $currentType
* *
* @return string * @return string
*/ */
public function extractDoctrineTypeFromComment($comment, $currentType) public function extractDoctrineTypeFromComment($comment, $currentType)
{ {
if (preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) {
$currentType = $match[1]; return $match[1];
} }
return $currentType; return $currentType;
} }
/** /**
* @param string $comment * @param string|null $comment
* @param string $type * @param string|null $type
* *
* @return string * @return string|null
*/ */
public function removeDoctrineTypeFromComment($comment, $type) public function removeDoctrineTypeFromComment($comment, $type)
{ {
if ($comment === null) {
return null;
}
return str_replace('(DC2Type:' . $type . ')', '', $comment); return str_replace('(DC2Type:' . $type . ')', '', $comment);
} }
} }
...@@ -356,7 +356,7 @@ class Column extends AbstractAsset ...@@ -356,7 +356,7 @@ class Column extends AbstractAsset
} }
/** /**
* @param string $comment * @param string|null $comment
* *
* @return Column * @return Column
*/ */
......
...@@ -253,6 +253,7 @@ class Comparator ...@@ -253,6 +253,7 @@ class Comparator
// See if index has changed in table 2. // See if index has changed in table 2.
$table2Index = $index->isPrimary() ? $table2->getPrimaryKey() : $table2->getIndex($indexName); $table2Index = $index->isPrimary() ? $table2->getPrimaryKey() : $table2->getIndex($indexName);
assert($table2Index instanceof Index);
if (! $this->diffIndex($index, $table2Index)) { if (! $this->diffIndex($index, $table2Index)) {
continue; continue;
......
...@@ -41,7 +41,6 @@ class DB2SchemaManager extends AbstractSchemaManager ...@@ -41,7 +41,6 @@ class DB2SchemaManager extends AbstractSchemaManager
$length = null; $length = null;
$fixed = null; $fixed = null;
$unsigned = false;
$scale = false; $scale = false;
$precision = false; $precision = false;
...@@ -80,7 +79,7 @@ class DB2SchemaManager extends AbstractSchemaManager ...@@ -80,7 +79,7 @@ class DB2SchemaManager extends AbstractSchemaManager
$options = [ $options = [
'length' => $length, 'length' => $length,
'unsigned' => (bool) $unsigned, 'unsigned' => false,
'fixed' => (bool) $fixed, 'fixed' => (bool) $fixed,
'default' => $default, 'default' => $default,
'autoincrement' => (bool) $tableColumn['autoincrement'], 'autoincrement' => (bool) $tableColumn['autoincrement'],
......
...@@ -64,7 +64,9 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -64,7 +64,9 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
*/ */
public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = []) public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = [])
{ {
if ($name !== null) {
$this->_setName($name); $this->_setName($name);
}
$this->_localColumnNames = $this->createIdentifierMap($localColumnNames); $this->_localColumnNames = $this->createIdentifierMap($localColumnNames);
......
...@@ -10,11 +10,9 @@ use function array_change_key_case; ...@@ -10,11 +10,9 @@ use function array_change_key_case;
use function array_shift; use function array_shift;
use function array_values; use function array_values;
use function assert; use function assert;
use function end;
use function explode; use function explode;
use function is_string; use function is_string;
use function preg_match; use function preg_match;
use function preg_replace;
use function str_replace; use function str_replace;
use function stripslashes; use function stripslashes;
use function strpos; use function strpos;
...@@ -78,14 +76,6 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -78,14 +76,6 @@ class MySqlSchemaManager extends AbstractSchemaManager
return parent::_getPortableTableIndexesList($tableIndexes, $tableName); return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
} }
/**
* {@inheritdoc}
*/
protected function _getPortableSequenceDefinition($sequence)
{
return end($sequence);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -227,15 +217,11 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -227,15 +217,11 @@ class MySqlSchemaManager extends AbstractSchemaManager
if ($columnDefault === 'NULL' || $columnDefault === null) { if ($columnDefault === 'NULL' || $columnDefault === null) {
return null; return null;
} }
if ($columnDefault[0] === "'") {
return stripslashes( if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches)) {
str_replace( return stripslashes(str_replace("''", "'", $matches[1]));
"''",
"'",
preg_replace('/^\'(.*)\'$/', '$1', $columnDefault)
)
);
} }
switch ($columnDefault) { switch ($columnDefault) {
case 'current_timestamp()': case 'current_timestamp()':
return $platform->getCurrentTimestampSQL(); return $platform->getCurrentTimestampSQL();
......
...@@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; ...@@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use Throwable;
use const CASE_LOWER; use const CASE_LOWER;
use function array_change_key_case; use function array_change_key_case;
use function array_values; use function array_values;
...@@ -31,6 +32,7 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -31,6 +32,7 @@ class OracleSchemaManager extends AbstractSchemaManager
parent::dropDatabase($database); parent::dropDatabase($database);
} catch (DBALException $exception) { } catch (DBALException $exception) {
$exception = $exception->getPrevious(); $exception = $exception->getPrevious();
assert($exception instanceof Throwable);
if (! $exception instanceof DriverException) { if (! $exception instanceof DriverException) {
throw $exception; throw $exception;
......
...@@ -134,8 +134,8 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -134,8 +134,8 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
{ {
$onUpdate = null; $onUpdate = null;
$onDelete = null; $onDelete = null;
$localColumns = null; $localColumns = [];
$foreignColumns = null; $foreignColumns = [];
$foreignTable = null; $foreignTable = null;
if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) {
......
...@@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException; ...@@ -6,6 +6,7 @@ use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use PDOException; use PDOException;
use Throwable;
use function assert; use function assert;
use function count; use function count;
use function in_array; use function in_array;
...@@ -31,6 +32,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -31,6 +32,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
parent::dropDatabase($database); parent::dropDatabase($database);
} catch (DBALException $exception) { } catch (DBALException $exception) {
$exception = $exception->getPrevious(); $exception = $exception->getPrevious();
assert($exception instanceof Throwable);
if (! $exception instanceof DriverException) { if (! $exception instanceof DriverException) {
throw $exception; throw $exception;
......
...@@ -105,7 +105,9 @@ class Schema extends AbstractAsset ...@@ -105,7 +105,9 @@ class Schema extends AbstractAsset
throw SchemaException::tableAlreadyExists($tableName); throw SchemaException::tableAlreadyExists($tableName);
} }
if (! $table->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { if ($namespaceName !== null
&& ! $table->isInDefaultNamespace($this->getName())
&& ! $this->hasNamespace($namespaceName)) {
$this->createNamespace($namespaceName); $this->createNamespace($namespaceName);
} }
...@@ -127,7 +129,9 @@ class Schema extends AbstractAsset ...@@ -127,7 +129,9 @@ class Schema extends AbstractAsset
throw SchemaException::sequenceAlreadyExists($seqName); throw SchemaException::sequenceAlreadyExists($seqName);
} }
if (! $sequence->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { if ($namespaceName !== null
&& ! $sequence->isInDefaultNamespace($this->getName())
&& ! $this->hasNamespace($namespaceName)) {
$this->createNamespace($namespaceName); $this->createNamespace($namespaceName);
} }
......
...@@ -10,7 +10,7 @@ use function array_merge; ...@@ -10,7 +10,7 @@ use function array_merge;
*/ */
class SchemaDiff class SchemaDiff
{ {
/** @var Schema */ /** @var Schema|null */
public $fromSchema; public $fromSchema;
/** /**
......
...@@ -104,11 +104,13 @@ class Sequence extends AbstractAsset ...@@ -104,11 +104,13 @@ class Sequence extends AbstractAsset
*/ */
public function isAutoIncrementsFor(Table $table) public function isAutoIncrementsFor(Table $table)
{ {
if (! $table->hasPrimaryKey()) { $primaryKey = $table->getPrimaryKey();
if ($primaryKey === null) {
return false; return false;
} }
$pkColumns = $table->getPrimaryKey()->getColumns(); $pkColumns = $primaryKey->getColumns();
if (count($pkColumns) !== 1) { if (count($pkColumns) !== 1) {
return false; return false;
......
...@@ -87,11 +87,14 @@ class SingleDatabaseSynchronizer extends AbstractSchemaSynchronizer ...@@ -87,11 +87,14 @@ class SingleDatabaseSynchronizer extends AbstractSchemaSynchronizer
} }
foreach ($dropSchema->getTables() as $table) { foreach ($dropSchema->getTables() as $table) {
if (! $table->hasPrimaryKey()) { $primaryKey = $table->getPrimaryKey();
if ($primaryKey === null) {
continue; continue;
} }
$columns = $table->getPrimaryKey()->getColumns(); $columns = $primaryKey->getColumns();
if (count($columns) > 1) { if (count($columns) > 1) {
continue; continue;
} }
......
...@@ -216,7 +216,7 @@ class Table extends AbstractAsset ...@@ -216,7 +216,7 @@ class Table extends AbstractAsset
if ($oldIndex->isPrimary()) { if ($oldIndex->isPrimary()) {
$this->dropPrimaryKey(); $this->dropPrimaryKey();
return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName); return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName ?? false);
} }
unset($this->_indexes[$oldIndexName]); unset($this->_indexes[$oldIndexName]);
...@@ -589,9 +589,11 @@ class Table extends AbstractAsset ...@@ -589,9 +589,11 @@ class Table extends AbstractAsset
*/ */
public function getColumns() public function getColumns()
{ {
$primaryKey = $this->getPrimaryKey();
$primaryKeyColumns = []; $primaryKeyColumns = [];
if ($this->hasPrimaryKey()) {
$primaryKeyColumns = $this->filterColumns($this->getPrimaryKey()->getColumns()); if ($primaryKey !== null) {
$primaryKeyColumns = $this->filterColumns($primaryKey->getColumns());
} }
return array_merge($primaryKeyColumns, $this->getForeignKeyColumns(), $this->_columns); return array_merge($primaryKeyColumns, $this->getForeignKeyColumns(), $this->_columns);
...@@ -681,10 +683,13 @@ class Table extends AbstractAsset ...@@ -681,10 +683,13 @@ class Table extends AbstractAsset
*/ */
public function getPrimaryKeyColumns() public function getPrimaryKeyColumns()
{ {
if (! $this->hasPrimaryKey()) { $primaryKey = $this->getPrimaryKey();
if ($primaryKey === null) {
throw new DBALException('Table ' . $this->getName() . ' has no primary key.'); throw new DBALException('Table ' . $this->getName() . ' has no primary key.');
} }
return $this->getPrimaryKey()->getColumns();
return $primaryKey->getColumns();
} }
/** /**
...@@ -820,12 +825,16 @@ class Table extends AbstractAsset ...@@ -820,12 +825,16 @@ class Table extends AbstractAsset
* *
* Trims quotes and lowercases the given identifier. * Trims quotes and lowercases the given identifier.
* *
* @param string $identifier The identifier to normalize. * @param string|null $identifier The identifier to normalize.
* *
* @return string The normalized identifier. * @return string The normalized identifier.
*/ */
private function normalizeIdentifier($identifier) private function normalizeIdentifier($identifier)
{ {
if ($identifier === null) {
return '';
}
return $this->trimQuotes(strtolower($identifier)); return $this->trimQuotes(strtolower($identifier));
} }
} }
...@@ -47,7 +47,7 @@ class CreateSchemaSqlCollector extends AbstractVisitor ...@@ -47,7 +47,7 @@ class CreateSchemaSqlCollector extends AbstractVisitor
*/ */
public function acceptTable(Table $table) public function acceptTable(Table $table)
{ {
$this->createTableQueries = array_merge($this->createTableQueries, (array) $this->platform->getCreateTableSQL($table)); $this->createTableQueries = array_merge($this->createTableQueries, $this->platform->getCreateTableSQL($table));
} }
/** /**
......
...@@ -81,7 +81,10 @@ class Graphviz extends AbstractVisitor ...@@ -81,7 +81,10 @@ class Graphviz extends AbstractVisitor
$label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>'; $label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>';
$label .= '</TD><TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()) . '</FONT></TD>'; $label .= '</TD><TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()) . '</FONT></TD>';
$label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">'; $label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">';
if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) {
$primaryKey = $table->getPrimaryKey();
if ($primaryKey !== null && in_array($column->getName(), $primaryKey->getColumns())) {
$label .= "\xe2\x9c\xb7"; $label .= "\xe2\x9c\xb7";
} }
$label .= '</TD></TR>'; $label .= '</TD></TR>';
......
...@@ -53,7 +53,7 @@ class PoolingShardConnection extends Connection ...@@ -53,7 +53,7 @@ class PoolingShardConnection extends Connection
/** @var DriverConnection[] */ /** @var DriverConnection[] */
private $activeConnections = []; private $activeConnections = [];
/** @var int|null */ /** @var string|int|null */
private $activeShardId; private $activeShardId;
/** @var mixed[] */ /** @var mixed[] */
...@@ -106,7 +106,7 @@ class PoolingShardConnection extends Connection ...@@ -106,7 +106,7 @@ class PoolingShardConnection extends Connection
/** /**
* Get active shard id. * Get active shard id.
* *
* @return int * @return string|int|null
*/ */
public function getActiveShardId() public function getActiveShardId()
{ {
...@@ -164,7 +164,7 @@ class PoolingShardConnection extends Connection ...@@ -164,7 +164,7 @@ class PoolingShardConnection extends Connection
/** /**
* Connects to a given shard. * Connects to a given shard.
* *
* @param mixed $shardId * @param string|int|null $shardId
* *
* @return bool * @return bool
* *
...@@ -184,15 +184,15 @@ class PoolingShardConnection extends Connection ...@@ -184,15 +184,15 @@ class PoolingShardConnection extends Connection
throw new ShardingException('Cannot switch shard when transaction is active.'); throw new ShardingException('Cannot switch shard when transaction is active.');
} }
$this->activeShardId = (int) $shardId; $activeShardId = $this->activeShardId = (int) $shardId;
if (isset($this->activeConnections[$this->activeShardId])) { if (isset($this->activeConnections[$activeShardId])) {
$this->_conn = $this->activeConnections[$this->activeShardId]; $this->_conn = $this->activeConnections[$activeShardId];
return false; return false;
} }
$this->_conn = $this->activeConnections[$this->activeShardId] = $this->connectTo($this->activeShardId); $this->_conn = $this->activeConnections[$activeShardId] = $this->connectTo($activeShardId);
if ($this->_eventManager->hasListeners(Events::postConnect)) { if ($this->_eventManager->hasListeners(Events::postConnect)) {
$eventArgs = new ConnectionEventArgs($this); $eventArgs = new ConnectionEventArgs($this);
...@@ -224,7 +224,7 @@ class PoolingShardConnection extends Connection ...@@ -224,7 +224,7 @@ class PoolingShardConnection extends Connection
} }
/** /**
* @param string|null $shardId * @param string|int|null $shardId
* *
* @return bool * @return bool
*/ */
......
parameters: parameters:
level: 6 level: 7
paths: paths:
- %currentWorkingDirectory%/lib - %currentWorkingDirectory%/lib
autoload_files: autoload_files:
...@@ -12,7 +12,12 @@ parameters: ...@@ -12,7 +12,12 @@ parameters:
# removing it would be BC break # removing it would be BC break
- '~^Constructor of class Doctrine\\DBAL\\Schema\\Table has an unused parameter \$idGeneratorType\.\z~' - '~^Constructor of class Doctrine\\DBAL\\Schema\\Table has an unused parameter \$idGeneratorType\.\z~'
# declaring $tableName in AbstractSchemaManager::_getPortableTableIndexesList() non-optional will be a BC break
- '~^Parameter #2 \$table of class Doctrine\\DBAL\\Event\\SchemaIndexDefinitionEventArgs constructor expects string, string\|null given\.\z~'
# changing these would be a BC break, to be done in next major # changing these would be a BC break, to be done in next major
- "~^Casting to bool something that's already bool.~"
- "~^Casting to int something that's already int.~"
- '~^Method Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Connection::exec\(\) should return int but returns bool\.\z~' - '~^Method Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Connection::exec\(\) should return int but returns bool\.\z~'
- '~^Method Doctrine\\DBAL\\Query\\QueryBuilder::execute\(\) should return Doctrine\\DBAL\\Driver\\Statement\|int but returns Doctrine\\DBAL\\Driver\\ResultStatement\.\z~' - '~^Method Doctrine\\DBAL\\Query\\QueryBuilder::execute\(\) should return Doctrine\\DBAL\\Driver\\Statement\|int but returns Doctrine\\DBAL\\Driver\\ResultStatement\.\z~'
- '~^Property Doctrine\\DBAL\\Schema\\Table::\$_primaryKeyName \(string\) does not accept (default value of type )?false\.\z~' - '~^Property Doctrine\\DBAL\\Schema\\Table::\$_primaryKeyName \(string\) does not accept (default value of type )?false\.\z~'
...@@ -33,6 +38,9 @@ parameters: ...@@ -33,6 +38,9 @@ parameters:
- '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::unknownAlias\(\) expects array<string>, array<int, int|string> given\.\z~' - '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::unknownAlias\(\) expects array<string>, array<int, int|string> given\.\z~'
- '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::nonUniqueAlias\(\) expects array<string>, array<int, int|string> given\.\z~' - '~^Parameter #2 \$registeredAliases of static method Doctrine\\DBAL\\Query\\QueryException::nonUniqueAlias\(\) expects array<string>, array<int, int|string> given\.\z~'
# PHPStan is too strict about preg_replace(): https://phpstan.org/r/993dc99f-0d43-4b51-868b-d01f982c1463
- '~^Method Doctrine\\DBAL\\Platforms\\AbstractPlatform::escapeStringForLike\(\) should return string but returns string|null\.\z~'
# legacy variadic-like signature # legacy variadic-like signature
- '~^Method Doctrine\\DBAL\\Driver\\Connection::query\(\) invoked with \d+ parameters?, 0 required\.\z~' - '~^Method Doctrine\\DBAL\\Driver\\Connection::query\(\) invoked with \d+ parameters?, 0 required\.\z~'
......
...@@ -28,7 +28,6 @@ use Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock; ...@@ -28,7 +28,6 @@ use Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock;
use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock; use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock;
use Exception; use Exception;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use ReflectionObject;
use stdClass; use stdClass;
use function call_user_func_array; use function call_user_func_array;
...@@ -605,29 +604,6 @@ class ConnectionTest extends DbalTestCase ...@@ -605,29 +604,6 @@ class ConnectionTest extends DbalTestCase
self::assertSame($result, $conn->fetchColumn($statement, $params, $column, $types)); self::assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
} }
public function testConnectionIsClosedButNotUnset()
{
// mock Connection, and make connect() purposefully do nothing
$connection = $this->getMockBuilder(Connection::class)
->disableOriginalConstructor()
->setMethods(['connect'])
->getMock();
// artificially set the wrapped connection to non-null
$reflection = new ReflectionObject($connection);
$connProperty = $reflection->getProperty('_conn');
$connProperty->setAccessible(true);
$connProperty->setValue($connection, new stdClass());
// close the connection (should nullify the wrapped connection)
$connection->close();
// the wrapped connection should be null
// (and since connect() does nothing, this will not reconnect)
// this will also fail if this _conn property was unset instead of set to null
self::assertNull($connection->getWrappedConnection());
}
public function testFetchAll() public function testFetchAll()
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
......
...@@ -4,7 +4,6 @@ namespace Doctrine\Tests\DBAL\Functional; ...@@ -4,7 +4,6 @@ namespace Doctrine\Tests\DBAL\Functional;
use Doctrine\DBAL\ColumnCase; use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Portability\Connection as ConnectionPortability; use Doctrine\DBAL\Portability\Connection as ConnectionPortability;
...@@ -136,29 +135,6 @@ class PortabilityTest extends DbalFunctionalTestCase ...@@ -136,29 +135,6 @@ class PortabilityTest extends DbalFunctionalTestCase
self::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.'); self::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.');
} }
/**
* @requires extension pdo
*/
public function testPortabilityPdoSqlServer()
{
$portability = ConnectionPortability::PORTABILITY_SQLSRV;
$params = ['portability' => $portability];
$driverMock = $this->getMockBuilder(Driver::class)
->setMethods(['connect'])
->getMock();
$driverMock->expects($this->once())
->method('connect')
->will($this->returnValue(null));
$connection = new ConnectionPortability($params, $driverMock);
$connection->connect($params);
self::assertEquals($portability, $connection->getPortability());
}
/** /**
* @param string $field * @param string $field
* @param mixed[] $expected * @param mixed[] $expected
......
...@@ -39,11 +39,13 @@ class CreateSchemaSqlCollectorTest extends TestCase ...@@ -39,11 +39,13 @@ class CreateSchemaSqlCollectorTest extends TestCase
->getMockForAbstractClass(); ->getMockForAbstractClass();
$this->visitor = new CreateSchemaSqlCollector($this->platformMock); $this->visitor = new CreateSchemaSqlCollector($this->platformMock);
foreach (['getCreateSchemaSQL', 'getCreateTableSQL', 'getCreateForeignKeySQL', 'getCreateSequenceSQL'] as $method) { foreach (['getCreateSchemaSQL', 'getCreateForeignKeySQL', 'getCreateSequenceSQL'] as $method) {
$this->platformMock->expects($this->any()) $this->platformMock->method($method)
->method($method) ->willReturn('foo');
->will($this->returnValue('foo'));
} }
$this->platformMock->method('getCreateTableSQL')
->willReturn(['foo']);
} }
public function testAcceptsNamespace() public function testAcceptsNamespace()
......
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