Fix too long lines

parent 0be2f9a5
...@@ -81,7 +81,8 @@ class Configuration ...@@ -81,7 +81,8 @@ class Configuration
{ {
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression; $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
if ($filterExpression) { if ($filterExpression) {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression); $this->_attributes['filterSchemaAssetsExpressionCallable']
= $this->buildSchemaAssetsFilterFromExpression($filterExpression);
} else { } else {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = null; $this->_attributes['filterSchemaAssetsExpressionCallable'] = null;
} }
......
...@@ -911,7 +911,12 @@ class Connection implements DriverConnection ...@@ -911,7 +911,12 @@ class Connection implements DriverConnection
$stmt = $connection->query($sql); $stmt = $connection->query($sql);
} }
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $sql, $this->resolveParams($params, $types)); throw DBALException::driverExceptionDuringQuery(
$this->_driver,
$ex,
$sql,
$this->resolveParams($params, $types)
);
} }
$stmt->setFetchMode($this->defaultFetchMode); $stmt->setFetchMode($this->defaultFetchMode);
...@@ -961,7 +966,13 @@ class Connection implements DriverConnection ...@@ -961,7 +966,13 @@ class Connection implements DriverConnection
} }
if (! isset($stmt)) { if (! isset($stmt)) {
$stmt = new ResultCacheStatement($this->executeQuery($sql, $params, $types), $resultCache, $cacheKey, $realKey, $qcp->getLifetime()); $stmt = new ResultCacheStatement(
$this->executeQuery($sql, $params, $types),
$resultCache,
$cacheKey,
$realKey,
$qcp->getLifetime()
);
} }
$stmt->setFetchMode($this->defaultFetchMode); $stmt->setFetchMode($this->defaultFetchMode);
...@@ -1069,7 +1080,12 @@ class Connection implements DriverConnection ...@@ -1069,7 +1080,12 @@ class Connection implements DriverConnection
$result = $connection->exec($sql); $result = $connection->exec($sql);
} }
} catch (Throwable $ex) { } catch (Throwable $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $sql, $this->resolveParams($params, $types)); throw DBALException::driverExceptionDuringQuery(
$this->_driver,
$ex,
$sql,
$this->resolveParams($params, $types)
);
} }
if ($logger) { if ($logger) {
......
...@@ -65,7 +65,8 @@ use function func_get_args; ...@@ -65,7 +65,8 @@ use function func_get_args;
* ) * )
* )); * ));
* *
* You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information. * You can also pass 'driverOptions' and any other documented option to each of this drivers
* to pass additional information.
*/ */
class MasterSlaveConnection extends Connection class MasterSlaveConnection extends Connection
{ {
...@@ -91,8 +92,12 @@ class MasterSlaveConnection extends Connection ...@@ -91,8 +92,12 @@ class MasterSlaveConnection extends Connection
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null) public function __construct(
{ array $params,
Driver $driver,
?Configuration $config = null,
?EventManager $eventManager = null
) {
if (! isset($params['slaves'], $params['master'])) { if (! isset($params['slaves'], $params['master'])) {
throw new InvalidArgumentException('master or slaves configuration missing'); throw new InvalidArgumentException('master or slaves configuration missing');
} }
......
...@@ -219,7 +219,9 @@ class DBALException extends Exception ...@@ -219,7 +219,9 @@ class DBALException extends Exception
*/ */
public static function invalidDriverClass($driverClass) public static function invalidDriverClass($driverClass)
{ {
return new self("The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.'); return new self(
"The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.'
);
} }
/** /**
...@@ -288,7 +290,9 @@ class DBALException extends Exception ...@@ -288,7 +290,9 @@ class DBALException extends Exception
public static function typeNotRegistered(Type $type): self public static function typeNotRegistered(Type $type): self
{ {
return new self(sprintf('Type of the class %s@%s is not registered.', get_class($type), spl_object_hash($type))); return new self(
sprintf('Type of the class %s@%s is not registered.', get_class($type), spl_object_hash($type))
);
} }
public static function typeAlreadyRegistered(Type $type): self public static function typeAlreadyRegistered(Type $type): self
......
...@@ -70,7 +70,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar ...@@ -70,7 +70,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
}); });
try { try {
if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) { if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) {
throw new MysqliException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno); throw new MysqliException(
$this->conn->connect_error,
$this->conn->sqlstate ?? 'HY000',
$this->conn->connect_errno
);
} }
} finally { } finally {
restore_error_handler(); restore_error_handler();
......
...@@ -223,7 +223,9 @@ class MysqliStatement implements IteratorAggregate, Statement ...@@ -223,7 +223,9 @@ class MysqliStatement implements IteratorAggregate, Statement
if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) { if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) {
if (is_resource($value)) { if (is_resource($value)) {
if (get_resource_type($value) !== 'stream') { if (get_resource_type($value) !== 'stream') {
throw new InvalidArgumentException('Resources passed with the LARGE_OBJECT parameter type must be stream resources.'); throw new InvalidArgumentException(
'Resources passed with the LARGE_OBJECT parameter type must be stream resources.'
);
} }
$streams[$parameter] = $value; $streams[$parameter] = $value;
......
...@@ -177,10 +177,12 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -177,10 +177,12 @@ 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 int $fragmentOffset The offset to build the next fragment from * @param int $fragmentOffset The offset to build the next fragment from
* @param string[] $fragments Fragments of the original statement not containing placeholders * @param string[] $fragments Fragments of the original statement
* not containing placeholders
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal * @param string|null $currentLiteralDelimiter The delimiter of the current string literal
* or NULL if not currently in a literal * or NULL if not currently in a literal
* @param array<int, string> $paramMap Mapping of the original parameter positions to their named replacements * @param array<int, string> $paramMap Mapping of the original parameter positions
* to their named replacements
* *
* @return bool Whether the token was found * @return bool Whether the token was found
*/ */
...@@ -282,7 +284,9 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -282,7 +284,9 @@ class OCI8Statement implements IteratorAggregate, Statement
{ {
if (is_int($param)) { if (is_int($param)) {
if (! isset($this->_paramMap[$param])) { if (! isset($this->_paramMap[$param])) {
throw new OCI8Exception(sprintf('Could not find variable mapping with index %d, in the SQL statement', $param)); throw new OCI8Exception(
sprintf('Could not find variable mapping with index %d, in the SQL statement', $param)
);
} }
$param = $this->_paramMap[$param]; $param = $this->_paramMap[$param];
......
...@@ -70,13 +70,15 @@ interface ResultStatement extends Traversable ...@@ -70,13 +70,15 @@ interface ResultStatement extends Traversable
* @param int|null $fetchMode Controls how the next row will be returned to the caller. * @param int|null $fetchMode Controls how the next row will be returned to the caller.
* The value must be one of the {@link FetchMode} constants, * The value must be one of the {@link FetchMode} constants,
* defaulting to {@link FetchMode::MIXED}. * defaulting to {@link FetchMode::MIXED}.
* @param int|null $fetchArgument This argument has a different meaning depending on the value of the $fetchMode parameter: * @param int|null $fetchArgument This argument has a different meaning depending on the value
* of the $fetchMode parameter:
* * {@link FetchMode::COLUMN}: * * {@link FetchMode::COLUMN}:
* Returns the indicated 0-indexed column. * Returns the indicated 0-indexed column.
* * {@link FetchMode::CUSTOM_OBJECT}: * * {@link FetchMode::CUSTOM_OBJECT}:
* Returns instances of the specified class, mapping the columns of each row * Returns instances of the specified class, mapping the columns of each row
* to named properties in the class. * to named properties in the class.
* * {@link PDO::FETCH_FUNC}: Returns the results of calling the specified function, using each row's * * {@link PDO::FETCH_FUNC}: Returns the results of calling
* the specified function, using each row's
* columns as parameters in the call. * columns as parameters in the call.
* @param mixed[]|null $ctorArgs Controls how the next row will be returned to the caller. * @param mixed[]|null $ctorArgs Controls how the next row will be returned to the caller.
* The value must be one of the {@link FetchMode} constants, * The value must be one of the {@link FetchMode} constants,
......
...@@ -64,8 +64,15 @@ class Driver extends AbstractSQLAnywhereDriver ...@@ -64,8 +64,15 @@ class Driver extends AbstractSQLAnywhereDriver
* *
* @return string * @return string
*/ */
private function buildDsn($host, $port, $server, $dbname, $username = null, $password = null, array $driverOptions = []) private function buildDsn(
{ $host,
$port,
$server,
$dbname,
$username = null,
$password = null,
array $driverOptions = []
) {
$host = $host ?: 'localhost'; $host = $host ?: 'localhost';
$port = $port ?: 2638; $port = $port ?: 2638;
......
...@@ -170,7 +170,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -170,7 +170,9 @@ class SQLSrvStatement implements IteratorAggregate, Statement
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null) public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
{ {
if (! is_numeric($param)) { if (! is_numeric($param)) {
throw new SQLSrvException('sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.'); throw new SQLSrvException(
'sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.'
);
} }
$this->variables[$param] =& $variable; $this->variables[$param] =& $variable;
......
...@@ -227,7 +227,10 @@ final class DriverManager ...@@ -227,7 +227,10 @@ final class DriverManager
throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap)); throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap));
} }
if (isset($params['driverClass']) && ! in_array(Driver::class, class_implements($params['driverClass'], true))) { if (
isset($params['driverClass'])
&& ! in_array(Driver::class, class_implements($params['driverClass'], true))
) {
throw DBALException::invalidDriverClass($params['driverClass']); throw DBALException::invalidDriverClass($params['driverClass']);
} }
} }
......
...@@ -75,7 +75,8 @@ class TableGenerator ...@@ -75,7 +75,8 @@ class TableGenerator
throw new DBALException('Cannot use TableGenerator with SQLite.'); throw new DBALException('Cannot use TableGenerator with SQLite.');
} }
$this->conn = DriverManager::getConnection($params, $conn->getConfiguration(), $conn->getEventManager()); $this->conn = DriverManager::getConnection($params, $conn->getConfiguration(), $conn->getEventManager());
$this->generatorTableName = $generatorTableName; $this->generatorTableName = $generatorTableName;
} }
...@@ -145,7 +146,11 @@ class TableGenerator ...@@ -145,7 +146,11 @@ class TableGenerator
} catch (Throwable $e) { } catch (Throwable $e) {
$this->conn->rollBack(); $this->conn->rollBack();
throw new DBALException('Error occurred while generating ID with TableGenerator, aborted generation: ' . $e->getMessage(), 0, $e); throw new DBALException(
'Error occurred while generating ID with TableGenerator, aborted generation: ' . $e->getMessage(),
0,
$e
);
} }
return $value; return $value;
......
...@@ -38,8 +38,14 @@ class DebugStack implements SQLLogger ...@@ -38,8 +38,14 @@ class DebugStack implements SQLLogger
return; return;
} }
$this->start = microtime(true); $this->start = microtime(true);
$this->queries[++$this->currentQuery] = ['sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0];
$this->queries[++$this->currentQuery] = [
'sql' => $sql,
'params' => $params,
'types' => $types,
'executionMS' => 0,
];
} }
/** /**
......
...@@ -291,7 +291,8 @@ abstract class AbstractPlatform ...@@ -291,7 +291,8 @@ abstract class AbstractPlatform
if ($column['length'] > $maxLength) { if ($column['length'] > $maxLength) {
if ($maxLength > 0) { if ($maxLength > 0) {
@trigger_error(sprintf( @trigger_error(sprintf(
'Binary column length %d is greater than supported by the platform (%d). Reduce the column length or use a BLOB column instead.', 'Binary column length %d is greater than supported by the platform (%d).'
. ' Reduce the column length or use a BLOB column instead.',
$column['length'], $column['length'],
$maxLength $maxLength
), E_USER_DEPRECATED); ), E_USER_DEPRECATED);
...@@ -439,7 +440,9 @@ abstract class AbstractPlatform ...@@ -439,7 +440,9 @@ abstract class AbstractPlatform
$dbType = strtolower($dbType); $dbType = strtolower($dbType);
if (! isset($this->doctrineTypeMapping[$dbType])) { if (! isset($this->doctrineTypeMapping[$dbType])) {
throw new DBALException('Unknown database type ' . $dbType . ' requested, ' . static::class . ' may not support it.'); throw new DBALException(
'Unknown database type ' . $dbType . ' requested, ' . static::class . ' may not support it.'
);
} }
return $this->doctrineTypeMapping[$dbType]; return $this->doctrineTypeMapping[$dbType];
...@@ -1355,7 +1358,8 @@ abstract class AbstractPlatform ...@@ -1355,7 +1358,8 @@ abstract class AbstractPlatform
} }
/** /**
* Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification. * Honors that some SQL vendors such as MsSql use table hints for locking instead of the
* ANSI SQL FOR UPDATE specification.
* *
* @param string $fromClause The FROM clause to append the hint for the given lock mode to. * @param string $fromClause The FROM clause to append the hint for the given lock mode to.
* @param int|null $lockMode One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will * @param int|null $lockMode One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will
...@@ -1543,7 +1547,9 @@ abstract class AbstractPlatform ...@@ -1543,7 +1547,9 @@ abstract class AbstractPlatform
public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES) public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
{ {
if (! is_int($createFlags)) { if (! is_int($createFlags)) {
throw new InvalidArgumentException('Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.'); throw new InvalidArgumentException(
'Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.'
);
} }
if (count($table->getColumns()) === 0) { if (count($table->getColumns()) === 0) {
...@@ -1571,7 +1577,10 @@ abstract class AbstractPlatform ...@@ -1571,7 +1577,10 @@ abstract class AbstractPlatform
$columns = []; $columns = [];
foreach ($table->getColumns() as $column) { foreach ($table->getColumns() as $column) {
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) { if (
$this->_eventManager !== null
&& $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)
) {
$eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this); $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs); $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
...@@ -1582,10 +1591,11 @@ abstract class AbstractPlatform ...@@ -1582,10 +1591,11 @@ abstract class AbstractPlatform
} }
} }
$columnData = $column->toArray(); $columnData = array_merge($column->toArray(), [
$columnData['name'] = $column->getQuotedName($this); 'name' => $column->getQuotedName($this),
$columnData['version'] = $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false; 'version' => $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false,
$columnData['comment'] = $this->getColumnComment($column); 'comment' => $this->getColumnComment($column),
]);
if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) { if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) {
$columnData['length'] = 255; $columnData['length'] = 255;
...@@ -2175,7 +2185,10 @@ abstract class AbstractPlatform ...@@ -2175,7 +2185,10 @@ abstract class AbstractPlatform
*/ */
protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff) protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff)); return array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
} }
/** /**
......
...@@ -628,8 +628,12 @@ class DB2Platform extends AbstractPlatform ...@@ -628,8 +628,12 @@ class DB2Platform extends AbstractPlatform
* @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(Identifier $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts): void private function gatherAlterColumnSQL(
{ Identifier $table,
ColumnDiff $columnDiff,
array &$sql,
array &$queryParts
): void {
$alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff);
if (empty($alterColumnClauses)) { if (empty($alterColumnClauses)) {
......
...@@ -329,8 +329,8 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -329,8 +329,8 @@ class DrizzlePlatform extends AbstractPlatform
$databaseSQL = 'DATABASE()'; $databaseSQL = 'DATABASE()';
} }
return 'SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, IS_AUTO_INCREMENT, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT,' . return 'SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, IS_AUTO_INCREMENT,' .
' NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME' . ' CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT, NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME' .
' FROM DATA_DICTIONARY.COLUMNS' . ' FROM DATA_DICTIONARY.COLUMNS' .
' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table); ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table);
} }
...@@ -349,9 +349,11 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -349,9 +349,11 @@ class DrizzlePlatform extends AbstractPlatform
$databaseSQL = 'DATABASE()'; $databaseSQL = 'DATABASE()';
} }
return 'SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS, UPDATE_RULE, DELETE_RULE' . return 'SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS,'
' FROM DATA_DICTIONARY.FOREIGN_KEYS' . . ' UPDATE_RULE, DELETE_RULE'
' WHERE CONSTRAINT_SCHEMA=' . $databaseSQL . ' AND CONSTRAINT_TABLE=' . $this->quoteStringLiteral($table); . ' FROM DATA_DICTIONARY.FOREIGN_KEYS'
. ' WHERE CONSTRAINT_SCHEMA=' . $databaseSQL
. ' AND CONSTRAINT_TABLE=' . $this->quoteStringLiteral($table);
} }
/** /**
...@@ -365,9 +367,12 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -365,9 +367,12 @@ class DrizzlePlatform extends AbstractPlatform
$databaseSQL = 'DATABASE()'; $databaseSQL = 'DATABASE()';
} }
return "SELECT INDEX_NAME AS 'key_name', COLUMN_NAME AS 'column_name', IS_USED_IN_PRIMARY AS 'primary', IS_UNIQUE=0 AS 'non_unique'" . return "SELECT INDEX_NAME AS 'key_name',"
' FROM DATA_DICTIONARY.INDEX_PARTS' . . " COLUMN_NAME AS 'column_name',"
' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME=' . $this->quoteStringLiteral($table); . " IS_USED_IN_PRIMARY AS 'primary',"
. " IS_UNIQUE=0 AS 'non_unique'"
. ' FROM DATA_DICTIONARY.INDEX_PARTS'
. ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME=' . $this->quoteStringLiteral($table);
} }
/** /**
...@@ -499,9 +504,11 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -499,9 +504,11 @@ class DrizzlePlatform extends AbstractPlatform
continue; continue;
} }
$columnArray = $column->toArray(); $columnArray = array_merge($column->toArray(), [
$columnArray['comment'] = $this->getColumnComment($column); 'comment' => $this->getColumnComment($column),
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); ]);
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
} }
foreach ($diff->removedColumns as $column) { foreach ($diff->removedColumns as $column) {
...@@ -554,7 +561,8 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -554,7 +561,8 @@ class DrizzlePlatform extends AbstractPlatform
if (! $this->onSchemaAlterTable($diff, $tableSql)) { if (! $this->onSchemaAlterTable($diff, $tableSql)) {
if (count($queryParts) > 0) { if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(', ', $queryParts); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' ' . implode(', ', $queryParts);
} }
$sql = array_merge( $sql = array_merge(
......
...@@ -198,10 +198,9 @@ class MySqlPlatform extends AbstractPlatform ...@@ -198,10 +198,9 @@ class MySqlPlatform extends AbstractPlatform
$databaseNameSql = $database ?? 'DATABASE()'; $databaseNameSql = $database ?? 'DATABASE()';
$sql .= ' AND k.table_schema = ' . $databaseNameSql . ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */'; return $sql . ' AND k.table_schema = ' . $databaseNameSql
$sql .= ' AND k.`REFERENCED_COLUMN_NAME` is not NULL'; . ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */'
. ' AND k.`REFERENCED_COLUMN_NAME` is not NULL';
return $sql;
} }
/** /**
...@@ -566,9 +565,11 @@ SQL ...@@ -566,9 +565,11 @@ SQL
continue; continue;
} }
$columnArray = $column->toArray(); $columnArray = array_merge($column->toArray(), [
$columnArray['comment'] = $this->getColumnComment($column); 'comment' => $this->getColumnComment($column),
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); ]);
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
} }
foreach ($diff->removedColumns as $column) { foreach ($diff->removedColumns as $column) {
...@@ -635,7 +636,8 @@ SQL ...@@ -635,7 +636,8 @@ SQL
if (! $this->onSchemaAlterTable($diff, $tableSql)) { if (! $this->onSchemaAlterTable($diff, $tableSql)) {
if (count($queryParts) > 0) { if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(', ', $queryParts); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' '
. implode(', ', $queryParts);
} }
$sql = array_merge( $sql = array_merge(
......
...@@ -508,14 +508,15 @@ class OraclePlatform extends AbstractPlatform ...@@ -508,14 +508,15 @@ class OraclePlatform extends AbstractPlatform
$idx = new Index($autoincrementIdentifierName, [$quotedName], true, true); $idx = new Index($autoincrementIdentifierName, [$quotedName], true, true);
$sql[] = 'DECLARE $sql[] = "DECLARE
constraints_Count NUMBER; constraints_Count NUMBER;
BEGIN BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \'' . $unquotedTableName . '\' AND CONSTRAINT_TYPE = \'P\'; SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '" . $unquotedTableName
IF constraints_Count = 0 OR constraints_Count = \'\' THEN . "' AND CONSTRAINT_TYPE = 'P';
EXECUTE IMMEDIATE \'' . $this->getCreateConstraintSQL($idx, $quotedTableName) . '\'; IF constraints_Count = 0 OR constraints_Count = '' THEN
EXECUTE IMMEDIATE '" . $this->getCreateConstraintSQL($idx, $quotedTableName) . "';
END IF; END IF;
END;'; END;";
$sequenceName = $this->getIdentitySequenceName( $sequenceName = $this->getIdentitySequenceName(
$tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName, $tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName,
...@@ -819,7 +820,8 @@ SQL ...@@ -819,7 +820,8 @@ SQL
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ADD (' . implode(', ', $fields) . ')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' ADD (' . implode(', ', $fields) . ')';
} }
$fields = []; $fields = [];
...@@ -868,7 +870,8 @@ SQL ...@@ -868,7 +870,8 @@ SQL
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' MODIFY (' . implode(', ', $fields) . ')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' MODIFY (' . implode(', ', $fields) . ')';
} }
foreach ($diff->renamedColumns as $oldColumnName => $column) { foreach ($diff->renamedColumns as $oldColumnName => $column) {
...@@ -892,7 +895,8 @@ SQL ...@@ -892,7 +895,8 @@ SQL
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' DROP (' . implode(', ', $fields) . ')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' DROP (' . implode(', ', $fields) . ')';
} }
$tableSql = []; $tableSql = [];
...@@ -1217,7 +1221,9 @@ SQL ...@@ -1217,7 +1221,9 @@ SQL
if ($database !== null && $database !== '/') { if ($database !== null && $database !== '/') {
$tableCommentsName = 'all_tab_comments'; $tableCommentsName = 'all_tab_comments';
$ownerCondition = ' AND owner = ' . $this->quoteStringLiteral($this->normalizeIdentifier($database)->getName()); $ownerCondition = ' AND owner = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($database)->getName()
);
} }
return sprintf( return sprintf(
......
...@@ -41,6 +41,8 @@ class PostgreSQL91Platform extends PostgreSqlPlatform ...@@ -41,6 +41,8 @@ class PostgreSQL91Platform extends PostgreSqlPlatform
$sql = parent::getListTableColumnsSQL($table, $database); $sql = parent::getListTableColumnsSQL($table, $database);
$parts = explode('AS complete_type,', $sql, 2); $parts = explode('AS complete_type,', $sql, 2);
return $parts[0] . 'AS complete_type, (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,' . $parts[1]; return $parts[0] . 'AS complete_type, '
. '(SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,'
. $parts[1];
} }
} }
...@@ -114,7 +114,8 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -114,7 +114,8 @@ class PostgreSqlPlatform extends AbstractPlatform
if ($startPos !== false) { if ($startPos !== false) {
$str = $this->getSubstringExpression($str, $startPos); $str = $this->getSubstringExpression($str, $startPos);
return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0 ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . ($startPos - 1) . ') END'; return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0'
. ' ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . ($startPos - 1) . ') END';
} }
return 'POSITION(' . $substr . ' IN ' . $str . ')'; return 'POSITION(' . $substr . ' IN ' . $str . ')';
...@@ -355,7 +356,8 @@ SQL ...@@ -355,7 +356,8 @@ SQL
WHERE oid IN ( WHERE oid IN (
SELECT indexrelid SELECT indexrelid
FROM pg_index si, pg_class sc, pg_namespace sn FROM pg_index si, pg_class sc, pg_namespace sn
WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . ' AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . '
AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
) AND pg_index.indexrelid = oid'; ) AND pg_index.indexrelid = oid';
} }
...@@ -544,7 +546,12 @@ SQL ...@@ -544,7 +546,12 @@ SQL
$oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this); $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
$column = $columnDiff->column; $column = $columnDiff->column;
if ($columnDiff->hasChanged('type') || $columnDiff->hasChanged('precision') || $columnDiff->hasChanged('scale') || $columnDiff->hasChanged('fixed')) { if (
$columnDiff->hasChanged('type')
|| $columnDiff->hasChanged('precision')
|| $columnDiff->hasChanged('scale')
|| $columnDiff->hasChanged('fixed')
) {
$type = $column->getType(); $type = $column->getType();
// SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type // SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type
...@@ -575,7 +582,8 @@ SQL ...@@ -575,7 +582,8 @@ SQL
$seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName); $seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName);
$sql[] = 'CREATE SEQUENCE ' . $seqName; $sql[] = 'CREATE SEQUENCE ' . $seqName;
$sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM ' . $diff->getName($this)->getQuotedName($this) . '))'; $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM '
. $diff->getName($this)->getQuotedName($this) . '))';
$query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; $query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} else { } else {
...@@ -588,7 +596,10 @@ SQL ...@@ -588,7 +596,10 @@ SQL
$newComment = $this->getColumnComment($column); $newComment = $this->getColumnComment($column);
$oldComment = $this->getOldColumnComment($columnDiff); $oldComment = $this->getOldColumnComment($columnDiff);
if ($columnDiff->hasChanged('comment') || ($columnDiff->fromColumn !== null && $oldComment !== $newComment)) { if (
$columnDiff->hasChanged('comment')
|| ($columnDiff->fromColumn !== null && $oldComment !== $newComment)
) {
$commentsSQL[] = $this->getCommentOnColumnSQL( $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->getName($this)->getQuotedName($this), $diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this), $column->getQuotedName($this),
...@@ -600,7 +611,8 @@ SQL ...@@ -600,7 +611,8 @@ SQL
continue; continue;
} }
$query = 'ALTER ' . $oldColumnName . ' TYPE ' . $column->getType()->getSQLDeclaration($column->toArray(), $this); $query = 'ALTER ' . $oldColumnName . ' TYPE '
. $column->getType()->getSQLDeclaration($column->toArray(), $this);
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
......
...@@ -1150,7 +1150,8 @@ SQL ...@@ -1150,7 +1150,8 @@ SQL
default: default:
return 'REVERSE(SUBSTR(REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))), ' . return 'REVERSE(SUBSTR(REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))), ' .
'PATINDEX(' . $pattern . ', REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))))))'; 'PATINDEX(' . $pattern . ', ' .
'REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))))))';
} }
} }
...@@ -1272,7 +1273,8 @@ SQL ...@@ -1272,7 +1273,8 @@ SQL
$flags = ' CLUSTERED '; $flags = ' CLUSTERED ';
} }
$columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values((array) $options['primary']))) . ')'; $columnListSql .= ', PRIMARY KEY' . $flags
. ' (' . implode(', ', array_unique(array_values((array) $options['primary']))) . ')';
} }
if (! empty($options['foreignKeys'])) { if (! empty($options['foreignKeys'])) {
...@@ -1394,8 +1396,8 @@ SQL ...@@ -1394,8 +1396,8 @@ SQL
if (! $constraint->isPrimary() && ! $constraint->isUnique()) { if (! $constraint->isPrimary() && ! $constraint->isUnique()) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
'Can only create primary, unique or foreign key constraint declarations, no common index declarations ' . 'Can only create primary, unique or foreign key constraint declarations, no common index declarations'
'with getTableConstraintDeclarationSQL().' . ' with getTableConstraintDeclarationSQL().'
); );
} }
...@@ -1418,7 +1420,8 @@ SQL ...@@ -1418,7 +1420,8 @@ SQL
} }
if ($constraint->isPrimary()) { if ($constraint->isPrimary()) {
return $sql . 'PRIMARY KEY ' . $flags . '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; return $sql . 'PRIMARY KEY ' . $flags
. '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')';
} }
return $sql . 'UNIQUE ' . $flags . '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; return $sql . 'UNIQUE ' . $flags . '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')';
......
...@@ -17,7 +17,8 @@ class SQLServer2008Platform extends SQLServer2005Platform ...@@ -17,7 +17,8 @@ class SQLServer2008Platform extends SQLServer2005Platform
{ {
// "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
// Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication // Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication
return "SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name"; return 'SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects'
. " WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name";
} }
/** /**
......
...@@ -289,7 +289,8 @@ SQL ...@@ -289,7 +289,8 @@ SQL
$flags = ' NONCLUSTERED'; $flags = ' NONCLUSTERED';
} }
$columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')'; $columnListSql .= ', PRIMARY KEY' . $flags
. ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')';
} }
$query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
...@@ -554,10 +555,12 @@ SQL ...@@ -554,10 +555,12 @@ SQL
$columnDef = $column->toArray(); $columnDef = $column->toArray();
$queryParts[] = 'ALTER COLUMN ' . $queryParts[] = 'ALTER COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
$this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
if (! isset($columnDef['default']) || (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))) { if (
! isset($columnDef['default'])
|| (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))
) {
continue; continue;
} }
...@@ -1084,15 +1087,6 @@ SQL ...@@ -1084,15 +1087,6 @@ SQL
return $trimFn . '(' . $str . ')'; return $trimFn . '(' . $str . ')';
} }
/** Original query used to get those expressions
declare @c varchar(100) = 'xxxBarxxx', @trim_char char(1) = 'x';
declare @pat varchar(10) = '%[^' + @trim_char + ']%';
select @c as string
, @trim_char as trim_char
, stuff(@c, 1, patindex(@pat, @c) - 1, null) as trim_leading
, reverse(stuff(reverse(@c), 1, patindex(@pat, reverse(@c)) - 1, null)) as trim_trailing
, reverse(stuff(reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null)), 1, patindex(@pat, reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null))) - 1, null)) as trim_both;
*/
$pattern = "'%[^' + " . $char . " + ']%'"; $pattern = "'%[^' + " . $char . " + ']%'";
if ($pos === TrimMode::LEADING) { if ($pos === TrimMode::LEADING) {
...@@ -1100,10 +1094,13 @@ SQL ...@@ -1100,10 +1094,13 @@ SQL
} }
if ($pos === TrimMode::TRAILING) { if ($pos === TrimMode::TRAILING) {
return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))'; return 'reverse(stuff(reverse(' . $str . '), 1, '
. 'patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))';
} }
return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null))) - 1, null))'; return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, '
. 'patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str
. ') - 1, null))) - 1, null))';
} }
/** /**
...@@ -1197,7 +1194,9 @@ SQL ...@@ -1197,7 +1194,9 @@ SQL
*/ */
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{ {
return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)'); return $fixed
? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
} }
/** /**
......
...@@ -473,9 +473,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -473,9 +473,13 @@ class SqlitePlatform extends AbstractPlatform
*/ */
public function getListTablesSQL() public function getListTablesSQL()
{ {
return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' " return 'SELECT name FROM sqlite_master'
. 'UNION ALL SELECT name FROM sqlite_temp_master ' . " WHERE type = 'table'"
. "WHERE type = 'table' ORDER BY name"; . " AND name != 'sqlite_sequence'"
. " AND name != 'geometry_columns'"
. " AND name != 'spatial_ref_sys'"
. ' UNION ALL SELECT name FROM sqlite_temp_master'
. " WHERE type = 'table' ORDER BY name";
} }
/** /**
...@@ -509,8 +513,18 @@ class SqlitePlatform extends AbstractPlatform ...@@ -509,8 +513,18 @@ class SqlitePlatform extends AbstractPlatform
{ {
$query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey); $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
$query .= ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false ? ' ' : ' NOT ') . 'DEFERRABLE'; if (! $foreignKey->hasOption('deferrable') || $foreignKey->getOption('deferrable') === false) {
$query .= ' INITIALLY ' . ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false ? 'DEFERRED' : 'IMMEDIATE'); $query .= ' NOT';
}
$query .= ' DEFERRABLE';
$query .= ' INITIALLY';
if ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) {
$query .= ' DEFERRED';
} else {
$query .= ' IMMEDIATE';
}
return $query; return $query;
} }
...@@ -683,7 +697,9 @@ class SqlitePlatform extends AbstractPlatform ...@@ -683,7 +697,9 @@ class SqlitePlatform extends AbstractPlatform
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
if (! $diff->fromTable instanceof Table) { if (! $diff->fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); throw new DBALException(
'Sqlite platform requires for alter table the table diff with reference to original table schema'
);
} }
$sql = []; $sql = [];
...@@ -704,7 +720,9 @@ class SqlitePlatform extends AbstractPlatform ...@@ -704,7 +720,9 @@ class SqlitePlatform extends AbstractPlatform
protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
if (! $diff->fromTable instanceof Table) { if (! $diff->fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); throw new DBALException(
'Sqlite platform requires for alter table the table diff with reference to original table schema'
);
} }
$sql = []; $sql = [];
...@@ -795,7 +813,10 @@ class SqlitePlatform extends AbstractPlatform ...@@ -795,7 +813,10 @@ class SqlitePlatform extends AbstractPlatform
*/ */
public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
{ {
throw new DBALException('Sqlite platform does not support alter foreign key, the table must be fully recreated using getAlterTableSQL.'); throw new DBALException(
'Sqlite platform does not support alter foreign key, '
. 'the table must be fully recreated using getAlterTableSQL.'
);
} }
/** /**
...@@ -803,7 +824,10 @@ class SqlitePlatform extends AbstractPlatform ...@@ -803,7 +824,10 @@ class SqlitePlatform extends AbstractPlatform
*/ */
public function getDropForeignKeySQL($foreignKey, $table) public function getDropForeignKeySQL($foreignKey, $table)
{ {
throw new DBALException('Sqlite platform does not support alter foreign key, the table must be fully recreated using getAlterTableSQL.'); throw new DBALException(
'Sqlite platform does not support alter foreign key, '
. 'the table must be fully recreated using getAlterTableSQL.'
);
} }
/** /**
...@@ -851,7 +875,9 @@ class SqlitePlatform extends AbstractPlatform ...@@ -851,7 +875,9 @@ class SqlitePlatform extends AbstractPlatform
$fromTable = $diff->fromTable; $fromTable = $diff->fromTable;
if (! $fromTable instanceof Table) { if (! $fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); throw new DBALException(
'Sqlite platform requires for alter table the table diff with reference to original table schema'
);
} }
$table = clone $fromTable; $table = clone $fromTable;
...@@ -934,16 +960,34 @@ class SqlitePlatform extends AbstractPlatform ...@@ -934,16 +960,34 @@ class SqlitePlatform extends AbstractPlatform
if (! $this->onSchemaAlterTable($diff, $tableSql)) { if (! $this->onSchemaAlterTable($diff, $tableSql)) {
$dataTable = new Table('__temp__' . $table->getName()); $dataTable = new Table('__temp__' . $table->getName());
$newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions()); $newTable = new Table(
$table->getQuotedName($this),
$columns,
$this->getPrimaryIndexInAlteredTable($diff),
$this->getForeignKeysInAlteredTable($diff),
0,
$table->getOptions()
);
$newTable->addOption('alter', true); $newTable->addOption('alter', true);
$sql = $this->getPreAlterTableIndexForeignKeySQL($diff); $sql = $this->getPreAlterTableIndexForeignKeySQL($diff);
//$sql = array_merge($sql, $this->getCreateTableSQL($dataTable, 0));
$sql[] = sprintf('CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s', $dataTable->getQuotedName($this), implode(', ', $oldColumnNames), $table->getQuotedName($this)); $sql[] = sprintf(
'CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s',
$dataTable->getQuotedName($this),
implode(', ', $oldColumnNames),
$table->getQuotedName($this)
);
$sql[] = $this->getDropTableSQL($fromTable); $sql[] = $this->getDropTableSQL($fromTable);
$sql = array_merge($sql, $this->getCreateTableSQL($newTable)); $sql = array_merge($sql, $this->getCreateTableSQL($newTable));
$sql[] = sprintf('INSERT INTO %s (%s) SELECT %s FROM %s', $newTable->getQuotedName($this), implode(', ', $newColumnNames), implode(', ', $oldColumnNames), $dataTable->getQuotedName($this)); $sql[] = sprintf(
'INSERT INTO %s (%s) SELECT %s FROM %s',
$newTable->getQuotedName($this),
implode(', ', $newColumnNames),
implode(', ', $oldColumnNames),
$dataTable->getQuotedName($this)
);
$sql[] = $this->getDropTableSQL($dataTable); $sql[] = $this->getDropTableSQL($dataTable);
$newName = $diff->getNewName(); $newName = $diff->getNewName();
...@@ -994,10 +1038,16 @@ class SqlitePlatform extends AbstractPlatform ...@@ -994,10 +1038,16 @@ class SqlitePlatform extends AbstractPlatform
} }
if ( if (
! empty($diff->renamedColumns) || ! empty($diff->addedForeignKeys) || ! empty($diff->addedIndexes) ! empty($diff->renamedColumns)
|| ! empty($diff->changedColumns) || ! empty($diff->changedForeignKeys) || ! empty($diff->changedIndexes) || ! empty($diff->addedForeignKeys)
|| ! empty($diff->removedColumns) || ! empty($diff->removedForeignKeys) || ! empty($diff->removedIndexes) || ! empty($diff->addedIndexes)
|| ! empty($diff->renamedIndexes) || ! empty($diff->changedColumns)
|| ! empty($diff->changedForeignKeys)
|| ! empty($diff->changedIndexes)
|| ! empty($diff->removedColumns)
|| ! empty($diff->removedForeignKeys)
|| ! empty($diff->removedIndexes)
|| ! empty($diff->renamedIndexes)
) { ) {
return false; return false;
} }
...@@ -1013,8 +1063,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -1013,8 +1063,13 @@ class SqlitePlatform extends AbstractPlatform
continue; continue;
} }
$definition = array_merge(['unique' => null, 'autoincrement' => null, 'default' => null], $column->toArray()); $definition = array_merge([
$type = $definition['type']; 'unique' => null,
'autoincrement' => null,
'default' => null,
], $column->toArray());
$type = $definition['type'];
switch (true) { switch (true) {
case isset($definition['columnDefinition']) || $definition['autoincrement'] || $definition['unique']: case isset($definition['columnDefinition']) || $definition['autoincrement'] || $definition['unique']:
...@@ -1029,13 +1084,16 @@ class SqlitePlatform extends AbstractPlatform ...@@ -1029,13 +1084,16 @@ class SqlitePlatform extends AbstractPlatform
$definition['length'] = 255; $definition['length'] = 255;
} }
$sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN ' . $this->getColumnDeclarationSQL($definition['name'], $definition); $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN '
. $this->getColumnDeclarationSQL($definition['name'], $definition);
} }
if (! $this->onSchemaAlterTable($diff, $tableSql)) { if (! $this->onSchemaAlterTable($diff, $tableSql)) {
if ($diff->newName !== false) { if ($diff->newName !== false) {
$newTable = new Identifier($diff->newName); $newTable = new Identifier($diff->newName);
$sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO ' . $newTable->getQuotedName($this);
$sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO '
. $newTable->getQuotedName($this);
} }
} }
...@@ -1120,7 +1178,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -1120,7 +1178,13 @@ class SqlitePlatform extends AbstractPlatform
continue; continue;
} }
$indexes[$key] = new Index($index->getName(), $indexColumns, $index->isUnique(), $index->isPrimary(), $index->getFlags()); $indexes[$key] = new Index(
$index->getName(),
$indexColumns,
$index->isUnique(),
$index->isPrimary(),
$index->getFlags()
);
} }
foreach ($diff->removedIndexes as $index) { foreach ($diff->removedIndexes as $index) {
...@@ -1174,7 +1238,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -1174,7 +1238,13 @@ class SqlitePlatform extends AbstractPlatform
continue; continue;
} }
$foreignKeys[$key] = new ForeignKeyConstraint($localColumns, $constraint->getForeignTableName(), $constraint->getForeignColumns(), $constraint->getName(), $constraint->getOptions()); $foreignKeys[$key] = new ForeignKeyConstraint(
$localColumns,
$constraint->getForeignTableName(),
$constraint->getForeignColumns(),
$constraint->getName(),
$constraint->getOptions()
);
} }
foreach ($diff->removedForeignKeys as $constraint) { foreach ($diff->removedForeignKeys as $constraint) {
......
...@@ -427,7 +427,12 @@ class QueryBuilder ...@@ -427,7 +427,12 @@ class QueryBuilder
$this->state = self::STATE_DIRTY; $this->state = self::STATE_DIRTY;
if ($append) { if ($append) {
if ($sqlPartName === 'orderBy' || $sqlPartName === 'groupBy' || $sqlPartName === 'select' || $sqlPartName === 'set') { if (
$sqlPartName === 'orderBy'
|| $sqlPartName === 'groupBy'
|| $sqlPartName === 'select'
|| $sqlPartName === 'set'
) {
foreach ($sqlPart as $part) { foreach ($sqlPart as $part) {
$this->sqlParts[$sqlPartName][] = $part; $this->sqlParts[$sqlPartName][] = $part;
} }
...@@ -1212,7 +1217,8 @@ class QueryBuilder ...@@ -1212,7 +1217,8 @@ class QueryBuilder
*/ */
private function getSQLForUpdate() private function getSQLForUpdate()
{ {
$table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); $table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
return 'UPDATE ' . $table return 'UPDATE ' . $table
. ' SET ' . implode(', ', $this->sqlParts['set']) . ' SET ' . implode(', ', $this->sqlParts['set'])
...@@ -1226,9 +1232,11 @@ class QueryBuilder ...@@ -1226,9 +1232,11 @@ class QueryBuilder
*/ */
private function getSQLForDelete() private function getSQLForDelete()
{ {
$table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); $table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
return 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); return 'DELETE FROM ' . $table
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
} }
/** /**
......
...@@ -89,7 +89,12 @@ class SQLParserUtils ...@@ -89,7 +89,12 @@ class SQLParserUtils
$statement, $statement,
':', ':',
self::NAMED_TOKEN, self::NAMED_TOKEN,
static function (string $placeholder, int $placeholderPosition, int $fragmentPosition, array &$carry): void { static function (
string $placeholder,
int $placeholderPosition,
int $fragmentPosition,
array &$carry
): void {
$carry[$placeholderPosition + $fragmentPosition] = substr($placeholder, 1); $carry[$placeholderPosition + $fragmentPosition] = substr($placeholder, 1);
} }
); );
...@@ -98,8 +103,12 @@ class SQLParserUtils ...@@ -98,8 +103,12 @@ class SQLParserUtils
/** /**
* @return mixed[] * @return mixed[]
*/ */
private static function collectPlaceholders(string $statement, string $match, string $token, callable $collector): array private static function collectPlaceholders(
{ string $statement,
string $match,
string $token,
callable $collector
): array {
if (strpos($statement, $match) === false) { if (strpos($statement, $match) === false) {
return []; return [];
} }
......
...@@ -18,7 +18,9 @@ class SQLParserUtilsException extends DBALException ...@@ -18,7 +18,9 @@ class SQLParserUtilsException extends DBALException
*/ */
public static function missingParam($paramName) public static function missingParam($paramName)
{ {
return new self(sprintf('Value for :%1$s not found in params array. Params array key should be "%1$s"', $paramName)); return new self(
sprintf('Value for :%1$s not found in params array. Params array key should be "%1$s"', $paramName)
);
} }
/** /**
...@@ -28,6 +30,8 @@ class SQLParserUtilsException extends DBALException ...@@ -28,6 +30,8 @@ class SQLParserUtilsException extends DBALException
*/ */
public static function missingType($typeName) public static function missingType($typeName)
{ {
return new self(sprintf('Value for :%1$s not found in types array. Types array key should be "%1$s"', $typeName)); return new self(
sprintf('Value for :%1$s not found in types array. Types array key should be "%1$s"', $typeName)
);
} }
} }
...@@ -529,7 +529,8 @@ abstract class AbstractSchemaManager ...@@ -529,7 +529,8 @@ abstract class AbstractSchemaManager
/** /**
* Drops and creates a new foreign key. * Drops and creates a new foreign key.
* *
* @param ForeignKeyConstraint $foreignKey An associative array that defines properties of the foreign key to be created. * @param ForeignKeyConstraint $foreignKey An associative array that defines properties
* of the foreign key to be created.
* @param Table|string $table The name of the table on which the foreign key is to be created. * @param Table|string $table The name of the table on which the foreign key is to be created.
* *
* @return void * @return void
...@@ -892,7 +893,14 @@ abstract class AbstractSchemaManager ...@@ -892,7 +893,14 @@ abstract class AbstractSchemaManager
} }
if (! $defaultPrevented) { if (! $defaultPrevented) {
$index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary'], $data['flags'], $data['options']); $index = new Index(
$data['name'],
$data['columns'],
$data['unique'],
$data['primary'],
$data['flags'],
$data['options']
);
} }
if (! $index) { if (! $index) {
......
...@@ -25,8 +25,12 @@ class ColumnDiff ...@@ -25,8 +25,12 @@ class ColumnDiff
* @param string $oldColumnName * @param string $oldColumnName
* @param string[] $changedProperties * @param string[] $changedProperties
*/ */
public function __construct($oldColumnName, Column $column, array $changedProperties = [], ?Column $fromColumn = null) public function __construct(
{ $oldColumnName,
Column $column,
array $changedProperties = [],
?Column $fromColumn = null
) {
$this->oldColumnName = $oldColumnName; $this->oldColumnName = $oldColumnName;
$this->column = $column; $this->column = $column;
$this->changedProperties = $changedProperties; $this->changedProperties = $changedProperties;
......
...@@ -68,7 +68,11 @@ class Comparator ...@@ -68,7 +68,11 @@ class Comparator
if (! $fromSchema->hasTable($tableName)) { if (! $fromSchema->hasTable($tableName)) {
$diff->newTables[$tableName] = $toSchema->getTable($tableName); $diff->newTables[$tableName] = $toSchema->getTable($tableName);
} else { } else {
$tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName)); $tableDifferences = $this->diffTable(
$fromSchema->getTable($tableName),
$toSchema->getTable($tableName)
);
if ($tableDifferences !== false) { if ($tableDifferences !== false) {
$diff->changedTables[$tableName] = $tableDifferences; $diff->changedTables[$tableName] = $tableDifferences;
} }
...@@ -225,7 +229,8 @@ class Comparator ...@@ -225,7 +229,8 @@ class Comparator
continue; continue;
} }
$columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties); $columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties);
$columnDiff->fromColumn = $column; $columnDiff->fromColumn = $column;
$tableDifferences->changedColumns[$column->getName()] = $columnDiff; $tableDifferences->changedColumns[$column->getName()] = $columnDiff;
$changes++; $changes++;
...@@ -394,11 +399,17 @@ class Comparator ...@@ -394,11 +399,17 @@ class Comparator
*/ */
public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2)
{ {
if (array_map('strtolower', $key1->getUnquotedLocalColumns()) !== array_map('strtolower', $key2->getUnquotedLocalColumns())) { if (
array_map('strtolower', $key1->getUnquotedLocalColumns())
!== array_map('strtolower', $key2->getUnquotedLocalColumns())
) {
return true; return true;
} }
if (array_map('strtolower', $key1->getUnquotedForeignColumns()) !== array_map('strtolower', $key2->getUnquotedForeignColumns())) { if (
array_map('strtolower', $key1->getUnquotedForeignColumns())
!== array_map('strtolower', $key2->getUnquotedForeignColumns())
) {
return true; return true;
} }
...@@ -440,7 +451,8 @@ class Comparator ...@@ -440,7 +451,8 @@ class Comparator
$changedProperties[] = $property; $changedProperties[] = $property;
} }
// This is a very nasty hack to make comparator work with the legacy json_array type, which should be killed in v3 // This is a very nasty hack to make comparator work with the legacy json_array type,
// which should be killed in v3
if ($this->isALegacyJsonComparison($properties1['type'], $properties2['type'])) { if ($this->isALegacyJsonComparison($properties1['type'], $properties2['type'])) {
array_shift($changedProperties); array_shift($changedProperties);
...@@ -525,8 +537,8 @@ class Comparator ...@@ -525,8 +537,8 @@ class Comparator
return false; return false;
} }
return ( ! $one instanceof Types\JsonArrayType && $other instanceof Types\JsonArrayType) return (! $one instanceof Types\JsonArrayType && $other instanceof Types\JsonArrayType)
|| ( ! $other instanceof Types\JsonArrayType && $one instanceof Types\JsonArrayType); || (! $other instanceof Types\JsonArrayType && $one instanceof Types\JsonArrayType);
} }
/** /**
......
...@@ -63,8 +63,13 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint ...@@ -63,8 +63,13 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* @param string|null $name Name of the foreign key constraint. * @param string|null $name Name of the foreign key constraint.
* @param mixed[] $options Options associated with the foreign key constraint. * @param mixed[] $options Options associated with the foreign key 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) { if ($name !== null) {
$this->_setName($name); $this->_setName($name);
} }
......
...@@ -54,8 +54,14 @@ class Index extends AbstractAsset implements Constraint ...@@ -54,8 +54,14 @@ class Index extends AbstractAsset implements Constraint
* @param string[] $flags * @param string[] $flags
* @param mixed[] $options * @param mixed[] $options
*/ */
public function __construct($name, array $columns, $isUnique = false, $isPrimary = false, array $flags = [], array $options = []) public function __construct(
{ $name,
array $columns,
$isUnique = false,
$isPrimary = false,
array $flags = [],
array $options = []
) {
$isUnique = $isUnique || $isPrimary; $isUnique = $isUnique || $isPrimary;
$this->_setName($name); $this->_setName($name);
...@@ -183,7 +189,10 @@ class Index extends AbstractAsset implements Constraint ...@@ -183,7 +189,10 @@ class Index extends AbstractAsset implements Constraint
$sameColumns = true; $sameColumns = true;
for ($i = 0; $i < $numberOfColumns; $i++) { for ($i = 0; $i < $numberOfColumns; $i++) {
if (isset($columnNames[$i]) && $this->trimQuotes(strtolower($columns[$i])) === $this->trimQuotes(strtolower($columnNames[$i]))) { if (
isset($columnNames[$i])
&& $this->trimQuotes(strtolower($columns[$i])) === $this->trimQuotes(strtolower($columnNames[$i]))
) {
continue; continue;
} }
...@@ -251,7 +260,9 @@ class Index extends AbstractAsset implements Constraint ...@@ -251,7 +260,9 @@ class Index extends AbstractAsset implements Constraint
return false; return false;
} }
return $this->spansColumns($other->getColumns()) && ($this->isPrimary() || $this->isUnique()) && $this->samePartialIndex($other); return $this->spansColumns($other->getColumns())
&& ($this->isPrimary() || $this->isUnique())
&& $this->samePartialIndex($other);
} }
/** /**
...@@ -339,7 +350,11 @@ class Index extends AbstractAsset implements Constraint ...@@ -339,7 +350,11 @@ class Index extends AbstractAsset implements Constraint
*/ */
private function samePartialIndex(Index $other) private function samePartialIndex(Index $other)
{ {
if ($this->hasOption('where') && $other->hasOption('where') && $this->getOption('where') === $other->getOption('where')) { if (
$this->hasOption('where')
&& $other->hasOption('where')
&& $this->getOption('where') === $other->getOption('where')
) {
return true; return true;
} }
......
...@@ -43,7 +43,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -43,7 +43,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
*/ */
public function getSchemaNames() public function getSchemaNames()
{ {
$statement = $this->_conn->executeQuery("SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"); $statement = $this->_conn->executeQuery(
"SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"
);
return $statement->fetchAll(FetchMode::COLUMN); return $statement->fetchAll(FetchMode::COLUMN);
} }
...@@ -302,7 +304,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -302,7 +304,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
if (! isset($sequence['increment_by'], $sequence['min_value'])) { if (! isset($sequence['increment_by'], $sequence['min_value'])) {
/** @var string[] $data */ /** @var string[] $data */
$data = $this->_conn->fetchAssoc('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName)); $data = $this->_conn->fetchAssoc(
'SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName)
);
$sequence += $data; $sequence += $data;
} }
...@@ -358,7 +362,10 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -358,7 +362,10 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$jsonb = null; $jsonb = null;
$dbType = strtolower($tableColumn['type']); $dbType = strtolower($tableColumn['type']);
if (strlen($tableColumn['domain_type']) && ! $this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])) { if (
strlen($tableColumn['domain_type'])
&& ! $this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])
) {
$dbType = strtolower($tableColumn['domain_type']); $dbType = strtolower($tableColumn['domain_type']);
$tableColumn['complete_type'] = $tableColumn['domain_complete_type']; $tableColumn['complete_type'] = $tableColumn['domain_complete_type'];
} }
......
...@@ -156,20 +156,22 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -156,20 +156,22 @@ class SQLServerSchemaManager extends AbstractSchemaManager
$foreignKeys = []; $foreignKeys = [];
foreach ($tableForeignKeys as $tableForeignKey) { foreach ($tableForeignKeys as $tableForeignKey) {
if (! isset($foreignKeys[$tableForeignKey['ForeignKey']])) { $name = $tableForeignKey['ForeignKey'];
$foreignKeys[$tableForeignKey['ForeignKey']] = [
if (! isset($foreignKeys[$name])) {
$foreignKeys[$name] = [
'local_columns' => [$tableForeignKey['ColumnName']], 'local_columns' => [$tableForeignKey['ColumnName']],
'foreign_table' => $tableForeignKey['ReferenceTableName'], 'foreign_table' => $tableForeignKey['ReferenceTableName'],
'foreign_columns' => [$tableForeignKey['ReferenceColumnName']], 'foreign_columns' => [$tableForeignKey['ReferenceColumnName']],
'name' => $tableForeignKey['ForeignKey'], 'name' => $name,
'options' => [ 'options' => [
'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']), 'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']),
'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']), 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']),
], ],
]; ];
} else { } else {
$foreignKeys[$tableForeignKey['ForeignKey']]['local_columns'][] = $tableForeignKey['ColumnName']; $foreignKeys[$name]['local_columns'][] = $tableForeignKey['ColumnName'];
$foreignKeys[$tableForeignKey['ForeignKey']]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName']; $foreignKeys[$name]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName'];
} }
} }
......
...@@ -168,8 +168,8 @@ class SchemaException extends DBALException ...@@ -168,8 +168,8 @@ class SchemaException extends DBALException
return new self( return new self(
'The performed schema operation on ' . $localTable->getName() . ' requires a named foreign key, ' . 'The performed schema operation on ' . $localTable->getName() . ' requires a named foreign key, ' .
'but the given foreign key from (' . implode(', ', $foreignKey->getColumns()) . ') onto foreign table ' . 'but the given foreign key from (' . implode(', ', $foreignKey->getColumns()) . ') onto foreign table ' .
"'" . $foreignKey->getForeignTableName() . "' (" . implode(', ', $foreignKey->getForeignColumns()) . ') is currently ' . "'" . $foreignKey->getForeignTableName() . "' (" . implode(', ', $foreignKey->getForeignColumns()) . ')' .
'unnamed.' ' is currently unnamed.'
); );
} }
......
...@@ -11,6 +11,7 @@ use Doctrine\DBAL\Types\Type; ...@@ -11,6 +11,7 @@ use Doctrine\DBAL\Types\Type;
use function array_change_key_case; use function array_change_key_case;
use function array_map; use function array_map;
use function array_merge;
use function array_reverse; use function array_reverse;
use function array_values; use function array_values;
use function explode; use function explode;
...@@ -145,10 +146,13 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -145,10 +146,13 @@ class SqliteSchemaManager extends AbstractSchemaManager
} }
foreach ($tableForeignKeys as $key => $value) { foreach ($tableForeignKeys as $key => $value) {
$id = $value['id']; $id = $value['id'];
$tableForeignKeys[$key]['constraint_name'] = isset($names[$id]) && $names[$id] !== '' ? $names[$id] : $id;
$tableForeignKeys[$key]['deferrable'] = isset($deferrable[$id]) && strtolower($deferrable[$id]) === 'deferrable'; $tableForeignKeys[$key] = array_merge($tableForeignKeys[$key], [
$tableForeignKeys[$key]['deferred'] = isset($deferred[$id]) && strtolower($deferred[$id]) === 'deferred'; 'constraint_name' => isset($names[$id]) && $names[$id] !== '' ? $names[$id] : $id,
'deferrable' => isset($deferrable[$id]) && strtolower($deferrable[$id]) === 'deferrable',
'deferred' => isset($deferred[$id]) && strtolower($deferred[$id]) === 'deferred',
]);
} }
} }
...@@ -283,7 +287,10 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -283,7 +287,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
$type = $column->getType(); $type = $column->getType();
if ($type instanceof StringType || $type instanceof TextType) { if ($type instanceof StringType || $type instanceof TextType) {
$column->setPlatformOption('collation', $this->parseColumnCollationFromSQL($columnName, $createSql) ?: 'BINARY'); $column->setPlatformOption(
'collation',
$this->parseColumnCollationFromSQL($columnName, $createSql) ?: 'BINARY'
);
} }
$comment = $this->parseColumnCommentFromSQL($columnName, $createSql); $comment = $this->parseColumnCommentFromSQL($columnName, $createSql);
...@@ -459,7 +466,9 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -459,7 +466,9 @@ class SqliteSchemaManager extends AbstractSchemaManager
$tableDetails = $this->tryMethod('listTableDetails', $table); $tableDetails = $this->tryMethod('listTableDetails', $table);
if ($tableDetails === false) { if ($tableDetails === false) {
throw new DBALException(sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)); throw new DBALException(
sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)
);
} }
$table = $tableDetails; $table = $tableDetails;
...@@ -473,7 +482,8 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -473,7 +482,8 @@ class SqliteSchemaManager extends AbstractSchemaManager
private function parseColumnCollationFromSQL(string $column, string $sql): ?string private function parseColumnCollationFromSQL(string $column, string $sql): ?string
{ {
$pattern = '{(?:\W' . preg_quote($column) . '\W|\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) $pattern = '{(?:\W' . preg_quote($column) . '\W|\W'
. preg_quote($this->_platform->quoteSingleIdentifier($column))
. '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is';
if (preg_match($pattern, $sql, $match) !== 1) { if (preg_match($pattern, $sql, $match) !== 1) {
...@@ -504,8 +514,8 @@ CREATE\sTABLE # Match "CREATE TABLE" ...@@ -504,8 +514,8 @@ CREATE\sTABLE # Match "CREATE TABLE"
private function parseColumnCommentFromSQL(string $column, string $sql): ?string private function parseColumnCommentFromSQL(string $column, string $sql): ?string
{ {
$pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column) $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column))
. '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; . '\W|\W' . preg_quote($column) . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i';
if (preg_match($pattern, $sql, $match) !== 1) { if (preg_match($pattern, $sql, $match) !== 1) {
return null; return null;
......
...@@ -53,8 +53,14 @@ class Table extends AbstractAsset ...@@ -53,8 +53,14 @@ class Table extends AbstractAsset
* *
* @throws DBALException * @throws DBALException
*/ */
public function __construct($name, array $columns = [], array $indexes = [], array $fkConstraints = [], $idGeneratorType = 0, array $options = []) public function __construct(
{ $name,
array $columns = [],
array $indexes = [],
array $fkConstraints = [],
$idGeneratorType = 0,
array $options = []
) {
if (strlen($name) === 0) { if (strlen($name) === 0) {
throw DBALException::invalidTableName($name); throw DBALException::invalidTableName($name);
} }
...@@ -263,8 +269,14 @@ class Table extends AbstractAsset ...@@ -263,8 +269,14 @@ class Table extends AbstractAsset
* *
* @throws SchemaException * @throws SchemaException
*/ */
private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = [], array $options = []) private function _createIndex(
{ array $columnNames,
$indexName,
$isUnique,
$isPrimary,
array $flags = [],
array $options = []
) {
if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) { if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
throw SchemaException::indexNameInvalid($indexName); throw SchemaException::indexNameInvalid($indexName);
} }
...@@ -357,11 +369,26 @@ class Table extends AbstractAsset ...@@ -357,11 +369,26 @@ class Table extends AbstractAsset
* *
* @return self * @return self
*/ */
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = [], $constraintName = null) public function addForeignKeyConstraint(
{ $foreignTable,
$constraintName = $constraintName ?: $this->_generateIdentifierName(array_merge((array) $this->getName(), $localColumnNames), 'fk', $this->_getMaxIdentifierLength()); array $localColumnNames,
array $foreignColumnNames,
array $options = [],
$constraintName = null
) {
$constraintName = $constraintName ?: $this->_generateIdentifierName(
array_merge((array) $this->getName(), $localColumnNames),
'fk',
$this->_getMaxIdentifierLength()
);
return $this->addNamedForeignKeyConstraint($constraintName, $foreignTable, $localColumnNames, $foreignColumnNames, $options); return $this->addNamedForeignKeyConstraint(
$constraintName,
$foreignTable,
$localColumnNames,
$foreignColumnNames,
$options
);
} }
/** /**
...@@ -378,8 +405,12 @@ class Table extends AbstractAsset ...@@ -378,8 +405,12 @@ class Table extends AbstractAsset
* *
* @return self * @return self
*/ */
public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = []) public function addUnnamedForeignKeyConstraint(
{ $foreignTable,
array $localColumnNames,
array $foreignColumnNames,
array $options = []
) {
return $this->addForeignKeyConstraint($foreignTable, $localColumnNames, $foreignColumnNames, $options); return $this->addForeignKeyConstraint($foreignTable, $localColumnNames, $foreignColumnNames, $options);
} }
...@@ -398,8 +429,13 @@ class Table extends AbstractAsset ...@@ -398,8 +429,13 @@ class Table extends AbstractAsset
* *
* @throws SchemaException * @throws SchemaException
*/ */
public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = []) public function addNamedForeignKeyConstraint(
{ $name,
$foreignTable,
array $localColumnNames,
array $foreignColumnNames,
array $options = []
) {
if ($foreignTable instanceof Table) { if ($foreignTable instanceof Table) {
foreach ($foreignColumnNames as $columnName) { foreach ($foreignColumnNames as $columnName) {
if (! $foreignTable->hasColumn($columnName)) { if (! $foreignTable->hasColumn($columnName)) {
...@@ -518,14 +554,17 @@ class Table extends AbstractAsset ...@@ -518,14 +554,17 @@ class Table extends AbstractAsset
$this->_fkConstraints[$name] = $constraint; $this->_fkConstraints[$name] = $constraint;
// add an explicit index on the foreign key columns. If there is already an index that fulfils this requirements drop the request. // Add an explicit index on the foreign key columns.
// In the case of __construct calling this method during hydration from schema-details all the explicitly added indexes // If there is already an index that fulfils this requirements drop the request.
// lead to duplicates. This creates computation overhead in this case, however no duplicate indexes are ever added (based on columns). // In the case of __construct calling this method during hydration from schema-details
$indexName = $this->_generateIdentifierName( // all the explicitly added indexes lead to duplicates. This creates computation overhead in this case,
// however no duplicate indexes are ever added (based on columns).
$indexName = $this->_generateIdentifierName(
array_merge([$this->getName()], $constraint->getColumns()), array_merge([$this->getName()], $constraint->getColumns()),
'idx', 'idx',
$this->_getMaxIdentifierLength() $this->_getMaxIdentifierLength()
); );
$indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false); $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false);
foreach ($this->_indexes as $existingIndex) { foreach ($this->_indexes as $existingIndex) {
......
...@@ -71,17 +71,21 @@ class Graphviz extends AbstractVisitor ...@@ -71,17 +71,21 @@ class Graphviz extends AbstractVisitor
$label = '<<TABLE CELLSPACING="0" BORDER="1" ALIGN="LEFT">'; $label = '<<TABLE CELLSPACING="0" BORDER="1" ALIGN="LEFT">';
// The title // The title
$label .= '<TR><TD BORDER="1" COLSPAN="3" ALIGN="CENTER" BGCOLOR="#fcaf3e"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $table->getName() . '</FONT></TD></TR>'; $label .= '<TR><TD BORDER="1" COLSPAN="3" ALIGN="CENTER" BGCOLOR="#fcaf3e">'
. '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $table->getName() . '</FONT></TD></TR>';
// The attributes block // The attributes block
foreach ($table->getColumns() as $column) { foreach ($table->getColumns() as $column) {
$columnLabel = $column->getName(); $columnLabel = $column->getName();
$label .= '<TR>'; $label .= '<TR>'
$label .= '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">'; . '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">'
$label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>'; . '<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>'; . '</TD>'
$label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">'; . '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">'
. '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()) . '</FONT>'
. '</TD>'
. '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">';
$primaryKey = $table->getPrimaryKey(); $primaryKey = $table->getPrimaryKey();
......
...@@ -65,8 +65,12 @@ class PoolingShardConnection extends Connection ...@@ -65,8 +65,12 @@ class PoolingShardConnection extends Connection
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null) public function __construct(
{ array $params,
Driver $driver,
?Configuration $config = null,
?EventManager $eventManager = null
) {
if (! isset($params['global'], $params['shards'])) { if (! isset($params['global'], $params['shards'])) {
throw new InvalidArgumentException("Connection Parameters require 'global' and 'shards' configurations."); throw new InvalidArgumentException("Connection Parameters require 'global' and 'shards' configurations.");
} }
...@@ -80,14 +84,18 @@ class PoolingShardConnection extends Connection ...@@ -80,14 +84,18 @@ class PoolingShardConnection extends Connection
} }
if (! ($params['shardChoser'] instanceof ShardChoser)) { if (! ($params['shardChoser'] instanceof ShardChoser)) {
throw new InvalidArgumentException("The 'shardChoser' configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser"); throw new InvalidArgumentException(
"The 'shardChoser' configuration is not a valid instance of " . ShardChoser::class
);
} }
$this->connectionParameters[0] = array_merge($params, $params['global']); $this->connectionParameters[0] = array_merge($params, $params['global']);
foreach ($params['shards'] as $shard) { foreach ($params['shards'] as $shard) {
if (! isset($shard['id'])) { if (! isset($shard['id'])) {
throw new InvalidArgumentException("Missing 'id' for one configured shard. Please specify a unique shard-id."); throw new InvalidArgumentException(
"Missing 'id' for one configured shard. Please specify a unique shard-id."
);
} }
if (! is_numeric($shard['id']) || $shard['id'] < 1) { if (! is_numeric($shard['id']) || $shard['id'] < 1) {
...@@ -119,7 +127,9 @@ class PoolingShardConnection extends Connection ...@@ -119,7 +127,9 @@ class PoolingShardConnection extends Connection
*/ */
public function getParams() public function getParams()
{ {
return $this->activeShardId ? $this->connectionParameters[$this->activeShardId] : $this->connectionParameters[0]; return $this->activeShardId
? $this->connectionParameters[$this->activeShardId]
: $this->connectionParameters[0];
} }
/** /**
......
...@@ -62,7 +62,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer ...@@ -62,7 +62,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer
$defaultValue = $this->getFederationTypeDefaultValue(); $defaultValue = $this->getFederationTypeDefaultValue();
$sql[] = $this->getCreateFederationStatement(); $sql[] = $this->getCreateFederationStatement();
$sql[] = 'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $defaultValue . ') WITH RESET, FILTERING = OFF;'; $sql[] = 'USE FEDERATION ' . $this->shardManager->getFederationName()
. ' (' . $this->shardManager->getDistributionKey() . ' = ' . $defaultValue . ')'
. ' WITH RESET, FILTERING = OFF;';
$sql = array_merge($sql, $federationSql); $sql = array_merge($sql, $federationSql);
} }
...@@ -136,7 +138,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer ...@@ -136,7 +138,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer
} }
$sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n" . $sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n" .
'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ') WITH RESET, FILTERING = OFF;'; 'USE FEDERATION ' . $this->shardManager->getFederationName()
. ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ')'
. ' WITH RESET, FILTERING = OFF;';
$sql = array_merge($sql, $federationSql); $sql = array_merge($sql, $federationSql);
} }
...@@ -226,8 +230,10 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer ...@@ -226,8 +230,10 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer
continue; continue;
} }
$sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n" . $sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n"
'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ') WITH RESET, FILTERING = OFF;'; . 'USE FEDERATION ' . $this->shardManager->getFederationName()
. ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ')'
. ' WITH RESET, FILTERING = OFF;';
$sql = array_merge($sql, $federationSql); $sql = array_merge($sql, $federationSql);
} }
...@@ -266,7 +272,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer ...@@ -266,7 +272,9 @@ class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer
$federationType = Type::getType($this->shardManager->getDistributionType()); $federationType = Type::getType($this->shardManager->getDistributionType());
$federationTypeSql = $federationType->getSQLDeclaration([], $this->conn->getDatabasePlatform()); $federationTypeSql = $federationType->getSQLDeclaration([], $this->conn->getDatabasePlatform());
return "--Create Federation\n" . return "--Create Federation\n"
'CREATE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' ' . $federationTypeSql . ' RANGE)'; . 'CREATE FEDERATION ' . $this->shardManager->getFederationName()
. ' (' . $this->shardManager->getDistributionKey()
. ' ' . $federationTypeSql . ' RANGE)';
} }
} }
...@@ -159,7 +159,10 @@ EOT ...@@ -159,7 +159,10 @@ EOT
$keywords[] = new $class(); $keywords[] = new $class();
} }
$output->write('Checking keyword violations for <comment>' . implode(', ', $keywordLists) . '</comment>...', true); $output->write(
'Checking keyword violations for <comment>' . implode(', ', $keywordLists) . '</comment>...',
true
);
$schema = $conn->getSchemaManager()->createSchema(); $schema = $conn->getSchemaManager()->createSchema();
$visitor = new ReservedKeywordsValidator($keywords); $visitor = new ReservedKeywordsValidator($keywords);
...@@ -167,7 +170,12 @@ EOT ...@@ -167,7 +170,12 @@ EOT
$violations = $visitor->getViolations(); $violations = $visitor->getViolations();
if (count($violations) !== 0) { if (count($violations) !== 0) {
$output->write('There are <error>' . count($violations) . '</error> reserved keyword violations in your database schema:', true); $output->write(
'There are <error>' . count($violations) . '</error> reserved keyword violations'
. ' in your database schema:',
true
);
foreach ($violations as $violation) { foreach ($violations as $violation) {
$output->write(' - ' . $violation, true); $output->write(' - ' . $violation, true);
} }
......
...@@ -61,7 +61,11 @@ class DateTimeType extends Type implements PhpDateTimeMappingType ...@@ -61,7 +61,11 @@ class DateTimeType extends Type implements PhpDateTimeMappingType
} }
if (! $val) { if (! $val) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeFormatString()
);
} }
return $val; return $val;
......
...@@ -67,7 +67,11 @@ class DateTimeTzType extends Type implements PhpDateTimeMappingType ...@@ -67,7 +67,11 @@ class DateTimeTzType extends Type implements PhpDateTimeMappingType
$val = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value); $val = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value);
if (! $val) { if (! $val) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeTzFormatString()); throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeTzFormatString()
);
} }
return $val; return $val;
......
...@@ -54,7 +54,11 @@ class DateType extends Type ...@@ -54,7 +54,11 @@ class DateType extends Type
$val = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value); $val = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value);
if (! $val) { if (! $val) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateFormatString()); throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateFormatString()
);
} }
return $val; return $val;
......
...@@ -54,7 +54,11 @@ class TimeType extends Type ...@@ -54,7 +54,11 @@ class TimeType extends Type
$val = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value); $val = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value);
if (! $val) { if (! $val) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString()); throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getTimeFormatString()
);
} }
return $val; return $val;
......
...@@ -184,7 +184,12 @@ class ConnectionTest extends DbalTestCase ...@@ -184,7 +184,12 @@ class ConnectionTest extends DbalTestCase
public function testDriverExceptionIsWrapped(string $method): void public function testDriverExceptionIsWrapped(string $method): void
{ {
$this->expectException(DBALException::class); $this->expectException(DBALException::class);
$this->expectExceptionMessage("An exception occurred while executing 'MUUHAAAAHAAAA':\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\""); $this->expectExceptionMessage(<<<EOF
An exception occurred while executing 'MUUHAAAAHAAAA':
SQLSTATE[HY000]: General error: 1 near "MUUHAAAAHAAAA"
EOF
);
$connection = DriverManager::getConnection([ $connection = DriverManager::getConnection([
'driver' => 'pdo_sqlite', 'driver' => 'pdo_sqlite',
...@@ -652,7 +657,7 @@ class ConnectionTest extends DbalTestCase ...@@ -652,7 +657,7 @@ class ConnectionTest extends DbalTestCase
$conn = new Connection($params, $driverMock); $conn = new Connection($params, $driverMock);
self::assertArrayNotHasKey('pdo', $conn->getParams(), 'Connection is maintaining additional reference to the PDO connection'); self::assertArrayNotHasKey('pdo', $conn->getParams());
} }
public function testPassingExternalPDOMeansConnectionIsConnected(): void public function testPassingExternalPDOMeansConnectionIsConnected(): void
......
...@@ -26,7 +26,14 @@ class DBALExceptionTest extends DbalTestCase ...@@ -26,7 +26,14 @@ class DBALExceptionTest extends DbalTestCase
public function testDriverExceptionDuringQueryAcceptsResource(): void public function testDriverExceptionDuringQueryAcceptsResource(): void
{ {
$driver = $this->createMock(Driver::class); $driver = $this->createMock(Driver::class);
$e = DBALException::driverExceptionDuringQuery($driver, new Exception(), 'INSERT INTO file (`content`) VALUES (?)', [1 => fopen(__FILE__, 'r')]);
$e = DBALException::driverExceptionDuringQuery(
$driver,
new Exception(),
'INSERT INTO file (`content`) VALUES (?)',
[1 => fopen(__FILE__, 'r')]
);
self::assertStringContainsString('Resource', $e->getMessage()); self::assertStringContainsString('Resource', $e->getMessage());
} }
...@@ -62,7 +69,8 @@ class DBALExceptionTest extends DbalTestCase ...@@ -62,7 +69,8 @@ class DBALExceptionTest extends DbalTestCase
$exception = DBALException::invalidPlatformType(new stdClass()); $exception = DBALException::invalidPlatformType(new stdClass());
self::assertSame( self::assertSame(
"Option 'platform' must be a subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform', instance of 'stdClass' given", "Option 'platform' must be a subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform', "
. "instance of 'stdClass' given",
$exception->getMessage() $exception->getMessage()
); );
} }
...@@ -72,7 +80,8 @@ class DBALExceptionTest extends DbalTestCase ...@@ -72,7 +80,8 @@ class DBALExceptionTest extends DbalTestCase
$exception = DBALException::invalidPlatformType('some string'); $exception = DBALException::invalidPlatformType('some string');
self::assertSame( self::assertSame(
"Option 'platform' must be an object and subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform'. Got 'string'", "Option 'platform' must be an object and subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform'. "
. "Got 'string'",
$exception->getMessage() $exception->getMessage()
); );
} }
......
...@@ -45,7 +45,8 @@ class EasyConnectStringTest extends TestCase ...@@ -45,7 +45,8 @@ class EasyConnectStringTest extends TestCase
'service' => true, 'service' => true,
'servicename' => 'BILLING', 'servicename' => 'BILLING',
], ],
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=BILLING)))', '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))'
. '(CONNECT_DATA=(SERVICE_NAME=BILLING)))',
], ],
'advanced-params' => [ 'advanced-params' => [
[ [
...@@ -55,7 +56,8 @@ class EasyConnectStringTest extends TestCase ...@@ -55,7 +56,8 @@ class EasyConnectStringTest extends TestCase
'instancename' => 'SALES', 'instancename' => 'SALES',
'pooled' => true, 'pooled' => true,
], ],
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=41521))(CONNECT_DATA=(SID=XE)(INSTANCE_NAME=SALES)(SERVER=POOLED)))', '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=41521))'
. '(CONNECT_DATA=(SID=XE)(INSTANCE_NAME=SALES)(SERVER=POOLED)))',
], ],
]; ];
} }
......
...@@ -141,7 +141,9 @@ class BlobTest extends DbalFunctionalTestCase ...@@ -141,7 +141,9 @@ class BlobTest extends DbalFunctionalTestCase
$this->markTestIncomplete('The oci8 driver does not support stream resources as parameters'); $this->markTestIncomplete('The oci8 driver does not support stream resources as parameters');
} }
$stmt = $this->connection->prepare("INSERT INTO blob_table(id, clobcolumn, blobcolumn) VALUES (1, 'ignored', ?)"); $stmt = $this->connection->prepare(
"INSERT INTO blob_table(id, clobcolumn, blobcolumn) VALUES (1, 'ignored', ?)"
);
$stream = null; $stream = null;
$stmt->bindParam(1, $stream, ParameterType::LARGE_OBJECT); $stmt->bindParam(1, $stream, ParameterType::LARGE_OBJECT);
......
...@@ -63,8 +63,6 @@ class ConnectionTest extends DbalFunctionalTestCase ...@@ -63,8 +63,6 @@ class ConnectionTest extends DbalFunctionalTestCase
self::assertEquals(2, $this->connection->getTransactionNestingLevel()); self::assertEquals(2, $this->connection->getTransactionNestingLevel());
throw new Exception(); throw new Exception();
$this->connection->commit(); // never reached
} catch (Throwable $e) { } catch (Throwable $e) {
$this->connection->rollBack(); $this->connection->rollBack();
self::assertEquals(1, $this->connection->getTransactionNestingLevel()); self::assertEquals(1, $this->connection->getTransactionNestingLevel());
...@@ -136,8 +134,6 @@ class ConnectionTest extends DbalFunctionalTestCase ...@@ -136,8 +134,6 @@ class ConnectionTest extends DbalFunctionalTestCase
self::assertEquals(2, $this->connection->getTransactionNestingLevel()); self::assertEquals(2, $this->connection->getTransactionNestingLevel());
throw new Exception(); throw new Exception();
$this->connection->commit(); // never reached
} catch (Throwable $e) { } catch (Throwable $e) {
$this->connection->rollBack(); $this->connection->rollBack();
self::assertEquals(1, $this->connection->getTransactionNestingLevel()); self::assertEquals(1, $this->connection->getTransactionNestingLevel());
...@@ -147,7 +143,7 @@ class ConnectionTest extends DbalFunctionalTestCase ...@@ -147,7 +143,7 @@ class ConnectionTest extends DbalFunctionalTestCase
self::assertFalse($this->connection->isRollbackOnly()); self::assertFalse($this->connection->isRollbackOnly());
try { try {
$this->connection->setNestTransactionsWithSavepoints(false); $this->connection->setNestTransactionsWithSavepoints(false);
$this->fail('Should not be able to disable savepoints in usage for nested transactions inside an open transaction.'); $this->fail('Should not be able to disable savepoints in usage inside a nested open transaction.');
} catch (ConnectionException $e) { } catch (ConnectionException $e) {
self::assertTrue($this->connection->getNestTransactionsWithSavepoints()); self::assertTrue($this->connection->getNestTransactionsWithSavepoints());
} }
...@@ -225,8 +221,6 @@ class ConnectionTest extends DbalFunctionalTestCase ...@@ -225,8 +221,6 @@ class ConnectionTest extends DbalFunctionalTestCase
self::assertEquals(1, $this->connection->getTransactionNestingLevel()); self::assertEquals(1, $this->connection->getTransactionNestingLevel());
throw new Exception(); throw new Exception();
$this->connection->commit(); // never reached
} catch (Throwable $e) { } catch (Throwable $e) {
self::assertEquals(1, $this->connection->getTransactionNestingLevel()); self::assertEquals(1, $this->connection->getTransactionNestingLevel());
$this->connection->rollBack(); $this->connection->rollBack();
......
...@@ -57,7 +57,12 @@ class DataAccessTest extends DbalFunctionalTestCase ...@@ -57,7 +57,12 @@ class DataAccessTest extends DbalFunctionalTestCase
$sm = $this->connection->getSchemaManager(); $sm = $this->connection->getSchemaManager();
$sm->createTable($table); $sm->createTable($table);
$this->connection->insert('fetch_table', ['test_int' => 1, 'test_string' => 'foo', 'test_datetime' => '2010-01-01 10:10:10']); $this->connection->insert('fetch_table', [
'test_int' => 1,
'test_string' => 'foo',
'test_datetime' => '2010-01-01 10:10:10',
]);
self::$generated = true; self::$generated = true;
} }
...@@ -472,7 +477,11 @@ class DataAccessTest extends DbalFunctionalTestCase ...@@ -472,7 +477,11 @@ class DataAccessTest extends DbalFunctionalTestCase
public function testNativeArrayListSupport(): void public function testNativeArrayListSupport(): void
{ {
for ($i = 100; $i < 110; $i++) { for ($i = 100; $i < 110; $i++) {
$this->connection->insert('fetch_table', ['test_int' => $i, 'test_string' => 'foo' . $i, 'test_datetime' => '2010-01-01 10:10:10']); $this->connection->insert('fetch_table', [
'test_int' => $i,
'test_string' => 'foo' . $i,
'test_datetime' => '2010-01-01 10:10:10',
]);
} }
$stmt = $this->connection->executeQuery( $stmt = $this->connection->executeQuery(
...@@ -583,22 +592,22 @@ class DataAccessTest extends DbalFunctionalTestCase ...@@ -583,22 +592,22 @@ class DataAccessTest extends DbalFunctionalTestCase
$row = $this->connection->fetchAssoc($sql); $row = $this->connection->fetchAssoc($sql);
$row = array_change_key_case($row, CASE_LOWER); $row = array_change_key_case($row, CASE_LOWER);
self::assertEquals('2010-01-01 10:10:11', date('Y-m-d H:i:s', strtotime($row['add_seconds'])), 'Adding second should end up on 2010-01-01 10:10:11'); self::assertEquals('2010-01-01 10:10:11', date('Y-m-d H:i:s', strtotime($row['add_seconds'])));
self::assertEquals('2010-01-01 10:10:09', date('Y-m-d H:i:s', strtotime($row['sub_seconds'])), 'Subtracting second should end up on 2010-01-01 10:10:09'); self::assertEquals('2010-01-01 10:10:09', date('Y-m-d H:i:s', strtotime($row['sub_seconds'])));
self::assertEquals('2010-01-01 10:15:10', date('Y-m-d H:i:s', strtotime($row['add_minutes'])), 'Adding minutes should end up on 2010-01-01 10:15:10'); self::assertEquals('2010-01-01 10:15:10', date('Y-m-d H:i:s', strtotime($row['add_minutes'])));
self::assertEquals('2010-01-01 10:05:10', date('Y-m-d H:i:s', strtotime($row['sub_minutes'])), 'Subtracting minutes should end up on 2010-01-01 10:05:10'); self::assertEquals('2010-01-01 10:05:10', date('Y-m-d H:i:s', strtotime($row['sub_minutes'])));
self::assertEquals('2010-01-01 13:10', date('Y-m-d H:i', strtotime($row['add_hour'])), 'Adding date should end up on 2010-01-01 13:10'); self::assertEquals('2010-01-01 13:10', date('Y-m-d H:i', strtotime($row['add_hour'])));
self::assertEquals('2010-01-01 07:10', date('Y-m-d H:i', strtotime($row['sub_hour'])), 'Subtracting date should end up on 2010-01-01 07:10'); self::assertEquals('2010-01-01 07:10', date('Y-m-d H:i', strtotime($row['sub_hour'])));
self::assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])), 'Adding date should end up on 2010-01-11'); self::assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])));
self::assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])), 'Subtracting date should end up on 2009-12-22'); self::assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])));
self::assertEquals('2010-01-08', date('Y-m-d', strtotime($row['add_weeks'])), 'Adding week should end up on 2010-01-08'); self::assertEquals('2010-01-08', date('Y-m-d', strtotime($row['add_weeks'])));
self::assertEquals('2009-12-25', date('Y-m-d', strtotime($row['sub_weeks'])), 'Subtracting week should end up on 2009-12-25'); self::assertEquals('2009-12-25', date('Y-m-d', strtotime($row['sub_weeks'])));
self::assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])), 'Adding month should end up on 2010-03-01'); self::assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])));
self::assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), 'Subtracting month should end up on 2009-11-01'); self::assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])));
self::assertEquals('2010-10-01', date('Y-m-d', strtotime($row['add_quarters'])), 'Adding quarters should end up on 2010-04-01'); self::assertEquals('2010-10-01', date('Y-m-d', strtotime($row['add_quarters'])));
self::assertEquals('2009-04-01', date('Y-m-d', strtotime($row['sub_quarters'])), 'Subtracting quarters should end up on 2009-10-01'); self::assertEquals('2009-04-01', date('Y-m-d', strtotime($row['sub_quarters'])));
self::assertEquals('2016-01-01', date('Y-m-d', strtotime($row['add_years'])), 'Adding years should end up on 2016-01-01'); self::assertEquals('2016-01-01', date('Y-m-d', strtotime($row['add_years'])));
self::assertEquals('2004-01-01', date('Y-m-d', strtotime($row['sub_years'])), 'Subtracting years should end up on 2004-01-01'); self::assertEquals('2004-01-01', date('Y-m-d', strtotime($row['sub_years'])));
} }
public function testSqliteDateArithmeticWithDynamicInterval(): void public function testSqliteDateArithmeticWithDynamicInterval(): void
......
...@@ -31,8 +31,11 @@ class DriverTest extends AbstractDriverTest ...@@ -31,8 +31,11 @@ class DriverTest extends AbstractDriverTest
/** /**
* @dataProvider getDatabaseParameter * @dataProvider getDatabaseParameter
*/ */
public function testDatabaseParameters(?string $databaseName, ?string $defaultDatabaseName, ?string $expectedDatabaseName): void public function testDatabaseParameters(
{ ?string $databaseName,
?string $defaultDatabaseName,
?string $expectedDatabaseName
): void {
$params = $this->connection->getParams(); $params = $this->connection->getParams();
$params['dbname'] = $databaseName; $params['dbname'] = $databaseName;
$params['default_dbname'] = $defaultDatabaseName; $params['default_dbname'] = $defaultDatabaseName;
......
...@@ -65,7 +65,11 @@ class ModifyLimitQueryTest extends DbalFunctionalTestCase ...@@ -65,7 +65,11 @@ class ModifyLimitQueryTest extends DbalFunctionalTestCase
$this->connection->insert('modify_limit_table2', ['test_int' => 2]); $this->connection->insert('modify_limit_table2', ['test_int' => 2]);
$this->connection->insert('modify_limit_table2', ['test_int' => 2]); $this->connection->insert('modify_limit_table2', ['test_int' => 2]);
$sql = 'SELECT modify_limit_table.test_int FROM modify_limit_table INNER JOIN modify_limit_table2 ON modify_limit_table.test_int = modify_limit_table2.test_int ORDER BY modify_limit_table.test_int DESC'; $sql = 'SELECT modify_limit_table.test_int'
. ' FROM modify_limit_table'
. ' INNER JOIN modify_limit_table2'
. ' ON modify_limit_table.test_int = modify_limit_table2.test_int'
. ' ORDER BY modify_limit_table.test_int DESC';
$this->assertLimitResult([2, 2, 1, 1, 1], $sql, 10, 0); $this->assertLimitResult([2, 2, 1, 1, 1], $sql, 10, 0);
$this->assertLimitResult([1, 1, 1], $sql, 3, 2); $this->assertLimitResult([1, 1, 1], $sql, 3, 2);
...@@ -113,7 +117,8 @@ class ModifyLimitQueryTest extends DbalFunctionalTestCase ...@@ -113,7 +117,8 @@ class ModifyLimitQueryTest extends DbalFunctionalTestCase
$this->connection->insert('modify_limit_table', ['test_int' => 3]); $this->connection->insert('modify_limit_table', ['test_int' => 3]);
$this->connection->insert('modify_limit_table', ['test_int' => 4]); $this->connection->insert('modify_limit_table', ['test_int' => 4]);
$sql = 'SELECT modify_limit_table.*, (SELECT COUNT(*) FROM modify_limit_table) AS cnt FROM modify_limit_table ORDER BY test_int DESC'; $sql = 'SELECT modify_limit_table.*, (SELECT COUNT(*) FROM modify_limit_table) AS cnt'
. ' FROM modify_limit_table ORDER BY test_int DESC';
$this->assertLimitResult([4, 3, 2, 1], $sql, 10, 0); $this->assertLimitResult([4, 3, 2, 1], $sql, 10, 0);
$this->assertLimitResult([4, 3], $sql, 2, 0); $this->assertLimitResult([4, 3], $sql, 2, 0);
...@@ -167,8 +172,13 @@ SQL; ...@@ -167,8 +172,13 @@ SQL;
/** /**
* @param array<int, int> $expectedResults * @param array<int, int> $expectedResults
*/ */
private function assertLimitResult(array $expectedResults, string $sql, ?int $limit, int $offset, bool $deterministic = true): void private function assertLimitResult(
{ array $expectedResults,
string $sql,
?int $limit,
int $offset,
bool $deterministic = true
): void {
$p = $this->connection->getDatabasePlatform(); $p = $this->connection->getDatabasePlatform();
$data = []; $data = [];
foreach ($this->connection->fetchAll($p->modifyLimitQuery($sql, $limit, $offset)) as $row) { foreach ($this->connection->fetchAll($p->modifyLimitQuery($sql, $limit, $offset)) as $row) {
......
...@@ -38,7 +38,11 @@ class PortabilityTest extends DbalFunctionalTestCase ...@@ -38,7 +38,11 @@ class PortabilityTest extends DbalFunctionalTestCase
$params['portability'] = $portabilityMode; $params['portability'] = $portabilityMode;
$params['fetch_case'] = $case; $params['fetch_case'] = $case;
$this->portableConnection = DriverManager::getConnection($params, $this->connection->getConfiguration(), $this->connection->getEventManager()); $this->portableConnection = DriverManager::getConnection(
$params,
$this->connection->getConfiguration(),
$this->connection->getEventManager()
);
try { try {
$table = new Table('portability_table'); $table = new Table('portability_table');
...@@ -50,8 +54,17 @@ class PortabilityTest extends DbalFunctionalTestCase ...@@ -50,8 +54,17 @@ class PortabilityTest extends DbalFunctionalTestCase
$sm = $this->portableConnection->getSchemaManager(); $sm = $this->portableConnection->getSchemaManager();
$sm->createTable($table); $sm->createTable($table);
$this->portableConnection->insert('portability_table', ['Test_Int' => 1, 'Test_String' => 'foo', 'Test_Null' => '']); $this->portableConnection->insert('portability_table', [
$this->portableConnection->insert('portability_table', ['Test_Int' => 2, 'Test_String' => 'foo ', 'Test_Null' => null]); 'Test_Int' => 1,
'Test_String' => 'foo',
'Test_Null' => '',
]);
$this->portableConnection->insert('portability_table', [
'Test_Int' => 2,
'Test_String' => 'foo ',
'Test_Null' => null,
]);
} catch (Throwable $e) { } catch (Throwable $e) {
} }
} }
...@@ -128,7 +141,7 @@ class PortabilityTest extends DbalFunctionalTestCase ...@@ -128,7 +141,7 @@ class PortabilityTest extends DbalFunctionalTestCase
{ {
self::assertContains($row['test_int'], [1, 2], 'Primary key test_int should either be 1 or 2.'); self::assertContains($row['test_int'], [1, 2], 'Primary key test_int should either be 1 or 2.');
self::assertArrayHasKey('test_string', $row, 'Case should be lowered.'); self::assertArrayHasKey('test_string', $row, 'Case should be lowered.');
self::assertEquals(3, strlen($row['test_string']), 'test_string should be rtrimed to length of three for CHAR(32) column.'); self::assertEquals(3, strlen($row['test_string']));
self::assertNull($row['test_null']); self::assertNull($row['test_null']);
self::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.'); self::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.');
} }
......
...@@ -21,7 +21,11 @@ use const CASE_LOWER; ...@@ -21,7 +21,11 @@ use const CASE_LOWER;
class ResultCacheTest extends DbalFunctionalTestCase class ResultCacheTest extends DbalFunctionalTestCase
{ {
/** @var list<array{test_int: int, test_string: string}> */ /** @var list<array{test_int: int, test_string: string}> */
private $expectedResult = [['test_int' => 100, 'test_string' => 'foo'], ['test_int' => 200, 'test_string' => 'bar'], ['test_int' => 300, 'test_string' => 'baz']]; private $expectedResult = [
['test_int' => 100, 'test_string' => 'foo'],
['test_int' => 200, 'test_string' => 'bar'],
['test_int' => 300, 'test_string' => 'baz'],
];
/** @var DebugStack */ /** @var DebugStack */
private $sqlLogger; private $sqlLogger;
...@@ -101,13 +105,23 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -101,13 +105,23 @@ class ResultCacheTest extends DbalFunctionalTestCase
$numExpectedResult[] = array_values($v); $numExpectedResult[] = array_values($v);
} }
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$data = $this->hydrateStmt($stmt, FetchMode::ASSOCIATIVE); $data = $this->hydrateStmt($stmt, FetchMode::ASSOCIATIVE);
self::assertEquals($this->expectedResult, $data); self::assertEquals($this->expectedResult, $data);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$data = $this->hydrateStmt($stmt, FetchMode::NUMERIC); $data = $this->hydrateStmt($stmt, FetchMode::NUMERIC);
...@@ -123,10 +137,22 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -123,10 +137,22 @@ class ResultCacheTest extends DbalFunctionalTestCase
private function assertStandardAndIteratorFetchAreEqual(int $fetchMode): void private function assertStandardAndIteratorFetchAreEqual(int $fetchMode): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$data = $this->hydrateStmt($stmt, $fetchMode); $data = $this->hydrateStmt($stmt, $fetchMode);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$dataIterator = $this->hydrateStmtIterator($stmt, $fetchMode); $dataIterator = $this->hydrateStmtIterator($stmt, $fetchMode);
self::assertEquals($data, $dataIterator); self::assertEquals($data, $dataIterator);
...@@ -134,7 +160,12 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -134,7 +160,12 @@ class ResultCacheTest extends DbalFunctionalTestCase
public function testDontCloseNoCache(): void public function testDontCloseNoCache(): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$data = []; $data = [];
...@@ -142,7 +173,12 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -142,7 +173,12 @@ class ResultCacheTest extends DbalFunctionalTestCase
$data[] = $row; $data[] = $row;
} }
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$data = []; $data = [];
...@@ -155,12 +191,22 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -155,12 +191,22 @@ class ResultCacheTest extends DbalFunctionalTestCase
public function testDontFinishNoCache(): void public function testDontFinishNoCache(): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$stmt->fetch(FetchMode::ASSOCIATIVE); $stmt->fetch(FetchMode::ASSOCIATIVE);
$stmt->closeCursor(); $stmt->closeCursor();
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
$this->hydrateStmt($stmt, FetchMode::NUMERIC); $this->hydrateStmt($stmt, FetchMode::NUMERIC);
...@@ -170,7 +216,14 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -170,7 +216,14 @@ class ResultCacheTest extends DbalFunctionalTestCase
public function testFetchAllAndFinishSavesCache(): void public function testFetchAllAndFinishSavesCache(): void
{ {
$layerCache = new ArrayCache(); $layerCache = new ArrayCache();
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(10, 'testcachekey', $layerCache));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'testcachekey', $layerCache)
);
$stmt->fetchAll(); $stmt->fetchAll();
$stmt->closeCursor(); $stmt->closeCursor();
...@@ -198,13 +251,23 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -198,13 +251,23 @@ class ResultCacheTest extends DbalFunctionalTestCase
*/ */
private function assertCacheNonCacheSelectSameFetchModeAreEqual(array $expectedResult, int $fetchMode): void private function assertCacheNonCacheSelectSameFetchModeAreEqual(array $expectedResult, int $fetchMode): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
self::assertEquals(2, $stmt->columnCount()); self::assertEquals(2, $stmt->columnCount());
$data = $this->hydrateStmt($stmt, $fetchMode); $data = $this->hydrateStmt($stmt, $fetchMode);
self::assertEquals($expectedResult, $data); self::assertEquals($expectedResult, $data);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(10, 'testcachekey')); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(10, 'testcachekey')
);
self::assertEquals(2, $stmt->columnCount()); self::assertEquals(2, $stmt->columnCount());
$data = $this->hydrateStmt($stmt, $fetchMode); $data = $this->hydrateStmt($stmt, $fetchMode);
...@@ -214,23 +277,48 @@ class ResultCacheTest extends DbalFunctionalTestCase ...@@ -214,23 +277,48 @@ class ResultCacheTest extends DbalFunctionalTestCase
public function testEmptyResultCache(): void public function testEmptyResultCache(): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(10, 'emptycachekey')); $stmt = $this->connection->executeQuery(
$data = $this->hydrateStmt($stmt); 'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$this->hydrateStmt($stmt);
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(10, 'emptycachekey')); $this->hydrateStmt($stmt);
$data = $this->hydrateStmt($stmt);
self::assertCount(1, $this->sqlLogger->queries, 'just one dbal hit'); self::assertCount(1, $this->sqlLogger->queries, 'just one dbal hit');
} }
public function testChangeCacheImpl(): void public function testChangeCacheImpl(): void
{ {
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(10, 'emptycachekey')); $stmt = $this->connection->executeQuery(
$data = $this->hydrateStmt($stmt); 'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$this->hydrateStmt($stmt);
$secondCache = new ArrayCache(); $secondCache = new ArrayCache();
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(10, 'emptycachekey', $secondCache));
$data = $this->hydrateStmt($stmt); $stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey', $secondCache)
);
$this->hydrateStmt($stmt);
self::assertCount(2, $this->sqlLogger->queries, 'two hits'); self::assertCount(2, $this->sqlLogger->queries, 'two hits');
self::assertCount(1, $secondCache->fetch('emptycachekey')); self::assertCount(1, $secondCache->fetch('emptycachekey'));
......
...@@ -246,7 +246,10 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -246,7 +246,10 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
public function testColumnCharsetChange(): void public function testColumnCharsetChange(): void
{ {
$table = new Table('test_column_charset_change'); $table = new Table('test_column_charset_change');
$table->addColumn('col_string', 'string')->setLength(100)->setNotnull(true)->setPlatformOption('charset', 'utf8'); $table->addColumn('col_string', 'string')
->setLength(100)
->setNotnull(true)
->setPlatformOption('charset', 'utf8');
$diffTable = clone $table; $diffTable = clone $table;
$diffTable->getColumn('col_string')->setPlatformOption('charset', 'ascii'); $diffTable->getColumn('col_string')->setPlatformOption('charset', 'ascii');
...@@ -255,7 +258,11 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -255,7 +258,11 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$toSchema = new Schema([$diffTable]); $toSchema = new Schema([$diffTable]);
$diff = $fromSchema->getMigrateToSql($toSchema, $this->connection->getDatabasePlatform()); $diff = $fromSchema->getMigrateToSql($toSchema, $this->connection->getDatabasePlatform());
self::assertContains('ALTER TABLE test_column_charset_change CHANGE col_string col_string VARCHAR(100) CHARACTER SET ascii NOT NULL', $diff); self::assertContains(
'ALTER TABLE test_column_charset_change CHANGE col_string'
. ' col_string VARCHAR(100) CHARACTER SET ascii NOT NULL',
$diff
);
} }
public function testColumnCollation(): void public function testColumnCollation(): void
......
...@@ -243,7 +243,10 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -243,7 +243,10 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
// Adding a primary key on already indexed columns // Adding a primary key on already indexed columns
// Oracle will reuse the unique index, which cause a constraint name differing from the index name // Oracle will reuse the unique index, which cause a constraint name differing from the index name
$this->schemaManager->createConstraint(new Schema\Index('id_pk_id_index', ['id'], true, true), 'list_table_indexes_pk_id_test'); $this->schemaManager->createConstraint(
new Schema\Index('id_pk_id_index', ['id'], true, true),
'list_table_indexes_pk_id_test'
);
$tableIndexes = $this->schemaManager->listTableIndexes('list_table_indexes_pk_id_test'); $tableIndexes = $this->schemaManager->listTableIndexes('list_table_indexes_pk_id_test');
...@@ -271,6 +274,8 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -271,6 +274,8 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
public function testCreateAndListSequences(): void public function testCreateAndListSequences(): void
{ {
self::markTestSkipped("Skipped for uppercase letters are contained in sequences' names. Fix the schema manager in 3.0."); self::markTestSkipped(
"Skipped for uppercase letters are contained in sequences' names. Fix the schema manager in 3.0."
);
} }
} }
...@@ -118,12 +118,15 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -118,12 +118,15 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertTrue($tableFrom->getColumn('id')->getAutoincrement()); self::assertTrue($tableFrom->getColumn('id')->getAutoincrement());
$tableTo = new Table('autoinc_table_drop'); $tableTo = new Table('autoinc_table_drop');
$column = $tableTo->addColumn('id', 'integer'); $tableTo->addColumn('id', 'integer');
$c = new Comparator(); $c = new Comparator();
$diff = $c->diffTable($tableFrom, $tableTo); $diff = $c->diffTable($tableFrom, $tableTo);
self::assertInstanceOf(TableDiff::class, $diff, 'There should be a difference and not false being returned from the table comparison'); self::assertInstanceOf(TableDiff::class, $diff);
self::assertEquals(['ALTER TABLE autoinc_table_drop ALTER id DROP DEFAULT'], $this->connection->getDatabasePlatform()->getAlterTableSQL($diff)); self::assertEquals(
['ALTER TABLE autoinc_table_drop ALTER id DROP DEFAULT'],
$this->connection->getDatabasePlatform()->getAlterTableSQL($diff)
);
$this->schemaManager->alterTable($diff); $this->schemaManager->alterTable($diff);
$tableFinal = $this->schemaManager->listTableDetails('autoinc_table_drop'); $tableFinal = $this->schemaManager->listTableDetails('autoinc_table_drop');
...@@ -163,10 +166,12 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -163,10 +166,12 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
public function testReturnQuotedAssets(): void public function testReturnQuotedAssets(): void
{ {
$sql = 'create table dbal91_something ( id integer CONSTRAINT id_something PRIMARY KEY NOT NULL ,"table" integer );'; $sql = 'create table dbal91_something'
. ' (id integer CONSTRAINT id_something PRIMARY KEY NOT NULL, "table" integer)';
$this->connection->exec($sql); $this->connection->exec($sql);
$sql = 'ALTER TABLE dbal91_something ADD CONSTRAINT something_input FOREIGN KEY( "table" ) REFERENCES dbal91_something ON UPDATE CASCADE;'; $sql = 'ALTER TABLE dbal91_something ADD CONSTRAINT something_input'
. ' FOREIGN KEY( "table" ) REFERENCES dbal91_something ON UPDATE CASCADE;';
$this->connection->exec($sql); $this->connection->exec($sql);
$table = $this->schemaManager->listTableDetails('dbal91_something'); $table = $this->schemaManager->listTableDetails('dbal91_something');
...@@ -226,13 +231,14 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -226,13 +231,14 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
} }
$fkeys = $this->schemaManager->listTableForeignKeys('test_create_fk1'); $fkeys = $this->schemaManager->listTableForeignKeys('test_create_fk1');
self::assertEquals(count($foreignKeys), count($fkeys), "Table 'test_create_fk1' has to have " . count($foreignKeys) . ' foreign keys.'); self::assertEquals(count($foreignKeys), count($fkeys));
for ($i = 0; $i < count($fkeys); $i++) { for ($i = 0; $i < count($fkeys); $i++) {
self::assertEquals(['foreign_key_test' . $i], array_map('strtolower', $fkeys[$i]->getLocalColumns())); self::assertEquals(['foreign_key_test' . $i], array_map('strtolower', $fkeys[$i]->getLocalColumns()));
self::assertEquals(['id'], array_map('strtolower', $fkeys[$i]->getForeignColumns())); self::assertEquals(['id'], array_map('strtolower', $fkeys[$i]->getForeignColumns()));
self::assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName())); self::assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName()));
if ($foreignKeys[$i]->getOption('onDelete') === 'NO ACTION') { if ($foreignKeys[$i]->getOption('onDelete') === 'NO ACTION') {
self::assertFalse($fkeys[$i]->hasOption('onDelete'), 'Unexpected option: ' . $fkeys[$i]->getOption('onDelete')); self::assertFalse($fkeys[$i]->hasOption('onDelete'));
} else { } else {
self::assertEquals($foreignKeys[$i]->getOption('onDelete'), $fkeys[$i]->getOption('onDelete')); self::assertEquals($foreignKeys[$i]->getOption('onDelete'), $fkeys[$i]->getOption('onDelete'));
} }
...@@ -483,8 +489,11 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -483,8 +489,11 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$c = new Comparator(); $c = new Comparator();
$diff = $c->diffTable($tableFrom, $tableTo); $diff = $c->diffTable($tableFrom, $tableTo);
self::assertInstanceOf(TableDiff::class, $diff, 'There should be a difference and not false being returned from the table comparison'); self::assertInstanceOf(TableDiff::class, $diff);
self::assertSame(['ALTER TABLE autoinc_type_modification ALTER id TYPE ' . $expected], $this->connection->getDatabasePlatform()->getAlterTableSQL($diff)); self::assertSame(
['ALTER TABLE autoinc_type_modification ALTER id TYPE ' . $expected],
$this->connection->getDatabasePlatform()->getAlterTableSQL($diff)
);
$this->schemaManager->alterTable($diff); $this->schemaManager->alterTable($diff);
$tableFinal = $this->schemaManager->listTableDetails('autoinc_type_modification'); $tableFinal = $this->schemaManager->listTableDetails('autoinc_type_modification');
......
...@@ -40,7 +40,8 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -40,7 +40,8 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->dropAndCreateTable($table); $this->schemaManager->dropAndCreateTable($table);
$columns = $this->schemaManager->listTableColumns($tableName); $columns = $this->schemaManager->listTableColumns($tableName);
self::assertTrue($columns[$columnName]->hasPlatformOption('collation')); // SQL Server should report a default collation on the column // SQL Server should report a default collation on the column
self::assertTrue($columns[$columnName]->hasPlatformOption('collation'));
$column->setPlatformOption('collation', $collation = 'Icelandic_CS_AS'); $column->setPlatformOption('collation', $collation = 'Icelandic_CS_AS');
...@@ -89,9 +90,15 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -89,9 +90,15 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
), ),
'df_string_3' => new ColumnDiff( 'df_string_3' => new ColumnDiff(
'df_string_3', 'df_string_3',
new Column('df_string_3', Type::getType('string'), ['length' => 50, 'default' => 'another default value']), new Column('df_string_3', Type::getType('string'), [
'length' => 50,
'default' => 'another default value',
]),
['length'], ['length'],
new Column('df_string_3', Type::getType('string'), ['length' => 50, 'default' => 'another default value']) new Column('df_string_3', Type::getType('string'), [
'length' => 50,
'default' => 'another default value',
])
), ),
'df_boolean' => new ColumnDiff( 'df_boolean' => new ColumnDiff(
'df_boolean', 'df_boolean',
...@@ -163,7 +170,11 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -163,7 +170,11 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
$table->addColumn('comment_float_0', 'integer', ['comment' => 0.0]); $table->addColumn('comment_float_0', 'integer', ['comment' => 0.0]);
$table->addColumn('comment_string_0', 'integer', ['comment' => '0']); $table->addColumn('comment_string_0', 'integer', ['comment' => '0']);
$table->addColumn('comment', 'integer', ['comment' => 'Doctrine 0wnz you!']); $table->addColumn('comment', 'integer', ['comment' => 'Doctrine 0wnz you!']);
$table->addColumn('`comment_quoted`', 'integer', ['comment' => 'Doctrine 0wnz comments for explicitly quoted columns!']); $table->addColumn(
'`comment_quoted`',
'integer',
['comment' => 'Doctrine 0wnz comments for explicitly quoted columns!']
);
$table->addColumn('create', 'integer', ['comment' => 'Doctrine 0wnz comments for reserved keyword columns!']); $table->addColumn('create', 'integer', ['comment' => 'Doctrine 0wnz comments for reserved keyword columns!']);
$table->addColumn('commented_type', 'object'); $table->addColumn('commented_type', 'object');
$table->addColumn('commented_type_with_comment', 'array', ['comment' => 'Doctrine array type.']); $table->addColumn('commented_type_with_comment', 'array', ['comment' => 'Doctrine array type.']);
...@@ -181,27 +192,55 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -181,27 +192,55 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertEquals('0', $columns['comment_float_0']->getComment()); self::assertEquals('0', $columns['comment_float_0']->getComment());
self::assertEquals('0', $columns['comment_string_0']->getComment()); self::assertEquals('0', $columns['comment_string_0']->getComment());
self::assertEquals('Doctrine 0wnz you!', $columns['comment']->getComment()); self::assertEquals('Doctrine 0wnz you!', $columns['comment']->getComment());
self::assertEquals('Doctrine 0wnz comments for explicitly quoted columns!', $columns['comment_quoted']->getComment()); self::assertEquals(
'Doctrine 0wnz comments for explicitly quoted columns!',
$columns['comment_quoted']->getComment()
);
self::assertEquals('Doctrine 0wnz comments for reserved keyword columns!', $columns['[create]']->getComment()); self::assertEquals('Doctrine 0wnz comments for reserved keyword columns!', $columns['[create]']->getComment());
self::assertNull($columns['commented_type']->getComment()); self::assertNull($columns['commented_type']->getComment());
self::assertEquals('Doctrine array type.', $columns['commented_type_with_comment']->getComment()); self::assertEquals('Doctrine array type.', $columns['commented_type_with_comment']->getComment());
$tableDiff = new TableDiff('sqlsrv_column_comment'); $tableDiff = new TableDiff('sqlsrv_column_comment');
$tableDiff->fromTable = $table; $tableDiff->fromTable = $table;
$tableDiff->addedColumns['added_comment_none'] = new Column('added_comment_none', Type::getType('integer'));
$tableDiff->addedColumns['added_comment_null'] = new Column('added_comment_null', Type::getType('integer'), ['comment' => null]); $tableDiff->addedColumns['added_comment_none']
$tableDiff->addedColumns['added_comment_false'] = new Column('added_comment_false', Type::getType('integer'), ['comment' => false]); = new Column('added_comment_none', Type::getType('integer'));
$tableDiff->addedColumns['added_comment_empty_string'] = new Column('added_comment_empty_string', Type::getType('integer'), ['comment' => '']);
$tableDiff->addedColumns['added_comment_integer_0'] = new Column('added_comment_integer_0', Type::getType('integer'), ['comment' => 0]); $tableDiff->addedColumns['added_comment_null']
$tableDiff->addedColumns['added_comment_float_0'] = new Column('added_comment_float_0', Type::getType('integer'), ['comment' => 0.0]); = new Column('added_comment_null', Type::getType('integer'), ['comment' => null]);
$tableDiff->addedColumns['added_comment_string_0'] = new Column('added_comment_string_0', Type::getType('integer'), ['comment' => '0']);
$tableDiff->addedColumns['added_comment'] = new Column('added_comment', Type::getType('integer'), ['comment' => 'Doctrine']); $tableDiff->addedColumns['added_comment_false']
$tableDiff->addedColumns['`added_comment_quoted`'] = new Column('`added_comment_quoted`', Type::getType('integer'), ['comment' => 'rulez']); = new Column('added_comment_false', Type::getType('integer'), ['comment' => false]);
$tableDiff->addedColumns['select'] = new Column('select', Type::getType('integer'), ['comment' => '666']);
$tableDiff->addedColumns['added_commented_type'] = new Column('added_commented_type', Type::getType('object')); $tableDiff->addedColumns['added_comment_empty_string']
$tableDiff->addedColumns['added_commented_type_with_comment'] = new Column('added_commented_type_with_comment', Type::getType('array'), ['comment' => '666']); = new Column('added_comment_empty_string', Type::getType('integer'), ['comment' => '']);
$tableDiff->renamedColumns['comment_float_0'] = new Column('comment_double_0', Type::getType('decimal'), ['comment' => 'Double for real!']); $tableDiff->addedColumns['added_comment_integer_0']
= new Column('added_comment_integer_0', Type::getType('integer'), ['comment' => 0]);
$tableDiff->addedColumns['added_comment_float_0']
= new Column('added_comment_float_0', Type::getType('integer'), ['comment' => 0.0]);
$tableDiff->addedColumns['added_comment_string_0']
= new Column('added_comment_string_0', Type::getType('integer'), ['comment' => '0']);
$tableDiff->addedColumns['added_comment']
= new Column('added_comment', Type::getType('integer'), ['comment' => 'Doctrine']);
$tableDiff->addedColumns['`added_comment_quoted`']
= new Column('`added_comment_quoted`', Type::getType('integer'), ['comment' => 'rulez']);
$tableDiff->addedColumns['select']
= new Column('select', Type::getType('integer'), ['comment' => '666']);
$tableDiff->addedColumns['added_commented_type']
= new Column('added_commented_type', Type::getType('object'));
$tableDiff->addedColumns['added_commented_type_with_comment']
= new Column('added_commented_type_with_comment', Type::getType('array'), ['comment' => '666']);
$tableDiff->renamedColumns['comment_float_0']
= new Column('comment_double_0', Type::getType('decimal'), ['comment' => 'Double for real!']);
// Add comment to non-commented column. // Add comment to non-commented column.
$tableDiff->changedColumns['id'] = new ColumnDiff( $tableDiff->changedColumns['id'] = new ColumnDiff(
...@@ -264,7 +303,11 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -264,7 +303,11 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
'create', 'create',
new Column('create', Type::getType('object')), new Column('create', Type::getType('object')),
['comment', 'type'], ['comment', 'type'],
new Column('create', Type::getType('integer'), ['comment' => 'Doctrine 0wnz comments for reserved keyword columns!']) new Column(
'create',
Type::getType('integer'),
['comment' => 'Doctrine 0wnz comments for reserved keyword columns!']
)
); );
// Add comment and change custom type to regular type from non-commented column. // Add comment and change custom type to regular type from non-commented column.
...@@ -283,7 +326,8 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -283,7 +326,8 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
new Column('commented_type_with_comment', Type::getType('array'), ['comment' => 'Doctrine array type.']) new Column('commented_type_with_comment', Type::getType('array'), ['comment' => 'Doctrine array type.'])
); );
$tableDiff->removedColumns['comment_integer_0'] = new Column('comment_integer_0', Type::getType('integer'), ['comment' => 0]); $tableDiff->removedColumns['comment_integer_0']
= new Column('comment_integer_0', Type::getType('integer'), ['comment' => 0]);
$this->schemaManager->alterTable($tableDiff); $this->schemaManager->alterTable($tableDiff);
......
...@@ -177,7 +177,8 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -177,7 +177,8 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$foundSequence = null; $foundSequence = null;
foreach ($sequences as $sequence) { foreach ($sequences as $sequence) {
self::assertInstanceOf(Sequence::class, $sequence, 'Array elements of listSequences() should be Sequence instances.'); self::assertInstanceOf(Sequence::class, $sequence);
if (strtolower($sequence->getName()) !== 'list_sequences_test_seq') { if (strtolower($sequence->getName()) !== 'list_sequences_test_seq') {
continue; continue;
} }
...@@ -215,7 +216,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -215,7 +216,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$namespaces = array_map('strtolower', $namespaces); $namespaces = array_map('strtolower', $namespaces);
if (! in_array('test_create_schema', $namespaces)) { if (! in_array('test_create_schema', $namespaces)) {
$this->connection->executeUpdate($this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema')); $this->connection->executeUpdate(
$this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema')
);
$namespaces = $this->schemaManager->listNamespaceNames(); $namespaces = $this->schemaManager->listNamespaceNames();
$namespaces = array_map('strtolower', $namespaces); $namespaces = array_map('strtolower', $namespaces);
...@@ -403,7 +406,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -403,7 +406,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
public function testDiffListTableColumns(): void public function testDiffListTableColumns(): void
{ {
if ($this->schemaManager->getDatabasePlatform()->getName() === 'oracle') { if ($this->schemaManager->getDatabasePlatform()->getName() === 'oracle') {
$this->markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).'); $this->markTestSkipped(
'Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).'
);
} }
$offlineTable = $this->createListTableColumns(); $offlineTable = $this->createListTableColumns();
...@@ -485,7 +490,7 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -485,7 +490,7 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
self::assertEquals(['foreign_key_test'], array_map('strtolower', $fkConstraint->getColumns())); self::assertEquals(['foreign_key_test'], array_map('strtolower', $fkConstraint->getColumns()));
self::assertEquals(['id'], array_map('strtolower', $fkConstraint->getForeignColumns())); self::assertEquals(['id'], array_map('strtolower', $fkConstraint->getForeignColumns()));
self::assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()), 'The columns of a foreign key constraint should always be indexed.'); self::assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()));
} }
public function testListForeignKeys(): void public function testListForeignKeys(): void
...@@ -585,7 +590,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -585,7 +590,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$table = $this->schemaManager->listTableDetails('alter_table'); $table = $this->schemaManager->listTableDetails('alter_table');
self::assertEquals(2, count($table->getIndexes())); self::assertEquals(2, count($table->getIndexes()));
self::assertTrue($table->hasIndex('foo_idx')); self::assertTrue($table->hasIndex('foo_idx'));
self::assertEquals(['foo', 'foreign_key_test'], array_map('strtolower', $table->getIndex('foo_idx')->getColumns())); self::assertEquals(
['foo', 'foreign_key_test'],
array_map('strtolower', $table->getIndex('foo_idx')->getColumns())
);
$tableDiff = new TableDiff('alter_table'); $tableDiff = new TableDiff('alter_table');
$tableDiff->fromTable = $table; $tableDiff->fromTable = $table;
...@@ -597,7 +605,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -597,7 +605,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
self::assertEquals(2, count($table->getIndexes())); self::assertEquals(2, count($table->getIndexes()));
self::assertTrue($table->hasIndex('bar_idx')); self::assertTrue($table->hasIndex('bar_idx'));
self::assertFalse($table->hasIndex('foo_idx')); self::assertFalse($table->hasIndex('foo_idx'));
self::assertEquals(['foo', 'foreign_key_test'], array_map('strtolower', $table->getIndex('bar_idx')->getColumns())); self::assertEquals(
['foo', 'foreign_key_test'],
array_map('strtolower', $table->getIndex('bar_idx')->getColumns())
);
self::assertFalse($table->getIndex('bar_idx')->isPrimary()); self::assertFalse($table->getIndex('bar_idx')->isPrimary());
self::assertFalse($table->getIndex('bar_idx')->isUnique()); self::assertFalse($table->getIndex('bar_idx')->isUnique());
...@@ -848,10 +859,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -848,10 +859,10 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$columns = $this->schemaManager->listTableColumns('column_comment_test2'); $columns = $this->schemaManager->listTableColumns('column_comment_test2');
self::assertEquals(3, count($columns)); self::assertEquals(3, count($columns));
self::assertEquals('This is a comment', $columns['id']->getComment()); self::assertEquals('This is a comment', $columns['id']->getComment());
self::assertEquals('This is a comment', $columns['obj']->getComment(), 'The Doctrine2 Typehint should be stripped from comment.'); self::assertEquals('This is a comment', $columns['obj']->getComment());
self::assertInstanceOf(ObjectType::class, $columns['obj']->getType(), 'The Doctrine2 should be detected from comment hint.'); self::assertInstanceOf(ObjectType::class, $columns['obj']->getType());
self::assertEquals('This is a comment', $columns['arr']->getComment(), 'The Doctrine2 Typehint should be stripped from comment.'); self::assertEquals('This is a comment', $columns['arr']->getComment());
self::assertInstanceOf(ArrayType::class, $columns['arr']->getType(), 'The Doctrine2 should be detected from comment hint.'); self::assertInstanceOf(ArrayType::class, $columns['arr']->getType());
} }
public function testCommentHintOnDateIntervalTypeColumn(): void public function testCommentHintOnDateIntervalTypeColumn(): void
...@@ -874,8 +885,8 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -874,8 +885,8 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$columns = $this->schemaManager->listTableColumns('column_dateinterval_comment'); $columns = $this->schemaManager->listTableColumns('column_dateinterval_comment');
self::assertEquals(2, count($columns)); self::assertEquals(2, count($columns));
self::assertEquals('This is a comment', $columns['id']->getComment()); self::assertEquals('This is a comment', $columns['id']->getComment());
self::assertEquals('This is a comment', $columns['date_interval']->getComment(), 'The Doctrine2 Typehint should be stripped from comment.'); self::assertEquals('This is a comment', $columns['date_interval']->getComment());
self::assertInstanceOf(DateIntervalType::class, $columns['date_interval']->getType(), 'The Doctrine2 should be detected from comment hint.'); self::assertInstanceOf(DateIntervalType::class, $columns['date_interval']->getType());
} }
public function testChangeColumnsTypeWithDefaultValue(): void public function testChangeColumnsTypeWithDefaultValue(): void
...@@ -1155,16 +1166,24 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -1155,16 +1166,24 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$this->markTestSkipped('Database does not support column comments.'); $this->markTestSkipped('Database does not support column comments.');
} }
$options = [ $options = [
'type' => Type::getType('integer'), 'type' => Type::getType('integer'),
'default' => 0, 'default' => 0,
'notnull' => true, 'notnull' => true,
'comment' => 'expected+column+comment', 'comment' => 'expected+column+comment',
]; ];
$columnDefinition = substr($this->connection->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
$columnDefinition = substr(
$this->connection->getDatabasePlatform()->getColumnDeclarationSQL('id', $options),
strlen('id') + 1
);
$table = new Table('my_table'); $table = new Table('my_table');
$table->addColumn('id', 'integer', ['columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment']); $table->addColumn('id', 'integer', [
'columnDefinition' => $columnDefinition,
'comment' => 'unexpected_column_comment',
]);
$sql = $this->connection->getDatabasePlatform()->getCreateTableSQL($table); $sql = $this->connection->getDatabasePlatform()->getCreateTableSQL($table);
self::assertStringContainsString('expected+column+comment', $sql[0]); self::assertStringContainsString('expected+column+comment', $sql[0]);
...@@ -1356,7 +1375,7 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -1356,7 +1375,7 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties); self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
} }
public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport(): void public function testComparatorReturnsAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport(): void
{ {
if (! $this->schemaManager->getDatabasePlatform()->hasNativeJsonType()) { if (! $this->schemaManager->getDatabasePlatform()->hasNativeJsonType()) {
$this->markTestSkipped('This test is only supported on platforms that have native JSON type.'); $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
...@@ -1512,7 +1531,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -1512,7 +1531,9 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
public function testGenerateAnIndexWithPartialColumnLength(): void public function testGenerateAnIndexWithPartialColumnLength(): void
{ {
if (! $this->schemaManager->getDatabasePlatform()->supportsColumnLengthIndexes()) { if (! $this->schemaManager->getDatabasePlatform()->supportsColumnLengthIndexes()) {
self::markTestSkipped('This test is only supported on platforms that support indexes with column length definitions.'); self::markTestSkipped(
'This test is only supported on platforms that support indexes with column length definitions.'
);
} }
$table = new Table('test_partial_column_index'); $table = new Table('test_partial_column_index');
...@@ -1574,7 +1595,11 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase ...@@ -1574,7 +1595,11 @@ abstract class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
$diff = Comparator::compareSchemas($offlineSchema, $schema); $diff = Comparator::compareSchemas($offlineSchema, $schema);
foreach ($diff->changedTables as $table) { foreach ($diff->changedTables as $table) {
if (count($table->changedForeignKeys) <= 0 && count($table->addedForeignKeys) <= 0 && count($table->removedForeignKeys) <= 0) { if (
count($table->changedForeignKeys) <= 0
&& count($table->addedForeignKeys) <= 0
&& count($table->removedForeignKeys) <= 0
) {
continue; continue;
} }
......
...@@ -181,8 +181,11 @@ SQL; ...@@ -181,8 +181,11 @@ SQL;
/** /**
* @dataProvider getDiffListIntegerAutoincrementTableColumnsData * @dataProvider getDiffListIntegerAutoincrementTableColumnsData
*/ */
public function testDiffListIntegerAutoincrementTableColumns(string $integerType, bool $unsigned, bool $expectedComparatorDiff): void public function testDiffListIntegerAutoincrementTableColumns(
{ string $integerType,
bool $unsigned,
bool $expectedComparatorDiff
): void {
$tableName = 'test_int_autoincrement_table'; $tableName = 'test_int_autoincrement_table';
$offlineTable = new Table($tableName); $offlineTable = new Table($tableName);
......
...@@ -61,8 +61,8 @@ class TemporaryTableTest extends DbalFunctionalTestCase ...@@ -61,8 +61,8 @@ class TemporaryTableTest extends DbalFunctionalTestCase
$this->connection->rollBack(); $this->connection->rollBack();
$rows = $this->connection->fetchAll('SELECT * FROM nontemporary'); // In an event of an error this result has one row, because of an implicit commit
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.'); self::assertEquals([], $this->connection->fetchAll('SELECT * FROM nontemporary'));
} }
public function testCreateTemporaryTableNotAutoCommitTransaction(): void public function testCreateTemporaryTableNotAutoCommitTransaction(): void
...@@ -100,7 +100,7 @@ class TemporaryTableTest extends DbalFunctionalTestCase ...@@ -100,7 +100,7 @@ class TemporaryTableTest extends DbalFunctionalTestCase
} catch (Throwable $e) { } catch (Throwable $e) {
} }
$rows = $this->connection->fetchAll('SELECT * FROM nontemporary'); // In an event of an error this result has one row, because of an implicit commit
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.'); self::assertEquals([], $this->connection->fetchAll('SELECT * FROM nontemporary'));
} }
} }
...@@ -238,7 +238,10 @@ class TypeConversionTest extends DbalFunctionalTestCase ...@@ -238,7 +238,10 @@ class TypeConversionTest extends DbalFunctionalTestCase
{ {
$columnName = 'test_' . $type; $columnName = 'test_' . $type;
$typeInstance = Type::getType($type); $typeInstance = Type::getType($type);
$insertionValue = $typeInstance->convertToDatabaseValue($originalValue, $this->connection->getDatabasePlatform()); $insertionValue = $typeInstance->convertToDatabaseValue(
$originalValue,
$this->connection->getDatabasePlatform()
);
$this->connection->insert('type_conversion', ['id' => ++self::$typeCounter, $columnName => $insertionValue]); $this->connection->insert('type_conversion', ['id' => ++self::$typeCounter, $columnName => $insertionValue]);
......
...@@ -140,9 +140,23 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -140,9 +140,23 @@ class WriteTest extends DbalFunctionalTestCase
{ {
$this->insertRows(); $this->insertRows();
self::assertEquals(1, $this->connection->update('write_table', ['test_string' => 'bar'], ['test_string' => 'foo'])); self::assertEquals(1, $this->connection->update(
self::assertEquals(2, $this->connection->update('write_table', ['test_string' => 'baz'], ['test_string' => 'bar'])); 'write_table',
self::assertEquals(0, $this->connection->update('write_table', ['test_string' => 'baz'], ['test_string' => 'bar'])); ['test_string' => 'bar'],
['test_string' => 'foo']
));
self::assertEquals(2, $this->connection->update(
'write_table',
['test_string' => 'baz'],
['test_string' => 'bar']
));
self::assertEquals(0, $this->connection->update(
'write_table',
['test_string' => 'baz'],
['test_string' => 'bar']
));
} }
public function testLastInsertId(): void public function testLastInsertId(): void
...@@ -175,7 +189,10 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -175,7 +189,10 @@ class WriteTest extends DbalFunctionalTestCase
return strtolower($sequence->getName()) === 'write_table_id_seq'; return strtolower($sequence->getName()) === 'write_table_id_seq';
})); }));
$stmt = $this->connection->query($this->connection->getDatabasePlatform()->getSequenceNextValSQL('write_table_id_seq')); $stmt = $this->connection->query(
$this->connection->getDatabasePlatform()->getSequenceNextValSQL('write_table_id_seq')
);
$nextSequenceVal = $stmt->fetchColumn(); $nextSequenceVal = $stmt->fetchColumn();
$lastInsertId = $this->lastInsertId('write_table_id_seq'); $lastInsertId = $this->lastInsertId('write_table_id_seq');
...@@ -186,8 +203,13 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -186,8 +203,13 @@ class WriteTest extends DbalFunctionalTestCase
public function testLastInsertIdNoSequenceGiven(): void public function testLastInsertIdNoSequenceGiven(): void
{ {
if (! $this->connection->getDatabasePlatform()->supportsSequences() || $this->connection->getDatabasePlatform()->supportsIdentityColumns()) { if (
$this->markTestSkipped("Test only works consistently on platforms that support sequences and don't support identity columns."); ! $this->connection->getDatabasePlatform()->supportsSequences()
|| $this->connection->getDatabasePlatform()->supportsIdentityColumns()
) {
$this->markTestSkipped(
"Test only works consistently on platforms that support sequences and don't support identity columns."
);
} }
self::assertFalse($this->lastInsertId()); self::assertFalse($this->lastInsertId());
...@@ -205,7 +227,10 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -205,7 +227,10 @@ class WriteTest extends DbalFunctionalTestCase
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data); self::assertEquals(
$testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()),
$data
);
} }
public function testUpdateWithKeyValueTypes(): void public function testUpdateWithKeyValueTypes(): void
...@@ -229,7 +254,10 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -229,7 +254,10 @@ class WriteTest extends DbalFunctionalTestCase
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data); self::assertEquals(
$testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()),
$data
);
} }
public function testDeleteWithKeyValueTypes(): void public function testDeleteWithKeyValueTypes(): void
...@@ -241,7 +269,13 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -241,7 +269,13 @@ class WriteTest extends DbalFunctionalTestCase
['test_string' => 'datetime', 'test_int' => 'integer'] ['test_string' => 'datetime', 'test_int' => 'integer']
); );
$this->connection->delete('write_table', ['test_int' => 30, 'test_string' => $val], ['test_string' => 'datetime', 'test_int' => 'integer']); $this->connection->delete('write_table', [
'test_int' => 30,
'test_string' => $val,
], [
'test_string' => 'datetime',
'test_int' => 'integer',
]);
$data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
...@@ -300,7 +334,10 @@ class WriteTest extends DbalFunctionalTestCase ...@@ -300,7 +334,10 @@ class WriteTest extends DbalFunctionalTestCase
self::assertCount(1, $data); self::assertCount(1, $data);
$this->connection->update('write_table', ['test_int' => 10], ['test_string' => null], ['test_string' => 'string', 'test_int' => 'integer']); $this->connection->update('write_table', ['test_int' => 10], ['test_string' => null], [
'test_string' => 'string',
'test_int' => 'integer',
]);
$data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30'); $data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30');
......
...@@ -367,7 +367,10 @@ abstract class AbstractPlatformTestCase extends DbalTestCase ...@@ -367,7 +367,10 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
->method('onSchemaCreateTableColumn'); ->method('onSchemaCreateTableColumn');
$eventManager = new EventManager(); $eventManager = new EventManager();
$eventManager->addEventListener([Events::onSchemaCreateTable, Events::onSchemaCreateTableColumn], $listenerMock); $eventManager->addEventListener([
Events::onSchemaCreateTable,
Events::onSchemaCreateTableColumn,
], $listenerMock);
$this->platform->setEventManager($eventManager); $this->platform->setEventManager($eventManager);
...@@ -632,27 +635,63 @@ abstract class AbstractPlatformTestCase extends DbalTestCase ...@@ -632,27 +635,63 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
// Foreign table with reserved keyword as name (needs quotation). // Foreign table with reserved keyword as name (needs quotation).
$foreignTable = new Table('foreign'); $foreignTable = new Table('foreign');
$foreignTable->addColumn('create', 'string'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('bar', 'string'); // Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('`foo-bar`', 'string'); // Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$table->addForeignKeyConstraint($foreignTable, ['create', 'foo', '`bar`'], ['create', 'bar', '`foo-bar`'], [], 'FK_WITH_RESERVED_KEYWORD'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('create', 'string');
// Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('bar', 'string');
// Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$foreignTable->addColumn('`foo-bar`', 'string');
$table->addForeignKeyConstraint(
$foreignTable,
['create', 'foo', '`bar`'],
['create', 'bar', '`foo-bar`'],
[],
'FK_WITH_RESERVED_KEYWORD'
);
// Foreign table with non-reserved keyword as name (does not need quotation). // Foreign table with non-reserved keyword as name (does not need quotation).
$foreignTable = new Table('foo'); $foreignTable = new Table('foo');
$foreignTable->addColumn('create', 'string'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('bar', 'string'); // Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('`foo-bar`', 'string'); // Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$table->addForeignKeyConstraint($foreignTable, ['create', 'foo', '`bar`'], ['create', 'bar', '`foo-bar`'], [], 'FK_WITH_NON_RESERVED_KEYWORD'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('create', 'string');
// Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('bar', 'string');
// Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$foreignTable->addColumn('`foo-bar`', 'string');
$table->addForeignKeyConstraint(
$foreignTable,
['create', 'foo', '`bar`'],
['create', 'bar', '`foo-bar`'],
[],
'FK_WITH_NON_RESERVED_KEYWORD'
);
// Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite). // Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$foreignTable = new Table('`foo-bar`'); $foreignTable = new Table('`foo-bar`');
$foreignTable->addColumn('create', 'string'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('bar', 'string'); // Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('`foo-bar`', 'string'); // Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$table->addForeignKeyConstraint($foreignTable, ['create', 'foo', '`bar`'], ['create', 'bar', '`foo-bar`'], [], 'FK_WITH_INTENDED_QUOTATION'); // Foreign column with reserved keyword as name (needs quotation).
$foreignTable->addColumn('create', 'string');
// Foreign column with non-reserved keyword as name (does not need quotation).
$foreignTable->addColumn('bar', 'string');
// Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite).
$foreignTable->addColumn('`foo-bar`', 'string');
$table->addForeignKeyConstraint(
$foreignTable,
['create', 'foo', '`bar`'],
['create', 'bar', '`foo-bar`'],
[],
'FK_WITH_INTENDED_QUOTATION'
);
$sql = $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS); $sql = $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS);
self::assertEquals($this->getQuotedColumnInForeignKeySQL(), $sql); self::assertEquals($this->getQuotedColumnInForeignKeySQL(), $sql);
...@@ -875,17 +914,32 @@ abstract class AbstractPlatformTestCase extends DbalTestCase ...@@ -875,17 +914,32 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
$toTable = new Table('mytable'); $toTable = new Table('mytable');
$toTable->addColumn('unquoted', 'integer', ['comment' => 'Unquoted 1']); // unquoted -> unquoted // unquoted -> unquoted
$toTable->addColumn('where', 'integer', ['comment' => 'Unquoted 2']); // unquoted -> reserved keyword $toTable->addColumn('unquoted', 'integer', ['comment' => 'Unquoted 1']);
$toTable->addColumn('`foo`', 'integer', ['comment' => 'Unquoted 3']); // unquoted -> quoted
// unquoted -> reserved keyword
$toTable->addColumn('where', 'integer', ['comment' => 'Unquoted 2']);
// unquoted -> quoted
$toTable->addColumn('`foo`', 'integer', ['comment' => 'Unquoted 3']);
// reserved keyword -> unquoted
$toTable->addColumn('reserved_keyword', 'integer', ['comment' => 'Reserved keyword 1']);
$toTable->addColumn('reserved_keyword', 'integer', ['comment' => 'Reserved keyword 1']); // reserved keyword -> unquoted // reserved keyword -> reserved keyword
$toTable->addColumn('from', 'integer', ['comment' => 'Reserved keyword 2']); // reserved keyword -> reserved keyword $toTable->addColumn('from', 'integer', ['comment' => 'Reserved keyword 2']);
$toTable->addColumn('`bar`', 'integer', ['comment' => 'Reserved keyword 3']); // reserved keyword -> quoted
$toTable->addColumn('quoted', 'integer', ['comment' => 'Quoted 1']); // quoted -> unquoted // reserved keyword -> quoted
$toTable->addColumn('and', 'integer', ['comment' => 'Quoted 2']); // quoted -> reserved keyword $toTable->addColumn('`bar`', 'integer', ['comment' => 'Reserved keyword 3']);
$toTable->addColumn('`baz`', 'integer', ['comment' => 'Quoted 3']); // quoted -> quoted
// quoted -> unquoted
$toTable->addColumn('quoted', 'integer', ['comment' => 'Quoted 1']);
// quoted -> reserved keyword
$toTable->addColumn('and', 'integer', ['comment' => 'Quoted 2']);
// quoted -> quoted
$toTable->addColumn('`baz`', 'integer', ['comment' => 'Quoted 3']);
$comparator = new Comparator(); $comparator = new Comparator();
...@@ -1165,7 +1219,9 @@ abstract class AbstractPlatformTestCase extends DbalTestCase ...@@ -1165,7 +1219,9 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
} }
$this->expectException(DBALException::class); $this->expectException(DBALException::class);
$this->expectExceptionMessage("Operation 'Doctrine\\DBAL\\Platforms\\AbstractPlatform::getInlineColumnCommentSQL' is not supported by platform."); $this->expectExceptionMessage(
"Operation '" . AbstractPlatform::class . "::getInlineColumnCommentSQL' is not supported by platform."
);
$this->expectExceptionCode(0); $this->expectExceptionCode(0);
$this->platform->getInlineColumnCommentSQL('unsupported'); $this->platform->getInlineColumnCommentSQL('unsupported');
......
...@@ -68,7 +68,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -68,7 +68,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
protected function getGenerateForeignKeySql(): string protected function getGenerateForeignKeySql(): string
{ {
return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE'; return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id)'
. ' REFERENCES other_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE';
} }
public function testGeneratesForeignKeySqlForNonStandardOptions(): void public function testGeneratesForeignKeySqlForNonStandardOptions(): void
...@@ -81,7 +82,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -81,7 +82,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['onDelete' => 'CASCADE'] ['onDelete' => 'CASCADE']
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
...@@ -93,7 +95,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -93,7 +95,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['match' => 'full'] ['match' => 'full']
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) MATCH full NOT DEFERRABLE INITIALLY IMMEDIATE', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) MATCH full NOT DEFERRABLE INITIALLY IMMEDIATE',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
...@@ -105,7 +108,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -105,7 +108,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['deferrable' => true] ['deferrable' => true]
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) DEFERRABLE INITIALLY IMMEDIATE', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) DEFERRABLE INITIALLY IMMEDIATE',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
...@@ -117,7 +121,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -117,7 +121,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['deferred' => true] ['deferred' => true]
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
...@@ -129,7 +134,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -129,7 +134,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['feferred' => true] ['feferred' => true]
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
...@@ -141,7 +147,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -141,7 +147,8 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
['deferrable' => true, 'deferred' => true, 'match' => 'full'] ['deferrable' => true, 'deferred' => true, 'match' => 'full']
); );
self::assertEquals( self::assertEquals(
'CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) MATCH full DEFERRABLE INITIALLY DEFERRED', 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)'
. ' REFERENCES my_table (id) MATCH full DEFERRABLE INITIALLY DEFERRED',
$this->platform->getForeignKeyDeclarationSQL($foreignKey) $this->platform->getForeignKeyDeclarationSQL($foreignKey)
); );
} }
...@@ -150,7 +157,12 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -150,7 +157,12 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
{ {
self::assertEquals('SIMILAR TO', $this->platform->getRegexpExpression()); self::assertEquals('SIMILAR TO', $this->platform->getRegexpExpression());
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter()); self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter());
self::assertEquals('column1 || column2 || column3', $this->platform->getConcatExpression('column1', 'column2', 'column3'));
self::assertEquals(
'column1 || column2 || column3',
$this->platform->getConcatExpression('column1', 'column2', 'column3')
);
self::assertEquals('SUBSTRING(column FROM 5)', $this->platform->getSubstringExpression('column', 5)); self::assertEquals('SUBSTRING(column FROM 5)', $this->platform->getSubstringExpression('column', 5));
self::assertEquals('SUBSTRING(column FROM 1 FOR 5)', $this->platform->getSubstringExpression('column', 1, 5)); self::assertEquals('SUBSTRING(column FROM 1 FOR 5)', $this->platform->getSubstringExpression('column', 1, 5));
} }
...@@ -188,7 +200,10 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -188,7 +200,10 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
$column = $table->addColumn('id', 'integer'); $column = $table->addColumn('id', 'integer');
$column->setAutoincrement(true); $column->setAutoincrement(true);
self::assertEquals(['CREATE TABLE autoinc_table (id SERIAL NOT NULL)'], $this->platform->getCreateTableSQL($table)); self::assertEquals(
['CREATE TABLE autoinc_table (id SERIAL NOT NULL)'],
$this->platform->getCreateTableSQL($table)
);
} }
/** /**
...@@ -419,10 +434,14 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -419,10 +434,14 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
protected function getQuotedColumnInForeignKeySQL(): array protected function getQuotedColumnInForeignKeySQL(): array
{ {
return [ return [
'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)', 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, '
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', . 'foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")'
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', . ' REFERENCES "foreign" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")'
. ' REFERENCES foo ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar")'
. ' REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
]; ];
} }
...@@ -484,8 +503,12 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -484,8 +503,12 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
* *
* @dataProvider pgBooleanProvider * @dataProvider pgBooleanProvider
*/ */
public function testConvertFromBoolean($databaseValue, string $prepareStatementValue, ?int $integerValue, ?bool $booleanValue): void public function testConvertFromBoolean(
{ $databaseValue,
string $prepareStatementValue,
?int $integerValue,
?bool $booleanValue
): void {
$platform = $this->createPlatform(); $platform = $this->createPlatform();
self::assertSame($booleanValue, $platform->convertFromBoolean($databaseValue)); self::assertSame($booleanValue, $platform->convertFromBoolean($databaseValue));
......
...@@ -111,7 +111,8 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -111,7 +111,8 @@ class OraclePlatformTest extends AbstractPlatformTestCase
{ {
return [ return [
'ALTER TABLE mytable ADD (quota NUMBER(10) DEFAULT NULL NULL)', 'ALTER TABLE mytable ADD (quota NUMBER(10) DEFAULT NULL NULL)',
"ALTER TABLE mytable MODIFY (baz VARCHAR2(255) DEFAULT 'def' NOT NULL, bloo NUMBER(1) DEFAULT '0' NOT NULL)", "ALTER TABLE mytable MODIFY (baz VARCHAR2(255) DEFAULT 'def' NOT NULL, "
. "bloo NUMBER(1) DEFAULT '0' NOT NULL)",
'ALTER TABLE mytable DROP (foo)', 'ALTER TABLE mytable DROP (foo)',
'ALTER TABLE mytable RENAME TO userlist', 'ALTER TABLE mytable RENAME TO userlist',
]; ];
...@@ -127,7 +128,10 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -127,7 +128,10 @@ class OraclePlatformTest extends AbstractPlatformTestCase
public function testGeneratesSqlSnippets(): void public function testGeneratesSqlSnippets(): void
{ {
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter()); self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter());
self::assertEquals('column1 || column2 || column3', $this->platform->getConcatExpression('column1', 'column2', 'column3')); self::assertEquals(
'column1 || column2 || column3',
$this->platform->getConcatExpression('column1', 'column2', 'column3')
);
} }
public function testGeneratesTransactionsCommands(): void public function testGeneratesTransactionsCommands(): void
...@@ -294,13 +298,25 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -294,13 +298,25 @@ class OraclePlatformTest extends AbstractPlatformTestCase
public function testModifyLimitQueryWithNonEmptyOffset(): void public function testModifyLimitQueryWithNonEmptyOffset(): void
{ {
$sql = $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 10); $sql = $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 10);
self::assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a WHERE ROWNUM <= 20) WHERE doctrine_rownum >= 11', $sql);
self::assertEquals(
'SELECT * FROM ('
. 'SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a WHERE ROWNUM <= 20'
. ') WHERE doctrine_rownum >= 11',
$sql
);
} }
public function testModifyLimitQueryWithEmptyLimit(): void public function testModifyLimitQueryWithEmptyLimit(): void
{ {
$sql = $this->platform->modifyLimitQuery('SELECT * FROM user', null, 10); $sql = $this->platform->modifyLimitQuery('SELECT * FROM user', null, 10);
self::assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a) WHERE doctrine_rownum >= 11', $sql);
self::assertEquals(
'SELECT * FROM ('
. 'SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a'
. ') WHERE doctrine_rownum >= 11',
$sql
);
} }
public function testModifyLimitQueryWithAscOrderBy(): void public function testModifyLimitQueryWithAscOrderBy(): void
...@@ -325,7 +341,17 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -325,7 +341,17 @@ class OraclePlatformTest extends AbstractPlatformTestCase
$targets = [ $targets = [
sprintf('CREATE TABLE %s (%s NUMBER(10) NOT NULL)', $tableName, $columnName), sprintf('CREATE TABLE %s (%s NUMBER(10) NOT NULL)', $tableName, $columnName),
sprintf( sprintf(
"DECLARE constraints_Count NUMBER; BEGIN SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '%s' AND CONSTRAINT_TYPE = 'P'; IF constraints_Count = 0 OR constraints_Count = '' THEN EXECUTE IMMEDIATE 'ALTER TABLE %s ADD CONSTRAINT %s_AI_PK PRIMARY KEY (%s)'; END IF; END;", 'DECLARE constraints_Count NUMBER;'
. ' BEGIN'
. ' SELECT COUNT(CONSTRAINT_NAME)'
. ' INTO constraints_Count'
. ' FROM USER_CONSTRAINTS'
. " WHERE TABLE_NAME = '%s' AND CONSTRAINT_TYPE = 'P';"
. " IF constraints_Count = 0 OR constraints_Count = ''"
. ' THEN EXECUTE IMMEDIATE'
. " 'ALTER TABLE %s ADD CONSTRAINT %s_AI_PK PRIMARY KEY (%s)';"
. ' END IF;'
. ' END;',
$tableName, $tableName,
$tableName, $tableName,
$tableName, $tableName,
...@@ -333,7 +359,20 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -333,7 +359,20 @@ class OraclePlatformTest extends AbstractPlatformTestCase
), ),
sprintf('CREATE SEQUENCE %s_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1', $tableName), sprintf('CREATE SEQUENCE %s_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1', $tableName),
sprintf( sprintf(
"CREATE TRIGGER %s_AI_PK BEFORE INSERT ON %s FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN SELECT %s_SEQ.NEXTVAL INTO :NEW.%s FROM DUAL; IF (:NEW.%s IS NULL OR :NEW.%s = 0) THEN SELECT %s_SEQ.NEXTVAL INTO :NEW.%s FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '%s_SEQ'; SELECT :NEW.%s INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP SELECT %s_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END;", 'CREATE TRIGGER %s_AI_PK BEFORE INSERT ON %s FOR EACH ROW DECLARE last_Sequence NUMBER;'
. ' last_InsertID NUMBER;'
. ' BEGIN SELECT %s_SEQ.NEXTVAL'
. ' INTO :NEW.%s FROM DUAL;'
. ' IF (:NEW.%s IS NULL OR :NEW.%s = 0)'
. ' THEN SELECT %s_SEQ.NEXTVAL INTO :NEW.%s FROM DUAL;'
. ' ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence'
. " FROM User_Sequences WHERE Sequence_Name = '%s_SEQ';"
. ' SELECT :NEW.%s INTO last_InsertID FROM DUAL;'
. ' WHILE (last_InsertID > last_Sequence) LOOP'
. ' SELECT %s_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;'
. ' END LOOP;'
. ' END IF;'
. ' END;',
$tableName, $tableName,
$tableName, $tableName,
$tableName, $tableName,
...@@ -441,10 +480,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -441,10 +480,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase
protected function getQuotedColumnInForeignKeySQL(): array protected function getQuotedColumnInForeignKeySQL(): array
{ {
return [ return [
'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, "bar" VARCHAR2(255) NOT NULL)', 'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, '
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foreign ("create", bar, "foo-bar")', . '"bar" VARCHAR2(255) NOT NULL)',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar")', 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")'
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar")', . ' REFERENCES foreign ("create", bar, "foo-bar")',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")'
. ' REFERENCES foo ("create", bar, "foo-bar")',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar")'
. ' REFERENCES "foo-bar" ("create", bar, "foo-bar")',
]; ];
} }
...@@ -479,7 +522,11 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -479,7 +522,11 @@ class OraclePlatformTest extends AbstractPlatformTestCase
['notnull'] ['notnull']
); );
$expectedSql = ["ALTER TABLE mytable MODIFY (foo VARCHAR2(255) DEFAULT 'bla', baz VARCHAR2(255) DEFAULT 'bla' NOT NULL, metar VARCHAR2(2000) DEFAULT NULL NULL)"]; $expectedSql = [
"ALTER TABLE mytable MODIFY (foo VARCHAR2(255) DEFAULT 'bla', baz VARCHAR2(255) DEFAULT 'bla' NOT NULL, "
. 'metar VARCHAR2(2000) DEFAULT NULL NULL)',
];
self::assertEquals($expectedSql, $this->platform->getAlterTableSQL($tableDiff)); self::assertEquals($expectedSql, $this->platform->getAlterTableSQL($tableDiff));
} }
...@@ -508,7 +555,11 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -508,7 +555,11 @@ class OraclePlatformTest extends AbstractPlatformTestCase
self::assertSame('RAW(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true])); self::assertSame('RAW(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0])); self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2000]));
self::assertSame(
'RAW(2000)',
$this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2000])
);
} }
public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL(): void public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL(): void
......
...@@ -30,12 +30,15 @@ class PostgreSQL91PlatformTest extends PostgreSqlPlatformTest ...@@ -30,12 +30,15 @@ class PostgreSQL91PlatformTest extends PostgreSqlPlatformTest
{ {
$table = new Table('foo'); $table = new Table('foo');
$table->addColumn('no_collation', 'string'); $table->addColumn('no_collation', 'string');
$table->addColumn('column_collation', 'string')->setPlatformOption('collation', 'en_US.UTF-8'); $table->addColumn('column_collation', 'string')
->setPlatformOption('collation', 'en_US.UTF-8');
self::assertSame( self::assertSame(
['CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, column_collation VARCHAR(255) NOT NULL COLLATE "en_US.UTF-8")'], [
$this->platform->getCreateTableSQL($table), 'CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, '
'Column "no_collation" will use the default collation from the table/database and "column_collation" overwrites the collation on this column' . 'column_collation VARCHAR(255) NOT NULL COLLATE "en_US.UTF-8")',
],
$this->platform->getCreateTableSQL($table)
); );
} }
} }
...@@ -83,7 +83,8 @@ class SQLAnywhere12PlatformTest extends SQLAnywhere11PlatformTest ...@@ -83,7 +83,8 @@ class SQLAnywhere12PlatformTest extends SQLAnywhere11PlatformTest
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL(): void public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL(): void
{ {
self::assertEquals( self::assertEquals(
'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD', 'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b)'
. ' WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
$this->platform->getCreateIndexSQL( $this->platform->getCreateIndexSQL(
new Index( new Index(
'fooindex', 'fooindex',
......
...@@ -23,6 +23,9 @@ class SQLAzurePlatformTest extends DbalTestCase ...@@ -23,6 +23,9 @@ class SQLAzurePlatformTest extends DbalTestCase
$table->addOption('azure.federatedOnDistributionName', 'TblId'); $table->addOption('azure.federatedOnDistributionName', 'TblId');
$table->addOption('azure.federatedOnColumnName', 'id'); $table->addOption('azure.federatedOnColumnName', 'id');
self::assertEquals(['CREATE TABLE tbl (id INT NOT NULL) FEDERATED ON (TblId = id)'], $this->platform->getCreateTableSQL($table)); self::assertEquals(
['CREATE TABLE tbl (id INT NOT NULL) FEDERATED ON (TblId = id)'],
$this->platform->getCreateTableSQL($table)
);
} }
} }
...@@ -58,18 +58,36 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase ...@@ -58,18 +58,36 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
return [ return [
// Test re-ordered query with correctly-scrubbed ORDER BY clause // Test re-ordered query with correctly-scrubbed ORDER BY clause
[ [
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_ ORDER BY c0_.title ASC) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', 'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM ('
. 'SELECT c0_.id AS id_0, c0_.title AS title_1, '
. 'ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_ ORDER BY c0_.title ASC) '
. 'dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30, 30,
null, null,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC', 'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM ('
. 'SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() '
. 'OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result '
. 'GROUP BY id_0 ORDER BY dctrn_minrownum ASC) '
. 'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) '
. 'AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 '
. 'ORDER BY doctrine_rownum ASC',
], ],
// Test re-ordered query with no scrubbed ORDER BY clause // Test re-ordered query with no scrubbed ORDER BY clause
[ [
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', 'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM ('
. 'SELECT c0_.id AS id_0, c0_.title AS title_1, '
. 'ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result '
. 'GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30, 30,
null, null,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC', 'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM ('
. 'SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() '
. 'OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result '
. 'GROUP BY id_0 ORDER BY dctrn_minrownum ASC) '
. 'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) '
. 'AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 '
. 'ORDER BY doctrine_rownum ASC',
], ],
]; ];
} }
......
...@@ -38,31 +38,37 @@ class MySqlInheritCharsetTest extends TestCase ...@@ -38,31 +38,37 @@ class MySqlInheritCharsetTest extends TestCase
public function testTableOptions(): void public function testTableOptions(): void
{ {
$eventManager = new EventManager(); $platform = new MySqlPlatform();
$driverMock = $this->createMock(Driver::class);
$platform = new MySqlPlatform();
// default, no overrides // default, no overrides
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
self::assertSame( self::assertSame(
$platform->getCreateTableSQL($table), [
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'] 'CREATE TABLE foobar (aa INT NOT NULL)'
. ' DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB',
],
$platform->getCreateTableSQL($table)
); );
// explicit utf8 // explicit utf8
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8'); $table->addOption('charset', 'utf8');
self::assertSame( self::assertSame(
$platform->getCreateTableSQL($table), [
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB'] 'CREATE TABLE foobar (aa INT NOT NULL)'
. ' DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB',
],
$platform->getCreateTableSQL($table)
); );
// explicit utf8mb4 // explicit utf8mb4
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]); $table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8mb4'); $table->addOption('charset', 'utf8mb4');
self::assertSame( self::assertSame(
$platform->getCreateTableSQL($table), ['CREATE TABLE foobar (aa INT NOT NULL)'
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'] . ' DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB',
],
$platform->getCreateTableSQL($table)
); );
} }
......
...@@ -42,8 +42,18 @@ class MySqlSchemaManagerTest extends TestCase ...@@ -42,8 +42,18 @@ class MySqlSchemaManagerTest extends TestCase
self::assertCount(1, $fkeys, 'Table has to have one foreign key.'); self::assertCount(1, $fkeys, 'Table has to have one foreign key.');
self::assertInstanceOf(ForeignKeyConstraint::class, $fkeys[0]); self::assertInstanceOf(ForeignKeyConstraint::class, $fkeys[0]);
self::assertEquals(['column_1', 'column_2', 'column_3'], array_map('strtolower', $fkeys[0]->getLocalColumns()));
self::assertEquals(['column_1', 'column_2', 'column_3'], array_map('strtolower', $fkeys[0]->getForeignColumns())); self::assertEquals([
'column_1',
'column_2',
'column_3',
], array_map('strtolower', $fkeys[0]->getLocalColumns()));
self::assertEquals([
'column_1',
'column_2',
'column_3',
], array_map('strtolower', $fkeys[0]->getForeignColumns()));
} }
/** /**
......
...@@ -55,7 +55,13 @@ class MySQLSchemaTest extends TestCase ...@@ -55,7 +55,13 @@ class MySQLSchemaTest extends TestCase
$sqls[] = $this->platform->getCreateForeignKeySQL($fk, $tableOld); $sqls[] = $this->platform->getCreateForeignKeySQL($fk, $tableOld);
} }
self::assertEquals(['ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C8E48560F FOREIGN KEY (foo_id) REFERENCES test_foreign (foo_id)'], $sqls); self::assertEquals(
[
'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C8E48560F FOREIGN KEY (foo_id)'
. ' REFERENCES test_foreign (foo_id)',
],
$sqls
);
} }
public function testClobNoAlterTable(): void public function testClobNoAlterTable(): void
......
...@@ -25,7 +25,7 @@ class RemoveNamespacedAssetsTest extends TestCase ...@@ -25,7 +25,7 @@ class RemoveNamespacedAssetsTest extends TestCase
$schema->visit(new RemoveNamespacedAssets()); $schema->visit(new RemoveNamespacedAssets());
$tables = $schema->getTables(); $tables = $schema->getTables();
self::assertEquals(['test.test', 'test.baz'], array_keys($tables), "Only 2 tables should be present, both in 'test' namespace."); self::assertEquals(['test.test', 'test.baz'], array_keys($tables));
} }
public function testCleanupForeignKeys(): void public function testCleanupForeignKeys(): void
......
This diff is collapsed.
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