diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 4d79fb739b6..8016b7da6a1 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -459,11 +459,11 @@ private function getDatabasePlatformVersion() */ private function getServerVersion() { + $connection = $this->getWrappedConnection(); + // Automatic platform version detection. - if ($this->_conn instanceof ServerInfoAwareConnection && - ! $this->_conn->requiresQueryForServerVersion() - ) { - return $this->_conn->getServerVersion(); + if ($connection instanceof ServerInfoAwareConnection && ! $connection->requiresQueryForServerVersion()) { + return $connection->getServerVersion(); } // Unable to detect platform version. @@ -810,20 +810,15 @@ public function quoteIdentifier($str) } /** - * Quotes a given input parameter. - * - * @param mixed $input The parameter to be quoted. - * @param int|null $type The type of the parameter. - * - * @return string The quoted parameter. + * {@inheritDoc} */ public function quote($input, $type = null) { - $this->connect(); + $connection = $this->getWrappedConnection(); [$value, $bindingType] = $this->getBindingInfo($input, $type); - return $this->_conn->quote($value, $bindingType); + return $connection->quote($value, $bindingType); } /** @@ -883,7 +878,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach return $this->executeCacheQuery($query, $params, $types, $qcp); } - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -894,7 +889,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach if ($params) { [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); - $stmt = $this->_conn->prepare($query); + $stmt = $connection->prepare($query); if ($types) { $this->_bindTypedValues($stmt, $params, $types); $stmt->execute(); @@ -902,7 +897,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach $stmt->execute($params); } } else { - $stmt = $this->_conn->query($query); + $stmt = $connection->query($query); } } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); @@ -931,8 +926,9 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach */ public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) { - $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl(); - if (! $resultCache) { + $resultCache = $qcp->getResultCacheDriver() ?? $this->_config->getResultCacheImpl(); + + if ($resultCache === null) { throw CacheException::noResultDriverConfigured(); } @@ -994,7 +990,7 @@ public function project($query, array $params, Closure $function) */ public function query() { - $this->connect(); + $connection = $this->getWrappedConnection(); $args = func_get_args(); @@ -1004,7 +1000,7 @@ public function query() } try { - $statement = $this->_conn->query(...$args); + $statement = $connection->query(...$args); } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]); } @@ -1034,7 +1030,7 @@ public function query() */ public function executeUpdate($query, array $params = [], array $types = []) { - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -1045,7 +1041,8 @@ public function executeUpdate($query, array $params = [], array $types = []) if ($params) { [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); - $stmt = $this->_conn->prepare($query); + $stmt = $connection->prepare($query); + if ($types) { $this->_bindTypedValues($stmt, $params, $types); $stmt->execute(); @@ -1054,7 +1051,7 @@ public function executeUpdate($query, array $params = [], array $types = []) } $result = $stmt->rowCount(); } else { - $result = $this->_conn->exec($query); + $result = $connection->exec($query); } } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); @@ -1078,7 +1075,7 @@ public function executeUpdate($query, array $params = [], array $types = []) */ public function exec($statement) { - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); if ($logger) { @@ -1086,7 +1083,7 @@ public function exec($statement) } try { - $result = $this->_conn->exec($statement); + $result = $connection->exec($statement); } catch (Throwable $ex) { throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement); } @@ -1115,9 +1112,7 @@ public function getTransactionNestingLevel() */ public function errorCode() { - $this->connect(); - - return $this->_conn->errorCode(); + return $this->getWrappedConnection()->errorCode(); } /** @@ -1125,9 +1120,7 @@ public function errorCode() */ public function errorInfo() { - $this->connect(); - - return $this->_conn->errorInfo(); + return $this->getWrappedConnection()->errorInfo(); } /** @@ -1144,9 +1137,7 @@ public function errorInfo() */ public function lastInsertId($seqName = null) { - $this->connect(); - - return $this->_conn->lastInsertId($seqName); + return $this->getWrappedConnection()->lastInsertId($seqName); } /** @@ -1228,7 +1219,7 @@ protected function _getNestedTransactionSavePointName() */ public function beginTransaction() { - $this->connect(); + $connection = $this->getWrappedConnection(); ++$this->transactionNestingLevel; @@ -1238,7 +1229,9 @@ public function beginTransaction() if ($logger) { $logger->startQuery('"START TRANSACTION"'); } - $this->_conn->beginTransaction(); + + $connection->beginTransaction(); + if ($logger) { $logger->stopQuery(); } @@ -1270,7 +1263,7 @@ public function commit() throw ConnectionException::commitFailedRollbackOnly(); } - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); @@ -1278,7 +1271,9 @@ public function commit() if ($logger) { $logger->startQuery('"COMMIT"'); } - $this->_conn->commit(); + + $connection->commit(); + if ($logger) { $logger->stopQuery(); } @@ -1332,7 +1327,7 @@ public function rollBack() throw ConnectionException::noActiveTransaction(); } - $this->connect(); + $connection = $this->getWrappedConnection(); $logger = $this->_config->getSQLLogger(); @@ -1341,7 +1336,7 @@ public function rollBack() $logger->startQuery('"ROLLBACK"'); } $this->transactionNestingLevel = 0; - $this->_conn->rollBack(); + $connection->rollBack(); $this->isRollbackOnly = false; if ($logger) { $logger->stopQuery(); @@ -1380,7 +1375,7 @@ public function createSavepoint($savepoint) throw ConnectionException::savepointsNotSupported(); } - $this->_conn->exec($this->platform->createSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->createSavePoint($savepoint)); } /** @@ -1402,7 +1397,7 @@ public function releaseSavepoint($savepoint) return; } - $this->_conn->exec($this->platform->releaseSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->releaseSavePoint($savepoint)); } /** @@ -1420,17 +1415,18 @@ public function rollbackSavepoint($savepoint) throw ConnectionException::savepointsNotSupported(); } - $this->_conn->exec($this->platform->rollbackSavePoint($savepoint)); + $this->getWrappedConnection()->exec($this->platform->rollbackSavePoint($savepoint)); } /** * Gets the wrapped driver connection. * - * @return \Doctrine\DBAL\Driver\Connection + * @return DriverConnection */ public function getWrappedConnection() { $this->connect(); + assert($this->_conn instanceof DriverConnection); return $this->_conn; } @@ -1558,8 +1554,8 @@ private function _bindTypedValues($stmt, array $params, array $types) /** * 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 int|string $type The type to bind (PDO or DBAL). + * @param mixed $value The value to bind. + * @param int|string|null $type The type to bind (PDO or DBAL). * * @return mixed[] [0] => the (escaped) value, [1] => the binding type. */ @@ -1658,10 +1654,10 @@ public function createQueryBuilder() */ public function ping() { - $this->connect(); + $connection = $this->getWrappedConnection(); - if ($this->_conn instanceof PingableConnection) { - return $this->_conn->ping(); + if ($connection instanceof PingableConnection) { + return $connection->ping(); } try { diff --git a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php index 1365e4039fb..ff310d9196b 100644 --- a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php +++ b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php @@ -11,6 +11,7 @@ use Doctrine\DBAL\Events; use InvalidArgumentException; use function array_rand; +use function assert; use function count; use function func_get_args; @@ -344,6 +345,7 @@ public function rollbackSavepoint($savepoint) public function query() { $this->connect('master'); + assert($this->_conn instanceof DriverConnection); $args = func_get_args(); diff --git a/lib/Doctrine/DBAL/DBALException.php b/lib/Doctrine/DBAL/DBALException.php index 5b7465f99fe..02cad00cc43 100644 --- a/lib/Doctrine/DBAL/DBALException.php +++ b/lib/Doctrine/DBAL/DBALException.php @@ -17,8 +17,8 @@ use function is_resource; use function is_string; use function json_encode; +use function preg_replace; use function sprintf; -use function str_split; class DBALException extends Exception { @@ -186,7 +186,7 @@ private static function formatParameters(array $params) if (! is_string($json) || $json === 'null' && is_string($param)) { // 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; diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php index 712cbe419f3..43497fd6026 100644 --- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php +++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -34,7 +34,7 @@ public function connect(array $params, $username = null, $password = null, array $password = null; } - return new DB2Connection($params, $username, $password, $driverOptions); + return new DB2Connection($params, (string) $username, (string) $password, $driverOptions); } /** diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php index aaf4f2bd9fd..1166e8d4c2e 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -13,7 +13,7 @@ class Driver extends AbstractMySQLDriver public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { try { - return new MysqliConnection($params, $username, $password, $driverOptions); + return new MysqliConnection($params, (string) $username, (string) $password, $driverOptions); } catch (MysqliException $e) { throw DBALException::driverException($this, $e); } diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php index 85a88f33401..893b3be4688 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php @@ -45,8 +45,8 @@ class MysqliStatement implements IteratorAggregate, Statement /** @var string[]|false|null */ protected $_columnNames; - /** @var mixed[]|null */ - protected $_rowBindedValues; + /** @var mixed[] */ + protected $_rowBindedValues = []; /** @var mixed[] */ protected $_bindedValues; @@ -318,6 +318,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX } $values = $this->_fetch(); + if ($values === null) { return false; } diff --git a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php index 872582d80b7..48195f1517e 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -18,10 +18,10 @@ public function connect(array $params, $username = null, $password = null, array { try { return new OCI8Connection( - $username, - $password, + (string) $username, + (string) $password, $this->_constructDsn($params), - $params['charset'] ?? null, + $params['charset'] ?? '', $params['sessionMode'] ?? OCI_DEFAULT, $params['persistent'] ?? false ); diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php index 35333e8d2d7..c1857936f5a 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -10,8 +10,6 @@ use const OCI_DEFAULT; use const OCI_NO_AUTO_COMMIT; use function addcslashes; -use function define; -use function defined; use function func_get_args; use function is_float; use function is_int; @@ -39,21 +37,23 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection /** * Creates a Connection to an Oracle Database using oci8 extension. * - * @param string $username - * @param string $password - * @param string $db - * @param string|null $charset - * @param int $sessionMode - * @param bool $persistent + * @param string $username + * @param string $password + * @param string $db + * @param string $charset + * @param int $sessionMode + * @param bool $persistent * * @throws OCI8Exception */ - public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT, $persistent = false) - { - if (! defined('OCI_NO_AUTO_COMMIT')) { - define('OCI_NO_AUTO_COMMIT', 0); - } - + public function __construct( + $username, + $password, + $db, + $charset = '', + $sessionMode = OCI_DEFAULT, + $persistent = false + ) { $dbh = $persistent ? @oci_pconnect($username, $password, $db, $charset, $sessionMode) : @oci_connect($username, $password, $db, $charset, $sessionMode); diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php index 32feaef93e3..f5a141c1732 100644 --- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php +++ b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php @@ -213,10 +213,9 @@ private static function findPlaceholderOrOpeningQuote( /** * Finds closing quote * - * @param string $statement The SQL statement to parse - * @param string $tokenOffset The offset to start searching from - * @param string|null $currentLiteralDelimiter The delimiter of the current string literal - * or NULL if not currently in a literal + * @param string $statement The SQL statement to parse + * @param string $tokenOffset The offset to start searching from + * @param string $currentLiteralDelimiter The delimiter of the current string literal * * @return bool Whether the token was found */ @@ -274,7 +273,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING) */ public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) { - $column = $this->_paramMap[$column] ?? $column; + $column = $this->_paramMap[$column]; if ($type === ParameterType::LARGE_OBJECT) { $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB); diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php index 11f5febc87b..336542ea50a 100644 --- a/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -24,7 +24,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection public function __construct($dsn, $user = null, $password = null, ?array $options = null) { 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_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (\PDOException $exception) { @@ -95,6 +95,10 @@ public function quote($input, $type = ParameterType::STRING) public function lastInsertId($name = null) { try { + if ($name === null) { + return parent::lastInsertId(); + } + return parent::lastInsertId($name); } catch (\PDOException $exception) { throw new PDOException($exception); diff --git a/lib/Doctrine/DBAL/Driver/PDOStatement.php b/lib/Doctrine/DBAL/Driver/PDOStatement.php index f734659c2b7..5be4f2c046d 100644 --- a/lib/Doctrine/DBAL/Driver/PDOStatement.php +++ b/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -6,7 +6,9 @@ use Doctrine\DBAL\ParameterType; use PDO; use const E_USER_DEPRECATED; +use function array_slice; use function assert; +use function func_get_args; use function is_array; use function sprintf; use function trigger_error; @@ -90,7 +92,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l $type = $this->convertParamType($type); try { - return parent::bindParam($column, $variable, $type, $length, $driverOptions); + return parent::bindParam($column, $variable, $type, ...array_slice(func_get_args(), 3)); } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -127,22 +129,14 @@ public function execute($params = null) */ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) { - $fetchMode = $this->convertFetchMode($fetchMode); - - try { - if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { - return parent::fetch(); - } + $args = func_get_args(); - if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { - return parent::fetch($fetchMode); - } - - if ($cursorOffset === 0) { - return parent::fetch($fetchMode, $cursorOrientation); - } + if (isset($args[0])) { + $args[0] = $this->convertFetchMode($args[0]); + } - return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset); + try { + return parent::fetch(...$args); } catch (\PDOException $exception) { throw new PDOException($exception); } @@ -153,7 +147,11 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX */ 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) { $args = []; @@ -210,14 +208,10 @@ private function convertParamType(int $type) : int /** * 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])) { // TODO: next major: throw an exception @trigger_error(sprintf( diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php index dbda962006a..e36bc9051cf 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php @@ -190,6 +190,6 @@ public function errorCode() */ public function errorInfo() { - return sqlsrv_errors(SQLSRV_ERR_ERRORS); + return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS); } } diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php index 796f5d129d4..1c1e8c472d7 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php @@ -16,12 +16,11 @@ class SQLSrvException extends AbstractDriverException */ public static function fromSqlSrvErrors() { - $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); $message = ''; $sqlState = 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"; if ($sqlState === null) { @@ -34,6 +33,7 @@ public static function fromSqlSrvErrors() $errorCode = $error['code']; } + if (! $message) { $message = 'SQL Server error occurred but no error message was retrieved from driver.'; } diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php index 49ca2567845..453bc8b3f3f 100644 --- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php +++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php @@ -180,7 +180,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l public function closeCursor() { // not having the result means there's nothing to close - if (! $this->result) { + if ($this->stmt === null || ! $this->result) { return true; } @@ -226,7 +226,7 @@ public function errorCode() */ public function errorInfo() { - return sqlsrv_errors(SQLSRV_ERR_ERRORS); + return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS); } /** @@ -337,7 +337,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX { // do not try fetching from the statement if it's not expected to contain result // in order to prevent exceptional situation - if (! $this->result) { + if ($this->stmt === null || ! $this->result) { return false; } diff --git a/lib/Doctrine/DBAL/Driver/Statement.php b/lib/Doctrine/DBAL/Driver/Statement.php index a3ea74a4df5..388983e46a6 100644 --- a/lib/Doctrine/DBAL/Driver/Statement.php +++ b/lib/Doctrine/DBAL/Driver/Statement.php @@ -48,7 +48,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING); * 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|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 * 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 diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 439f6f541d2..6a6c65a4092 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -27,12 +27,14 @@ use Doctrine\DBAL\Types; use Doctrine\DBAL\Types\Type; use InvalidArgumentException; +use UnexpectedValueException; use const E_USER_DEPRECATED; use function addcslashes; use function array_map; use function array_merge; use function array_unique; use function array_values; +use function assert; use function count; use function explode; use function func_get_arg; @@ -486,6 +488,8 @@ public function isCommentedDoctrineType(Type $doctrineType) $this->initializeCommentedDoctrineTypes(); } + assert(is_array($this->doctrineTypeComments)); + return in_array($doctrineType->getName(), $this->doctrineTypeComments); } @@ -502,6 +506,8 @@ public function markDoctrineTypeCommented($doctrineType) $this->initializeCommentedDoctrineTypes(); } + assert(is_array($this->doctrineTypeComments)); + $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType; } @@ -1419,7 +1425,13 @@ public function getDropTableSQL($table) $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); 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; } } diff --git a/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/lib/Doctrine/DBAL/Platforms/DB2Platform.php index bfe2790e30c..88c9b187f9d 100644 --- a/lib/Doctrine/DBAL/Platforms/DB2Platform.php +++ b/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Identifier; use Doctrine\DBAL\Schema\Index; -use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Types\Type; use function array_merge; @@ -571,7 +570,7 @@ public function getAlterTableSQL(TableDiff $diff) } } - $this->gatherAlterColumnSQL($diff->fromTable, $columnDiff, $sql, $queryParts); + $this->gatherAlterColumnSQL($diff->getName($this), $columnDiff, $sql, $queryParts); } foreach ($diff->renamedColumns as $oldColumnName => $column) { @@ -622,12 +621,12 @@ public function getAlterTableSQL(TableDiff $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 string[] $sql The sequence of table alteration statements 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); diff --git a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php b/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php index bb5b5cad36d..ae25e28ee30 100644 --- a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php @@ -47,9 +47,7 @@ public function getIdentifierQuoteCharacter() */ public function getConcatExpression() { - $args = func_get_args(); - - return 'CONCAT(' . implode(', ', (array) $args) . ')'; + return 'CONCAT(' . implode(', ', func_get_args()) . ')'; } /** diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php index 0f097de601b..510c153e65f 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -23,7 +23,7 @@ use function get_class; use function implode; use function is_string; -use function preg_replace; +use function preg_match; use function sprintf; use function strlen; use function strpos; @@ -1312,9 +1312,15 @@ protected function doModifyLimitQuery($query, $limit, $offset) { $limitOffsetClause = $this->getTopClauseSQL($limit, $offset); - return $limitOffsetClause === '' - ? $query - : preg_replace('/^\s*(SELECT\s+(DISTINCT\s+)?)/i', '\1' . $limitOffsetClause . ' ', $query); + if ($limitOffsetClause === '') { + return $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 diff --git a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php index 5ce17aae36b..12419ee6cd4 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -26,7 +26,6 @@ use function is_numeric; use function is_string; use function preg_match; -use function preg_replace; use function sprintf; use function str_replace; use function stripos; @@ -341,9 +340,9 @@ public function getCreatePrimaryKeySQL(Index $index, $table) * as column comments are stored in the same property there when * specifying a column's "Description" attribute. * - * @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 $comment The column's comment. + * @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|null $comment The column's comment. * * @return string */ @@ -700,9 +699,9 @@ private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff * as column comments are stored in the same property there when * specifying a column's "Description" attribute. * - * @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 $comment The column's comment. + * @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|null $comment The column's comment. * * @return string */ @@ -808,10 +807,10 @@ public function getAddExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_addextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -840,9 +839,9 @@ public function getDropExtendedPropertySQL( ) { return 'EXEC sp_dropextendedproperty ' . 'N' . $this->quoteStringLiteral($name) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -872,10 +871,10 @@ public function getUpdateExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_updateextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; } /** @@ -1279,9 +1278,11 @@ protected function doModifyLimitQuery($query, $limit, $offset = null) // 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 // actually scan the entire range covered by the TOP clause. - $selectPattern = '/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im'; - $replacePattern = sprintf('$1%s $2', $top); - $query = preg_replace($selectPattern, $replacePattern, $query); + if (! preg_match('/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im', $query, $matches)) { + return $query; + } + + $query = $matches[1] . $top . ' ' . $matches[2]; if (stristr($query, 'ORDER BY')) { // Inner order by is not valid in SQL Server for our purposes diff --git a/lib/Doctrine/DBAL/Portability/Connection.php b/lib/Doctrine/DBAL/Portability/Connection.php index 32186dcb0ec..7b4af8a8799 100644 --- a/lib/Doctrine/DBAL/Portability/Connection.php +++ b/lib/Doctrine/DBAL/Portability/Connection.php @@ -121,9 +121,9 @@ public function prepare($statement) */ 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->setFetchMode($this->defaultFetchMode); diff --git a/lib/Doctrine/DBAL/Schema/AbstractAsset.php b/lib/Doctrine/DBAL/Schema/AbstractAsset.php index eb7262e32a6..45af02f5cc9 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractAsset.php +++ b/lib/Doctrine/DBAL/Schema/AbstractAsset.php @@ -84,7 +84,7 @@ public function getNamespaceName() * The shortest name is stripped of the default namespace. All other * namespaced elements are returned as full-qualified names. * - * @param string $defaultNamespaceName + * @param string|null $defaultNamespaceName * * @return string */ diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index d1db70c4c25..eea98c09be4 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -188,7 +188,7 @@ public function listTableIndexes($table) /** * Returns true if all the given tables exist. * - * @param string[] $tableNames + * @param string|string[] $tableNames * * @return bool */ @@ -1098,28 +1098,32 @@ public function getSchemaSearchPaths() * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns * the type given as default. * - * @param string $comment - * @param string $currentType + * @param string|null $comment + * @param string $currentType * * @return string */ public function extractDoctrineTypeFromComment($comment, $currentType) { - if (preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { - $currentType = $match[1]; + if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { + return $match[1]; } return $currentType; } /** - * @param string $comment - * @param string $type + * @param string|null $comment + * @param string|null $type * - * @return string + * @return string|null */ public function removeDoctrineTypeFromComment($comment, $type) { + if ($comment === null) { + return null; + } + return str_replace('(DC2Type:' . $type . ')', '', $comment); } } diff --git a/lib/Doctrine/DBAL/Schema/Column.php b/lib/Doctrine/DBAL/Schema/Column.php index aef471e06fe..56c39c14994 100644 --- a/lib/Doctrine/DBAL/Schema/Column.php +++ b/lib/Doctrine/DBAL/Schema/Column.php @@ -356,7 +356,7 @@ public function setAutoincrement($flag) } /** - * @param string $comment + * @param string|null $comment * * @return Column */ diff --git a/lib/Doctrine/DBAL/Schema/Comparator.php b/lib/Doctrine/DBAL/Schema/Comparator.php index 585732d7dff..84d7808abef 100644 --- a/lib/Doctrine/DBAL/Schema/Comparator.php +++ b/lib/Doctrine/DBAL/Schema/Comparator.php @@ -253,6 +253,7 @@ public function diffTable(Table $table1, Table $table2) // See if index has changed in table 2. $table2Index = $index->isPrimary() ? $table2->getPrimaryKey() : $table2->getIndex($indexName); + assert($table2Index instanceof Index); if (! $this->diffIndex($index, $table2Index)) { continue; diff --git a/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php b/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php index f5e225512ab..0307a0d537d 100644 --- a/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php @@ -41,7 +41,6 @@ protected function _getPortableTableColumnDefinition($tableColumn) $length = null; $fixed = null; - $unsigned = false; $scale = false; $precision = false; @@ -80,7 +79,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) $options = [ 'length' => $length, - 'unsigned' => (bool) $unsigned, + 'unsigned' => false, 'fixed' => (bool) $fixed, 'default' => $default, 'autoincrement' => (bool) $tableColumn['autoincrement'], diff --git a/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php b/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php index 0a0977a4027..3c6585e4600 100644 --- a/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php +++ b/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php @@ -64,7 +64,9 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint */ public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = []) { - $this->_setName($name); + if ($name !== null) { + $this->_setName($name); + } $this->_localColumnNames = $this->createIdentifierMap($localColumnNames); diff --git a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index f442f54d116..4cc31a9258a 100644 --- a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -10,11 +10,9 @@ use function array_shift; use function array_values; use function assert; -use function end; use function explode; use function is_string; use function preg_match; -use function preg_replace; use function str_replace; use function stripslashes; use function strpos; @@ -78,14 +76,6 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null return parent::_getPortableTableIndexesList($tableIndexes, $tableName); } - /** - * {@inheritdoc} - */ - protected function _getPortableSequenceDefinition($sequence) - { - return end($sequence); - } - /** * {@inheritdoc} */ @@ -227,15 +217,11 @@ private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?str if ($columnDefault === 'NULL' || $columnDefault === null) { return null; } - if ($columnDefault[0] === "'") { - return stripslashes( - str_replace( - "''", - "'", - preg_replace('/^\'(.*)\'$/', '$1', $columnDefault) - ) - ); + + if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches)) { + return stripslashes(str_replace("''", "'", $matches[1])); } + switch ($columnDefault) { case 'current_timestamp()': return $platform->getCurrentTimestampSQL(); diff --git a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index 250ec2a2652..0a3e76b1c51 100644 --- a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Types\Type; +use Throwable; use const CASE_LOWER; use function array_change_key_case; use function array_values; @@ -31,6 +32,7 @@ public function dropDatabase($database) parent::dropDatabase($database); } catch (DBALException $exception) { $exception = $exception->getPrevious(); + assert($exception instanceof Throwable); if (! $exception instanceof DriverException) { throw $exception; diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 168e74ea87f..d0f50562785 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -134,8 +134,8 @@ protected function _getPortableTableForeignKeyDefinition($tableForeignKey) { $onUpdate = null; $onDelete = null; - $localColumns = null; - $foreignColumns = null; + $localColumns = []; + $foreignColumns = []; $foreignTable = null; if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { diff --git a/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php b/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php index ce3e403ae77..bd6b02cb9a0 100644 --- a/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\DriverException; use Doctrine\DBAL\Types\Type; use PDOException; +use Throwable; use function assert; use function count; use function in_array; @@ -31,6 +32,7 @@ public function dropDatabase($database) parent::dropDatabase($database); } catch (DBALException $exception) { $exception = $exception->getPrevious(); + assert($exception instanceof Throwable); if (! $exception instanceof DriverException) { throw $exception; diff --git a/lib/Doctrine/DBAL/Schema/Schema.php b/lib/Doctrine/DBAL/Schema/Schema.php index 7b75f4fb743..5d746654a40 100644 --- a/lib/Doctrine/DBAL/Schema/Schema.php +++ b/lib/Doctrine/DBAL/Schema/Schema.php @@ -105,7 +105,9 @@ protected function _addTable(Table $table) 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); } @@ -127,7 +129,9 @@ protected function _addSequence(Sequence $sequence) 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); } diff --git a/lib/Doctrine/DBAL/Schema/SchemaDiff.php b/lib/Doctrine/DBAL/Schema/SchemaDiff.php index 0f2e25fb32b..69bf125a844 100644 --- a/lib/Doctrine/DBAL/Schema/SchemaDiff.php +++ b/lib/Doctrine/DBAL/Schema/SchemaDiff.php @@ -10,7 +10,7 @@ */ class SchemaDiff { - /** @var Schema */ + /** @var Schema|null */ public $fromSchema; /** diff --git a/lib/Doctrine/DBAL/Schema/Sequence.php b/lib/Doctrine/DBAL/Schema/Sequence.php index 269961fb232..88891019bfd 100644 --- a/lib/Doctrine/DBAL/Schema/Sequence.php +++ b/lib/Doctrine/DBAL/Schema/Sequence.php @@ -104,11 +104,13 @@ public function setCache($cache) */ public function isAutoIncrementsFor(Table $table) { - if (! $table->hasPrimaryKey()) { + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { return false; } - $pkColumns = $table->getPrimaryKey()->getColumns(); + $pkColumns = $primaryKey->getColumns(); if (count($pkColumns) !== 1) { return false; diff --git a/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php b/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php index e51b27f3726..0925b7743c8 100644 --- a/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php +++ b/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php @@ -87,11 +87,14 @@ public function getDropSchema(Schema $dropSchema) } foreach ($dropSchema->getTables() as $table) { - if (! $table->hasPrimaryKey()) { + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { continue; } - $columns = $table->getPrimaryKey()->getColumns(); + $columns = $primaryKey->getColumns(); + if (count($columns) > 1) { continue; } diff --git a/lib/Doctrine/DBAL/Schema/Table.php b/lib/Doctrine/DBAL/Schema/Table.php index 5659e578636..6030f25cffa 100644 --- a/lib/Doctrine/DBAL/Schema/Table.php +++ b/lib/Doctrine/DBAL/Schema/Table.php @@ -216,7 +216,7 @@ public function renameIndex($oldIndexName, $newIndexName = null) if ($oldIndex->isPrimary()) { $this->dropPrimaryKey(); - return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName); + return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName ?? false); } unset($this->_indexes[$oldIndexName]); @@ -589,9 +589,11 @@ public function removeForeignKey($constraintName) */ public function getColumns() { + $primaryKey = $this->getPrimaryKey(); $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); @@ -681,10 +683,13 @@ public function getPrimaryKey() */ public function getPrimaryKeyColumns() { - if (! $this->hasPrimaryKey()) { + $primaryKey = $this->getPrimaryKey(); + + if ($primaryKey === null) { throw new DBALException('Table ' . $this->getName() . ' has no primary key.'); } - return $this->getPrimaryKey()->getColumns(); + + return $primaryKey->getColumns(); } /** @@ -820,12 +825,16 @@ public function __clone() * * 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. */ private function normalizeIdentifier($identifier) { + if ($identifier === null) { + return ''; + } + return $this->trimQuotes(strtolower($identifier)); } } diff --git a/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php b/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php index 318c8b26222..cc15bc0f655 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php @@ -47,7 +47,7 @@ public function acceptNamespace($namespaceName) */ 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)); } /** diff --git a/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php b/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php index 7efb39e2863..d5e94cf6ea3 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php @@ -81,7 +81,10 @@ private function createTableLabel(Table $table) $label .= '' . $columnLabel . ''; $label .= '