Unverified Commit 859e80c9 authored by Sergei Morozov's avatar Sergei Morozov

Merge branch '3.0.x'

parents a36c5b7e 95b40a13
......@@ -9,8 +9,8 @@
<arg name="cache" value=".phpcs-cache"/>
<arg name="colors"/>
<!-- Ignore warnings, show progress of the run and show sniff names -->
<arg value="nps"/>
<!-- Show progress of the run and show sniff names -->
<arg value="ps"/>
<file>bin</file>
<file>src</file>
......@@ -38,6 +38,16 @@
</properties>
</rule>
<rule ref="PSR2.Classes.PropertyDeclaration.Underscore">
<exclude-pattern>*/src/Configuration.php</exclude-pattern>
<exclude-pattern>*/src/Connection.php</exclude-pattern>
<exclude-pattern>*/src/Driver</exclude-pattern>
<exclude-pattern>*/src/Event/Listeners</exclude-pattern>
<exclude-pattern>*/src/Platforms</exclude-pattern>
<exclude-pattern>*/src/Schema</exclude-pattern>
<exclude-pattern>*/src/Tools/Console/Helper/ConnectionHelper.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint">
<exclude-pattern>*/src/*</exclude-pattern>
</rule>
......@@ -120,4 +130,10 @@
<rule ref="Squiz.PHP.LowercasePHPFunctions">
<exclude-pattern>src/Driver/SQLSrv/Statement.php</exclude-pattern>
</rule>
<!-- This could be considered a bug in the sniff or the shortcoming of the Platform API design
see https://github.com/squizlabs/PHP_CodeSniffer/issues/3035 -->
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod.Found">
<exclude-pattern>src/Platforms/SqlitePlatform.php</exclude-pattern>
</rule>
</ruleset>
......@@ -3,8 +3,6 @@ parameters:
paths:
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/tests
scanFiles:
- %currentWorkingDirectory%/tests/phpstan-polyfill.php
treatPhpDocTypesAsCertain: false
reportUnmatchedIgnoredErrors: false
checkMissingIterableValueType: false
......
......@@ -572,7 +572,8 @@ class Connection
* Table expression and columns are not escaped and are not safe for user-input.
*
* @param string $table The SQL expression of the table on which to delete.
* @param array<string, mixed> $identifier The deletion criteria. An associative array containing column-value pairs.
* @param array<string, mixed> $identifier The deletion criteria. An associative array
* containing column-value pairs.
* @param array<int|string, int|string> $types The query parameter types.
*
* @return int The number of affected rows.
......@@ -640,9 +641,12 @@ class Connection
*
* Table expression and columns are not escaped and are not safe for user-input.
*
* @param string $table The SQL expression of the table to update quoted or unquoted.
* @param array<string, mixed> $data An associative array containing column-value pairs.
* @param array<string, mixed> $identifier The update criteria. An associative array containing column-value pairs.
* @param string $table The SQL expression of the table
* to update quoted or unquoted.
* @param array<string, mixed> $data An associative array
* containing column-value pairs.
* @param array<string, mixed> $identifier The update criteria. An associative array
* containing column-value pairs.
* @param array<int, int|string>|array<string, int|string> $types The query parameter types.
*
* @return int The number of affected rows.
......@@ -676,8 +680,10 @@ class Connection
*
* Table expression and columns are not escaped and are not safe for user-input.
*
* @param string $table The SQL expression of the table to insert data into, quoted or unquoted.
* @param array<string, mixed> $data An associative array containing column-value pairs.
* @param string $table The SQL expression of the table
* to insert data into, quoted or unquoted.
* @param array<string, mixed> $data An associative array
* containing column-value pairs.
* @param array<int, int|string>|array<string, int|string> $types The query parameter types.
*
* @return int The number of affected rows.
......@@ -836,7 +842,8 @@ class Connection
}
/**
* Prepares and executes an SQL query and returns the result as an iterator over rows represented as associative arrays.
* Prepares and executes an SQL query and returns the result as an iterator over rows represented
* as associative arrays.
*
* @param string $query The SQL query.
* @param array<int, mixed>|array<string, mixed> $params The query parameters.
......
......@@ -135,7 +135,10 @@ class PrimaryReadReplicaConnection extends Connection
public function connect(?string $connectionName = null): void
{
if ($connectionName !== null) {
throw new InvalidArgumentException('Passing a connection name as first argument is not supported anymore. Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.');
throw new InvalidArgumentException(
'Passing a connection name as first argument is not supported anymore.'
. ' Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.'
);
}
$this->performConnect();
......
......@@ -74,7 +74,8 @@ final class ConvertPositionalToNamedPlaceholders
* @param string[] $fragments Fragments of the original statement not containing placeholders
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal
* or NULL if not currently in a literal
* @param string[] $paramMap Mapping of the original parameter positions to their named replacements
* @param string[] $paramMap Mapping of the original parameter positions
* to their named replacements
*
* @return bool Whether the token was found
*/
......
......@@ -10,9 +10,6 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use PDO;
use function strpos;
use function substr;
final class Connection implements ServerInfoAwareConnection
{
/** @var PDOConnection */
......@@ -37,14 +34,7 @@ final class Connection implements ServerInfoAwareConnection
public function quote(string $value): string
{
$val = $this->connection->quote($value);
// Fix for a driver version terminating all values with null byte
if (strpos($val, "\0") !== false) {
$val = substr($val, 0, -1);
}
return $val;
return $this->connection->quote($value);
}
public function exec(string $sql): int
......
......@@ -60,8 +60,13 @@ final class Statement implements StatementInterface
* @param mixed $variable
* @param mixed $driverOptions
*/
public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null, $driverOptions = null): void
{
public function bindParam(
$param,
&$variable,
int $type = ParameterType::STRING,
?int $length = null,
$driverOptions = null
): void {
$type = $this->convertParamType($type);
$extraParameters = array_slice(func_get_args(), 3);
......
......@@ -203,7 +203,10 @@ final class DriverManager
throw UnknownDriver::new($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 InvalidDriverClass::new($params['driverClass']);
}
}
......
......@@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use function array_merge;
/**
* Event Arguments used when SQL queries for adding table columns are generated inside Doctrine\DBAL\Platform\*Platform.
* Event Arguments used when SQL queries for adding table columns are generated inside {@link AbstractPlatform}.
*/
class SchemaAlterTableAddColumnEventArgs extends SchemaEventArgs
{
......
......@@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use function array_merge;
/**
* Event Arguments used when SQL queries for changing table columns are generated inside Doctrine\DBAL\Platform\*Platform.
* Event Arguments used when SQL queries for changing table columns are generated inside {@link AbstractPlatform}.
*/
class SchemaAlterTableChangeColumnEventArgs extends SchemaEventArgs
{
......
......@@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use function array_merge;
/**
* Event Arguments used when SQL queries for creating tables are generated inside Doctrine\DBAL\Platform\*Platform.
* Event Arguments used when SQL queries for creating tables are generated inside {@link AbstractPlatform}.
*/
class SchemaAlterTableEventArgs extends SchemaEventArgs
{
......
......@@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use function array_merge;
/**
* Event Arguments used when SQL queries for removing table columns are generated inside Doctrine\DBAL\Platform\*Platform.
* Event Arguments used when SQL queries for removing table columns are generated inside {@link AbstractPlatform}.
*/
class SchemaAlterTableRemoveColumnEventArgs extends SchemaEventArgs
{
......
......@@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use function array_merge;
/**
* Event Arguments used when SQL queries for renaming table columns are generated inside Doctrine\DBAL\Platform\*Platform.
* Event Arguments used when SQL queries for renaming table columns are generated inside {@link AbstractPlatform}.
*/
class SchemaAlterTableRenameColumnEventArgs extends SchemaEventArgs
{
......
......@@ -8,7 +8,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Column;
/**
* Event Arguments used when the portable column definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager.
* Event Arguments used when the portable column definition is generated inside {@link AbstractPlatform}.
*/
class SchemaColumnDefinitionEventArgs extends SchemaEventArgs
{
......
......@@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\Table;
use function array_merge;
/**
* Event Arguments used when SQL queries for creating table columns are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
* Event Arguments used when SQL queries for creating table columns are generated inside {@link AbstractPlatform}.
*/
class SchemaCreateTableColumnEventArgs extends SchemaEventArgs
{
......
......@@ -10,8 +10,7 @@ use Doctrine\DBAL\Schema\Table;
use function array_merge;
/**
* Event Arguments used when SQL queries for creating tables are generated
* inside Doctrine\DBAL\Platform\AbstractPlatform.
* Event Arguments used when SQL queries for creating tables are generated inside {@link AbstractPlatform}.
*/
class SchemaCreateTableEventArgs extends SchemaEventArgs
{
......
......@@ -9,7 +9,7 @@ use Doctrine\DBAL\Schema\Table;
use InvalidArgumentException;
/**
* Event Arguments used when the SQL query for dropping tables are generated inside Doctrine\DBAL\Platform\AbstractPlatform.
* Event Arguments used when the SQL query for dropping tables are generated inside {@link AbstractPlatform}.
*/
class SchemaDropTableEventArgs extends SchemaEventArgs
{
......
......@@ -8,7 +8,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Index;
/**
* Event Arguments used when the portable index definition is generated inside Doctrine\DBAL\Schema\AbstractSchemaManager.
* Event Arguments used when the portable index definition is generated inside {@link AbstractSchemaManager}.
*/
class SchemaIndexDefinitionEventArgs extends SchemaEventArgs
{
......
......@@ -145,7 +145,10 @@ class TableGenerator
} catch (Throwable $e) {
$this->conn->rollBack();
throw new DBALException(sprintf('Error occurred while generating ID with TableGenerator, aborted generation with error: %s', $e->getMessage()), 0, $e);
throw new DBALException(sprintf(
'Error occurred while generating ID with TableGenerator, aborted generation with error: %s',
$e->getMessage()
), 0, $e);
}
return $value;
......
......@@ -40,8 +40,14 @@ final class DebugStack implements SQLLogger
return;
}
$this->start = microtime(true);
$this->queries[++$this->currentQuery] = ['sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0];
$this->start = microtime(true);
$this->queries[++$this->currentQuery] = [
'sql' => $sql,
'params' => $params,
'types' => $types,
'executionMS' => 0,
];
}
public function stopQuery(): void
......
......@@ -1071,8 +1071,12 @@ abstract class AbstractPlatform
*
* @throws DBALException If not supported on this platform.
*/
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
throw NotSupported::new(__METHOD__);
}
......@@ -1125,7 +1129,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 int|null $lockMode One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will
......@@ -1183,7 +1188,9 @@ abstract class AbstractPlatform
}
if (! is_string($table)) {
throw new InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
throw new InvalidArgumentException(
__METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
);
}
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) {
......@@ -1194,7 +1201,9 @@ abstract class AbstractPlatform
$sql = $eventArgs->getSql();
if ($sql === null) {
throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL.');
throw new UnexpectedValueException(
'Default implementation of DROP TABLE was overridden with NULL.'
);
}
return $sql;
......@@ -1227,7 +1236,9 @@ abstract class AbstractPlatform
if ($index instanceof Index) {
$index = $index->getQuotedName($this);
} elseif (! is_string($index)) {
throw new InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
throw new InvalidArgumentException(
__METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
);
}
return 'DROP INDEX ' . $index;
......@@ -1327,7 +1338,10 @@ abstract class AbstractPlatform
$columns = [];
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);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
......@@ -1338,10 +1352,11 @@ abstract class AbstractPlatform
}
}
$columnData = $column->toArray();
$columnData['name'] = $column->getQuotedName($this);
$columnData['version'] = $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false;
$columnData['comment'] = $this->getColumnComment($column);
$columnData = array_merge($column->toArray(), [
'name' => $column->getQuotedName($this),
'version' => $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false,
'comment' => $this->getColumnComment($column),
]);
if (in_array($column->getName(), $options['primary'], true)) {
$columnData['primary'] = true;
......@@ -1737,8 +1752,12 @@ abstract class AbstractPlatform
/**
* @param string[] $columnSql
*/
protected function onSchemaAlterTableRenameColumn(string $oldColumnName, Column $column, TableDiff $diff, array &$columnSql): bool
{
protected function onSchemaAlterTableRenameColumn(
string $oldColumnName,
Column $column,
TableDiff $diff,
array &$columnSql
): bool {
if ($this->_eventManager === null) {
return false;
}
......
......@@ -143,8 +143,12 @@ class DB2Platform extends AbstractPlatform
return 'BITOR(' . $value1 . ', ' . $value2 . ')';
}
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
switch ($unit) {
case DateIntervalUnit::WEEK:
$interval = $this->multiplyInterval($interval, 7);
......@@ -513,8 +517,12 @@ class DB2Platform extends AbstractPlatform
* @param string[] $sql The sequence of table alteration statements to fill.
* @param mixed[] $queryParts The sequence of column alteration clauses to fill.
*/
private function gatherAlterColumnSQL(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);
if (empty($alterColumnClauses)) {
......
......@@ -21,12 +21,10 @@ final class InvalidPlatformVersion extends DBALException implements PlatformExce
*/
public static function new(string $version, string $expectedFormat): self
{
return new self(
sprintf(
'Invalid platform version "%s" specified. The platform version has to be specified in the format: "%s".',
$version,
$expectedFormat
)
);
return new self(sprintf(
'Invalid platform version "%s" specified. The platform version has to be specified in the format: "%s".',
$version,
$expectedFormat
));
}
}
......@@ -86,8 +86,12 @@ class MySqlPlatform extends AbstractPlatform
return sprintf('CONCAT(%s)', implode(', ', $string));
}
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
$function = $operator === '+' ? 'DATE_ADD' : 'DATE_SUB';
return $function . '(' . $date . ', INTERVAL ' . $interval . ' ' . $unit . ')';
......@@ -153,10 +157,9 @@ class MySqlPlatform extends AbstractPlatform
$databaseNameSql = $this->getDatabaseNameSql($database);
$sql .= ' AND k.table_schema = ' . $databaseNameSql . ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */';
$sql .= ' AND k.`REFERENCED_COLUMN_NAME` is not NULL';
return $sql;
return $sql . ' AND k.table_schema = ' . $databaseNameSql
. ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */'
. ' AND k.`REFERENCED_COLUMN_NAME` is not NULL';
}
public function getCreateViewSQL(string $name, string $sql): string
......@@ -452,9 +455,11 @@ SQL
continue;
}
$columnArray = $column->toArray();
$columnArray['comment'] = $this->getColumnComment($column);
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
$columnArray = array_merge($column->toArray(), [
'comment' => $this->getColumnComment($column),
]);
$queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
}
foreach ($diff->removedColumns as $column) {
......@@ -521,7 +526,8 @@ SQL
if (! $this->onSchemaAlterTable($diff, $tableSql)) {
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(
......@@ -882,13 +888,17 @@ SQL
} elseif (is_string($index)) {
$indexName = $index;
} else {
throw new InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
throw new InvalidArgumentException(
__METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
);
}
if ($table instanceof Table) {
$table = $table->getQuotedName($this);
} elseif (! is_string($table)) {
throw new InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
throw new InvalidArgumentException(
__METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
);
}
if ($index instanceof Index && $index->isPrimary()) {
......@@ -972,7 +982,9 @@ SQL
if ($table instanceof Table) {
$table = $table->getQuotedName($this);
} elseif (! is_string($table)) {
throw new InvalidArgumentException('getDropTemporaryTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
throw new InvalidArgumentException(
__METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
);
}
return 'DROP TEMPORARY TABLE ' . $table;
......
......@@ -75,8 +75,12 @@ class OraclePlatform extends AbstractPlatform
return sprintf('INSTR(%s, %s, %s)', $string, $substring, $start);
}
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
switch ($unit) {
case DateIntervalUnit::MONTH:
case DateIntervalUnit::QUARTER:
......@@ -437,14 +441,15 @@ class OraclePlatform extends AbstractPlatform
$idx = new Index($autoincrementIdentifierName, [$quotedName], true, true);
$sql[] = 'DECLARE
$sql[] = "DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \'' . $unquotedTableName . '\' AND CONSTRAINT_TYPE = \'P\';
IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \'' . $this->getCreateConstraintSQL($idx, $quotedTableName) . '\';
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '" . $unquotedTableName
. "' AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
EXECUTE IMMEDIATE '" . $this->getCreateConstraintSQL($idx, $quotedTableName) . "';
END IF;
END;';
END;";
$sequenceName = $this->getIdentitySequenceName(
$tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName,
......@@ -732,7 +737,8 @@ SQL
}
if (count($fields) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ADD (' . implode(', ', $fields) . ')';
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' ADD (' . implode(', ', $fields) . ')';
}
$fields = [];
......@@ -781,7 +787,8 @@ SQL
}
if (count($fields) > 0) {
$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) {
......@@ -805,7 +812,8 @@ SQL
}
if (count($fields) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' DROP (' . implode(', ', $fields) . ')';
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this)
. ' DROP (' . implode(', ', $fields) . ')';
}
$tableSql = [];
......@@ -1058,7 +1066,9 @@ SQL
if ($database !== null && $database !== '/') {
$tableCommentsName = 'all_tab_comments';
$ownerCondition = ' AND owner = ' . $this->quoteStringLiteral($this->normalizeIdentifier($database)->getName());
$ownerCondition = ' AND owner = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($database)->getName()
);
}
return sprintf(
......
......@@ -88,14 +88,19 @@ class PostgreSQL94Platform extends AbstractPlatform
if ($start !== null) {
$string = $this->getSubstringExpression($string, $start);
return 'CASE WHEN (POSITION(' . $substring . ' IN ' . $string . ') = 0) THEN 0 ELSE (POSITION(' . $substring . ' IN ' . $string . ') + ' . $start . ' - 1) END';
return 'CASE WHEN (POSITION(' . $substring . ' IN ' . $string . ') = 0) THEN 0'
. ' ELSE (POSITION(' . $substring . ' IN ' . $string . ') + ' . $start . ' - 1) END';
}
return sprintf('POSITION(%s IN %s)', $substring, $string);
}
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
if ($unit === DateIntervalUnit::QUARTER) {
$interval = $this->multiplyInterval($interval, 3);
$unit = DateIntervalUnit::MONTH;
......@@ -268,7 +273,8 @@ SQL
WHERE oid IN (
SELECT indexrelid
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';
}
......@@ -437,7 +443,12 @@ SQL
$oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
$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();
// SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type
......@@ -468,7 +479,8 @@ SQL
$seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName);
$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 . "')";
$sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} else {
......@@ -481,7 +493,10 @@ SQL
$newComment = $this->getColumnComment($column);
$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(
$diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this),
......@@ -493,7 +508,8 @@ SQL
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;
}
......
......@@ -65,8 +65,12 @@ class SQLServer2012Platform extends AbstractPlatform
return sprintf('CONVERT(%s, %s)', $dataType, $expression);
}
protected function getDateArithmeticIntervalExpression(string $date, string $operator, string $interval, string $unit): string
{
protected function getDateArithmeticIntervalExpression(
string $date,
string $operator,
string $interval,
string $unit
): string {
$factorClause = '';
if ($operator === '-') {
......@@ -222,10 +226,9 @@ class SQLServer2012Platform extends AbstractPlatform
if ($index instanceof Index) {
$index = $index->getQuotedName($this);
} elseif (! is_string($index)) {
throw new InvalidArgumentException(sprintf(
'AbstractPlatform::getDropIndexSQL() expects $index parameter to be a string or an instanceof %s.',
Index::class
));
throw new InvalidArgumentException(
__METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
);
}
if (! isset($table)) {
......@@ -299,7 +302,8 @@ SQL
$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;
......@@ -544,7 +548,10 @@ SQL
$queryParts[] = 'ALTER COLUMN ' .
$this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
if (! isset($columnDef['default']) || (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))) {
if (
! isset($columnDef['default'])
|| (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))
) {
continue;
}
......@@ -868,7 +875,8 @@ SQL
{
// "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
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";
}
public function getListTableColumnsSQL(string $table, ?string $database = null): string
......@@ -1011,15 +1019,6 @@ SQL
}
}
/** 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 . " + ']%'";
if ($mode === TrimMode::LEADING) {
......@@ -1027,10 +1026,13 @@ SQL
}
if ($mode === 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))';
}
public function getConcatExpression(string ...$string): string
......
This diff is collapsed.
......@@ -820,7 +820,12 @@ class QueryBuilder
*/
public function andWhere($predicate, ...$predicates): self
{
$this->where = $this->appendToPredicate($this->where, CompositeExpression::TYPE_AND, $predicate, ...$predicates);
$this->where = $this->appendToPredicate(
$this->where,
CompositeExpression::TYPE_AND,
$predicate,
...$predicates
);
$this->state = self::STATE_DIRTY;
......@@ -988,7 +993,12 @@ class QueryBuilder
*/
public function andHaving($predicate, ...$predicates): self
{
$this->having = $this->appendToPredicate($this->having, CompositeExpression::TYPE_AND, $predicate, ...$predicates);
$this->having = $this->appendToPredicate(
$this->having,
CompositeExpression::TYPE_AND,
$predicate,
...$predicates
);
$this->state = self::STATE_DIRTY;
......@@ -1006,7 +1016,12 @@ class QueryBuilder
*/
public function orHaving($predicate, ...$predicates): self
{
$this->having = $this->appendToPredicate($this->having, CompositeExpression::TYPE_OR, $predicate, ...$predicates);
$this->having = $this->appendToPredicate(
$this->having,
CompositeExpression::TYPE_OR,
$predicate,
...$predicates
);
$this->state = self::STATE_DIRTY;
......@@ -1211,7 +1226,8 @@ class QueryBuilder
*/
private function getSQLForUpdate(): string
{
$query = 'UPDATE ' . $this->table . ' SET ' . implode(', ', $this->set);
$query = 'UPDATE ' . $this->table
. ' SET ' . implode(', ', $this->set);
if ($this->where !== null) {
$query .= ' WHERE ' . $this->where;
......
......@@ -72,7 +72,12 @@ class SQLParserUtils
$statement,
':',
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);
}
);
......@@ -81,8 +86,12 @@ class SQLParserUtils
/**
* @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) {
return [];
}
......
......@@ -509,7 +509,8 @@ abstract class AbstractSchemaManager
/**
* 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.
*
* @throws DBALException
......@@ -615,7 +616,8 @@ abstract class AbstractSchemaManager
/**
* Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition.
*
* @param array<int, array<string, mixed>> $namespaces The list of namespace names in the native DBMS data definition.
* @param array<int, array<string, mixed>> $namespaces The list of namespace names
* in the native DBMS data definition.
*
* @return array<int, string>
*/
......@@ -789,7 +791,14 @@ abstract class AbstractSchemaManager
}
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 === null) {
......
......@@ -26,8 +26,12 @@ class ColumnDiff
/**
* @param array<string> $changedProperties
*/
public function __construct(string $oldColumnName, Column $column, array $changedProperties = [], ?Column $fromColumn = null)
{
public function __construct(
string $oldColumnName,
Column $column,
array $changedProperties = [],
?Column $fromColumn = null
) {
$this->oldColumnName = $oldColumnName;
$this->column = $column;
$this->changedProperties = $changedProperties;
......
......@@ -69,7 +69,11 @@ class Comparator
if (! $fromSchema->hasTable($tableName)) {
$diff->newTables[$tableName] = $toSchema->getTable($tableName);
} else {
$tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName));
$tableDifferences = $this->diffTable(
$fromSchema->getTable($tableName),
$toSchema->getTable($tableName)
);
if ($tableDifferences !== null) {
$diff->changedTables[$tableName] = $tableDifferences;
}
......@@ -215,7 +219,8 @@ class Comparator
continue;
}
$columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties);
$columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties);
$columnDiff->fromColumn = $column;
$tableDifferences->changedColumns[$column->getName()] = $columnDiff;
$changes++;
......@@ -377,11 +382,17 @@ class Comparator
public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2): bool
{
if (array_map('strtolower', $key1->getUnquotedLocalColumns()) !== array_map('strtolower', $key2->getUnquotedLocalColumns())) {
if (
array_map('strtolower', $key1->getUnquotedLocalColumns())
!== array_map('strtolower', $key2->getUnquotedLocalColumns())
) {
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;
}
......
......@@ -62,8 +62,13 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* @param string $name Name of the foreign key constraint.
* @param array<string, mixed> $options Options associated with the foreign key constraint.
*/
public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, string $name = '', array $options = [])
{
public function __construct(
array $localColumnNames,
$foreignTableName,
array $foreignColumnNames,
string $name = '',
array $options = []
) {
$this->_setName($name);
$this->_localColumnNames = $this->createIdentifierMap($localColumnNames);
......
......@@ -49,8 +49,14 @@ class Index extends AbstractAsset implements Constraint
* @param array<int, string> $flags
* @param array<string, mixed> $options
*/
public function __construct(?string $name, array $columns, bool $isUnique = false, bool $isPrimary = false, array $flags = [], array $options = [])
{
public function __construct(
?string $name,
array $columns,
bool $isUnique = false,
bool $isPrimary = false,
array $flags = [],
array $options = []
) {
$isUnique = $isUnique || $isPrimary;
if ($name !== null) {
......@@ -154,7 +160,10 @@ class Index extends AbstractAsset implements Constraint
$sameColumns = true;
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;
}
......@@ -218,7 +227,9 @@ class Index extends AbstractAsset implements Constraint
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);
}
/**
......@@ -285,7 +296,11 @@ class Index extends AbstractAsset implements Constraint
*/
private function samePartialIndex(Index $other): bool
{
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;
}
......
......@@ -46,7 +46,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
*/
public function getSchemaNames(): array
{
return $this->_conn->fetchFirstColumn("SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'");
return $this->_conn->fetchFirstColumn(
"SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"
);
}
/**
......@@ -303,7 +305,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
if (! isset($sequence['increment_by'], $sequence['min_value'])) {
/** @var string[] $data */
$data = $this->_conn->fetchAssociative('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
$data = $this->_conn->fetchAssociative(
'SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName)
);
$sequence += $data;
}
......@@ -330,7 +334,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$matches = [];
$autoincrement = false;
if ($tableColumn['default'] !== null && preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches) === 1) {
if (
$tableColumn['default'] !== null
&& preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches) === 1
) {
$tableColumn['sequence'] = $matches[1];
$tableColumn['default'] = null;
$autoincrement = true;
......
......@@ -169,20 +169,22 @@ class SQLServerSchemaManager extends AbstractSchemaManager
$foreignKeys = [];
foreach ($tableForeignKeys as $tableForeignKey) {
if (! isset($foreignKeys[$tableForeignKey['ForeignKey']])) {
$foreignKeys[$tableForeignKey['ForeignKey']] = [
$name = $tableForeignKey['ForeignKey'];
if (! isset($foreignKeys[$name])) {
$foreignKeys[$name] = [
'local_columns' => [$tableForeignKey['ColumnName']],
'foreign_table' => $tableForeignKey['ReferenceTableName'],
'foreign_columns' => [$tableForeignKey['ReferenceColumnName']],
'name' => $tableForeignKey['ForeignKey'],
'name' => $name,
'options' => [
'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']),
'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']),
],
];
} else {
$foreignKeys[$tableForeignKey['ForeignKey']]['local_columns'][] = $tableForeignKey['ColumnName'];
$foreignKeys[$tableForeignKey['ForeignKey']]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName'];
$foreignKeys[$name]['local_columns'][] = $tableForeignKey['ColumnName'];
$foreignKeys[$name]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName'];
}
}
......
......@@ -71,8 +71,12 @@ class SchemaDiff
* @param array<string, TableDiff> $changedTables
* @param array<string, Table> $removedTables
*/
public function __construct(array $newTables = [], array $changedTables = [], array $removedTables = [], ?Schema $fromSchema = null)
{
public function __construct(
array $newTables = [],
array $changedTables = [],
array $removedTables = [],
?Schema $fromSchema = null
) {
$this->newTables = $newTables;
$this->changedTables = $changedTables;
$this->removedTables = $removedTables;
......
......@@ -11,6 +11,7 @@ use Doctrine\DBAL\Types\TextType;
use Doctrine\DBAL\Types\Type;
use function array_change_key_case;
use function array_merge;
use function array_reverse;
use function array_values;
use function assert;
......@@ -151,10 +152,13 @@ class SqliteSchemaManager extends AbstractSchemaManager
}
foreach ($tableForeignKeys as $key => $value) {
$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]['deferred'] = isset($deferred[$id]) && strtolower($deferred[$id]) === 'deferred';
$id = $value['id'];
$tableForeignKeys[$key] = array_merge($tableForeignKeys[$key], [
'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',
]);
}
}
......@@ -437,7 +441,8 @@ class SqliteSchemaManager extends AbstractSchemaManager
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';
if (preg_match($pattern, $sql, $match) !== 1) {
......@@ -468,8 +473,8 @@ CREATE\sTABLE # Match "CREATE TABLE"
private function parseColumnCommentFromSQL(string $column, string $sql): string
{
$pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column)
. '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i';
$pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column))
. '\W|\W' . preg_quote($column) . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i';
if (preg_match($pattern, $sql, $match) !== 1) {
return '';
......
......@@ -136,8 +136,12 @@ class Table extends AbstractAsset
*
* @throws SchemaException
*/
public function addUniqueConstraint(array $columnNames, ?string $indexName = null, array $flags = [], array $options = []): self
{
public function addUniqueConstraint(
array $columnNames,
?string $indexName = null,
array $flags = [],
array $options = []
): self {
if ($indexName === null) {
$indexName = $this->_generateIdentifierName(
array_merge([$this->getName()], $columnNames),
......@@ -154,8 +158,12 @@ class Table extends AbstractAsset
* @param array<int, string> $flags
* @param array<string, mixed> $options
*/
public function addIndex(array $columnNames, ?string $indexName = null, array $flags = [], array $options = []): self
{
public function addIndex(
array $columnNames,
?string $indexName = null,
array $flags = [],
array $options = []
): self {
if ($indexName === null) {
$indexName = $this->_generateIdentifierName(
array_merge([$this->getName()], $columnNames),
......@@ -330,8 +338,13 @@ class Table extends AbstractAsset
*
* @throws SchemaException
*/
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = [], ?string $name = null): self
{
public function addForeignKeyConstraint(
$foreignTable,
array $localColumnNames,
array $foreignColumnNames,
array $options = [],
?string $name = null
): self {
if ($name === null) {
$name = $this->_generateIdentifierName(
array_merge((array) $this->getName(), $localColumnNames),
......@@ -839,8 +852,12 @@ class Table extends AbstractAsset
*
* @throws SchemaException
*/
private function _createUniqueConstraint(array $columns, string $indexName, array $flags = [], array $options = []): UniqueConstraint
{
private function _createUniqueConstraint(
array $columns,
string $indexName,
array $flags = [],
array $options = []
): UniqueConstraint {
if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName)) === 1) {
throw IndexNameInvalid::new($indexName);
}
......@@ -867,8 +884,14 @@ class Table extends AbstractAsset
*
* @throws SchemaException
*/
private function _createIndex(array $columns, string $indexName, bool $isUnique, bool $isPrimary, array $flags = [], array $options = []): Index
{
private function _createIndex(
array $columns,
string $indexName,
bool $isUnique,
bool $isPrimary,
array $flags = [],
array $options = []
): Index {
if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName)) === 1) {
throw IndexNameInvalid::new($indexName);
}
......
......@@ -61,17 +61,23 @@ class Graphviz extends AbstractVisitor
$label = '<<TABLE CELLSPACING="0" BORDER="1" ALIGN="LEFT">';
// 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
foreach ($table->getColumns() as $column) {
$columnLabel = $column->getName();
$label .= '<TR>';
$label .= '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">';
$label .= '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>';
$label .= '</TD><TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec"><FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">' . strtolower($column->getType()->getName()) . '</FONT></TD>';
$label .= '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">';
$label .= '<TR>'
. '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">'
. '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="12">' . $columnLabel . '</FONT>'
. '</TD>'
. '<TD BORDER="0" ALIGN="LEFT" BGCOLOR="#eeeeec">'
. '<FONT COLOR="#2e3436" FACE="Helvetica" POINT-SIZE="10">'
. strtolower($column->getType()->getName())
. '</FONT>'
. '</TD>'
. '<TD BORDER="0" ALIGN="RIGHT" BGCOLOR="#eeeeec" PORT="col' . $column->getName() . '">';
$primaryKey = $table->getPrimaryKey();
......
......@@ -137,7 +137,10 @@ EOT
$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();
$visitor = new ReservedKeywordsValidator($keywords);
......@@ -145,7 +148,12 @@ EOT
$violations = $visitor->getViolations();
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) {
$output->write(' - ' . $violation, true);
}
......
......@@ -62,7 +62,11 @@ class DateTimeType extends Type implements PhpDateTimeMappingType
}
if ($val === false) {
throw InvalidFormat::new($value, $this->getName(), $platform->getDateTimeFormatString());
throw InvalidFormat::new(
$value,
$this->getName(),
$platform->getDateTimeFormatString()
);
}
return $val;
......
......@@ -54,7 +54,11 @@ class DateTimeTzType extends Type implements PhpDateTimeMappingType
return $value->format($platform->getDateTimeTzFormatString());
}
throw InvalidType::new($value, $this->getName(), ['null', 'DateTime']);
throw InvalidType::new(
$value,
$this->getName(),
['null', 'DateTime']
);
}
/**
......@@ -68,7 +72,11 @@ class DateTimeTzType extends Type implements PhpDateTimeMappingType
$val = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value);
if ($val === false) {
throw InvalidFormat::new($value, $this->getName(), $platform->getDateTimeTzFormatString());
throw InvalidFormat::new(
$value,
$this->getName(),
$platform->getDateTimeTzFormatString()
);
}
return $val;
......
......@@ -55,7 +55,11 @@ class DateType extends Type
$val = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value);
if ($val === false) {
throw InvalidFormat::new($value, $this->getName(), $platform->getDateFormatString());
throw InvalidFormat::new(
$value,
$this->getName(),
$platform->getDateFormatString()
);
}
return $val;
......
......@@ -18,6 +18,10 @@ final class TypeNotRegistered extends DBALException implements TypesException
{
public static function new(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)
));
}
}
......@@ -55,7 +55,11 @@ class TimeType extends Type
$val = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value);
if ($val === false) {
throw InvalidFormat::new($value, $this->getName(), $platform->getTimeFormatString());
throw InvalidFormat::new(
$value,
$this->getName(),
$platform->getTimeFormatString()
);
}
return $val;
......
......@@ -149,7 +149,12 @@ class ConnectionTest extends TestCase
public function testDriverExceptionIsWrapped(callable $callback): void
{
$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([
'driver' => 'pdo_sqlite',
......
......@@ -6,6 +6,7 @@ namespace Doctrine\DBAL\Tests;
use Doctrine\DBAL\Exception\DriverRequired;
use Doctrine\DBAL\Exception\InvalidPlatformType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use PHPUnit\Framework\TestCase;
use stdClass;
......@@ -33,7 +34,8 @@ class DBALExceptionTest extends TestCase
$exception = InvalidPlatformType::new(new stdClass());
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()
);
}
......@@ -43,7 +45,7 @@ class DBALExceptionTest extends TestCase
$exception = InvalidPlatformType::new('some string');
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 ' . AbstractPlatform::class . '. Got string.',
$exception->getMessage()
);
}
......
......@@ -47,7 +47,8 @@ class EasyConnectStringTest extends TestCase
'service' => true,
'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' => [
[
......@@ -57,7 +58,8 @@ class EasyConnectStringTest extends TestCase
'instancename' => 'SALES',
'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)))',
],
];
}
......
......@@ -23,8 +23,11 @@ class ConvertPositionalToNamedPlaceholdersTest extends TestCase
*
* @dataProvider positionalToNamedPlaceholdersProvider
*/
public function testConvertPositionalToNamedParameters(string $inputSQL, string $expectedOutputSQL, array $expectedOutputParamsMap): void
{
public function testConvertPositionalToNamedParameters(
string $inputSQL,
string $expectedOutputSQL,
array $expectedOutputParamsMap
): void {
[$statement, $params] = ($this->convertPositionalToNamedPlaceholders)($inputSQL);
self::assertEquals($expectedOutputSQL, $statement);
......
......@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Exception;
use Doctrine\DBAL\Exception\InvalidPlatformType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use PHPUnit\Framework\TestCase;
use stdClass;
......@@ -18,7 +19,7 @@ class InvalidPlatformTypeTest extends TestCase
$exception = InvalidPlatformType::new(new stdClass());
self::assertSame(
'Option "platform" must be a subtype of Doctrine\DBAL\Platforms\AbstractPlatform, instance of stdClass given.',
'Option "platform" must be a subtype of ' . AbstractPlatform::class . ', instance of stdClass given.',
$exception->getMessage()
);
}
......@@ -31,7 +32,7 @@ class InvalidPlatformTypeTest extends TestCase
$exception = InvalidPlatformType::new('some string');
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 ' . AbstractPlatform::class . '. Got string.',
$exception->getMessage()
);
}
......
......@@ -142,7 +142,9 @@ class BlobTest extends FunctionalTestCase
self::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;
$stmt->bindParam(1, $stream, ParameterType::LARGE_OBJECT);
......
......@@ -140,7 +140,7 @@ class ConnectionTest extends FunctionalTestCase
self::assertFalse($this->connection->isRollbackOnly());
try {
$this->connection->setNestTransactionsWithSavepoints(false);
self::fail('Should not be able to disable savepoints in usage for nested transactions inside an open transaction.');
self::fail('Should not be able to disable savepoints in usage inside a nested open transaction.');
} catch (ConnectionException $e) {
self::assertTrue($this->connection->getNestTransactionsWithSavepoints());
}
......
......@@ -49,7 +49,12 @@ class DataAccessTest extends FunctionalTestCase
$sm = $this->connection->getSchemaManager();
$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;
}
......@@ -183,7 +188,7 @@ class DataAccessTest extends FunctionalTestCase
public function testFetchNoResult(): void
{
self::assertFalse(
$this->connection->executeQuery('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1])->fetchAssociative()
$this->connection->fetchAssociative('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1])
);
}
......@@ -328,7 +333,11 @@ class DataAccessTest extends FunctionalTestCase
public function testNativeArrayListSupport(): void
{
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',
]);
}
$result = $this->connection->executeQuery(
......@@ -682,8 +691,13 @@ class DataAccessTest extends FunctionalTestCase
* @param int $interval Interval value
* @param string $expected Expected value
*/
private function assertDateExpression(callable $buildQuery, callable $bindParams, callable $expression, int $interval, string $expected): void
{
private function assertDateExpression(
callable $buildQuery,
callable $bindParams,
callable $expression,
int $interval,
string $expected
): void {
$connection = $this->connection;
$platform = $connection->getDatabasePlatform();
......
......@@ -30,11 +30,6 @@ class ConnectionTest extends FunctionalTestCase
self::markTestSkipped('MySQLi only test.');
}
protected function tearDown(): void
{
parent::tearDown();
}
public function testSupportedDriverOptions(): void
{
$this->expectNotToPerformAssertions();
......
......@@ -33,8 +33,11 @@ class DriverTest extends AbstractDriverTest
/**
* @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['dbname'] = $databaseName;
$params['default_dbname'] = $defaultDatabaseName;
......
......@@ -74,7 +74,11 @@ class ModifyLimitQueryTest extends FunctionalTestCase
$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([1, 1, 1], $sql, 3, 2);
......@@ -122,7 +126,8 @@ class ModifyLimitQueryTest extends FunctionalTestCase
$this->connection->insert('modify_limit_table', ['test_int' => 3]);
$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], $sql, 2, 0);
......@@ -176,8 +181,13 @@ SQL;
/**
* @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();
$data = [];
foreach ($this->connection->fetchAllAssociative($p->modifyLimitQuery($sql, $limit, $offset)) as $row) {
......
......@@ -42,8 +42,17 @@ class PortabilityTest extends FunctionalTestCase
$sm = $this->connection->getSchemaManager();
$sm->createTable($table);
$this->connection->insert('portability_table', ['Test_Int' => 1, 'Test_String' => 'foo', 'Test_Null' => '']);
$this->connection->insert('portability_table', ['Test_Int' => 2, 'Test_String' => 'foo ', 'Test_Null' => null]);
$this->connection->insert('portability_table', [
'Test_Int' => 1,
'Test_String' => 'foo',
'Test_Null' => '',
]);
$this->connection->insert('portability_table', [
'Test_Int' => 2,
'Test_String' => 'foo ',
'Test_Null' => null,
]);
} catch (Throwable $e) {
}
}
......@@ -113,7 +122,7 @@ class PortabilityTest extends FunctionalTestCase
));
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::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.');
}
......
......@@ -21,7 +21,11 @@ use const CASE_LOWER;
class ResultCacheTest extends FunctionalTestCase
{
/** @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 */
private $sqlLogger;
......@@ -99,7 +103,12 @@ class ResultCacheTest extends FunctionalTestCase
$numExpectedResult[] = array_values($v);
}
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$data = $this->hydrateViaFetchAll($stmt, static function (Result $result): array {
return $result->fetchAllAssociative();
......@@ -107,7 +116,12 @@ class ResultCacheTest extends FunctionalTestCase
self::assertEquals($this->expectedResult, $data);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$data = $this->hydrateViaFetchAll($stmt, static function (Result $result): array {
return $result->fetchAllNumeric();
......@@ -121,10 +135,22 @@ class ResultCacheTest extends FunctionalTestCase
*/
public function testFetchViaIteration(callable $fetch, callable $fetchAll): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$data = $this->hydrateViaFetchAll($stmt, $fetchAll);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$iterator = $this->hydrateViaIteration($stmt, $fetch);
self::assertEquals($data, $iterator);
......@@ -132,12 +158,22 @@ class ResultCacheTest extends FunctionalTestCase
public function testFetchAndFinishSavesCache(): void
{
$result = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$result = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
while (($row = $result->fetchAssociative()) !== false) {
}
$result = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$result = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
while (($row = $result->fetchNumeric()) !== false) {
}
......@@ -147,11 +183,21 @@ class ResultCacheTest extends FunctionalTestCase
public function testDontFinishNoCache(): void
{
$result = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$result = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$result->fetchAssociative();
$result = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$result = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
$this->hydrateViaIteration($result, static function (Result $result) {
return $result->fetchNumeric();
......@@ -163,7 +209,8 @@ class ResultCacheTest extends FunctionalTestCase
public function testFetchAllSavesCache(): void
{
$layerCache = new ArrayCache();
$result = $this->connection->executeQuery(
$result = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
......@@ -194,13 +241,23 @@ class ResultCacheTest extends FunctionalTestCase
*/
private function assertCacheNonCacheSelectSameFetchModeAreEqual(array $expectedResult, callable $fetchMode): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
self::assertEquals(2, $stmt->columnCount());
$data = $this->hydrateViaIteration($stmt, $fetchMode);
self::assertEquals($expectedResult, $data);
$stmt = $this->connection->executeQuery('SELECT * FROM caching ORDER BY test_int ASC', [], [], new QueryCacheProfile(0, 'testcachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching ORDER BY test_int ASC',
[],
[],
new QueryCacheProfile(0, 'testcachekey')
);
self::assertEquals(2, $stmt->columnCount());
$data = $this->hydrateViaIteration($stmt, $fetchMode);
......@@ -210,12 +267,24 @@ class ResultCacheTest extends FunctionalTestCase
public function testEmptyResultCache(): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'emptycachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$this->hydrateViaIteration($stmt, static function (Result $result) {
return $result->fetchAssociative();
});
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'emptycachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$this->hydrateViaIteration($stmt, static function (Result $result) {
return $result->fetchAssociative();
});
......@@ -225,14 +294,26 @@ class ResultCacheTest extends FunctionalTestCase
public function testChangeCacheImpl(): void
{
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'emptycachekey'));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey')
);
$this->hydrateViaIteration($stmt, static function (Result $result) {
return $result->fetchAssociative();
});
$secondCache = new ArrayCache();
$stmt = $this->connection->executeQuery('SELECT * FROM caching WHERE test_int > 500', [], [], new QueryCacheProfile(0, 'emptycachekey', $secondCache));
$stmt = $this->connection->executeQuery(
'SELECT * FROM caching WHERE test_int > 500',
[],
[],
new QueryCacheProfile(10, 'emptycachekey', $secondCache)
);
$this->hydrateViaIteration($stmt, static function (Result $result) {
return $result->fetchAssociative();
});
......
......@@ -9,6 +9,7 @@ use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception\DatabaseRequired;
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
......@@ -249,7 +250,10 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
public function testColumnCharsetChange(): void
{
$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->getColumn('col_string')->setPlatformOption('charset', 'ascii');
......@@ -258,7 +262,11 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$toSchema = new Schema([$diffTable]);
$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
......@@ -563,7 +571,9 @@ SQL;
$schemaManager = $connection->getSchemaManager();
$this->expectException(DatabaseRequired::class);
$this->expectExceptionMessage('A database is required for the method: Doctrine\DBAL\Schema\AbstractSchemaManager::listTableColumns');
$this->expectExceptionMessage(
'A database is required for the method: ' . AbstractSchemaManager::class . '::listTableColumns'
);
$schemaManager->listTableColumns('users');
}
......
......@@ -258,7 +258,10 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
// Adding a primary key on already indexed columns
// 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');
......@@ -286,6 +289,8 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
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."
);
}
}
......@@ -125,7 +125,10 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertNotNull($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);
$tableFinal = $this->schemaManager->listTableDetails('autoinc_table_drop');
......@@ -169,10 +172,12 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
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->executeStatement($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->executeStatement($sql);
$table = $this->schemaManager->listTableDetails('dbal91_something');
......@@ -236,13 +241,14 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
}
$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++) {
self::assertEquals(['foreign_key_test' . $i], array_map('strtolower', $fkeys[$i]->getLocalColumns()));
self::assertEquals(['id'], array_map('strtolower', $fkeys[$i]->getForeignColumns()));
self::assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName()));
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 {
self::assertEquals($foreignKeys[$i]->getOption('onDelete'), $fkeys[$i]->getOption('onDelete'));
}
......@@ -472,8 +478,11 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$c = new Comparator();
$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::assertSame(['ALTER TABLE autoinc_type_modification ALTER id TYPE ' . $expected], $this->connection->getDatabasePlatform()->getAlterTableSQL($diff));
self::assertInstanceOf(TableDiff::class, $diff);
self::assertSame(
['ALTER TABLE autoinc_type_modification ALTER id TYPE ' . $expected],
$this->connection->getDatabasePlatform()->getAlterTableSQL($diff)
);
$this->schemaManager->alterTable($diff);
$tableFinal = $this->schemaManager->listTableDetails('autoinc_type_modification');
......
......@@ -27,7 +27,13 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->createTable($table);
$diff = new TableDiff('sqlsrv_drop_column', [], [], ['todrop' => new Column('todrop', Type::getType('decimal'))]);
$diff = new TableDiff(
'sqlsrv_drop_column',
[],
[],
['todrop' => new Column('todrop', Type::getType('decimal'))]
);
$this->schemaManager->alterTable($diff);
$columns = $this->schemaManager->listTableColumns('sqlsrv_drop_column');
......@@ -42,7 +48,8 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->dropAndCreateTable($table);
$columns = $this->schemaManager->listTableColumns($tableName);
self::assertTrue($columns['test']->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['test']->hasPlatformOption('collation'));
$column->setPlatformOption('collation', $collation = 'Icelandic_CS_AS');
......@@ -106,9 +113,15 @@ class SQLServerSchemaManagerTest extends SchemaManagerFunctionalTestCase
),
'df_string_3' => new ColumnDiff(
'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'],
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',
......
......@@ -204,7 +204,9 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
$namespaces = array_map('strtolower', $namespaces);
if (! in_array('test_create_schema', $namespaces, true)) {
$this->connection->executeStatement($this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
$this->connection->executeStatement(
$this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema')
);
$namespaces = $this->schemaManager->listNamespaceNames();
$namespaces = array_map('strtolower', $namespaces);
......@@ -385,7 +387,9 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
public function testDiffListTableColumns(): void
{
if ($this->schemaManager->getDatabasePlatform()->getName() === 'oracle') {
self::markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).');
self::markTestSkipped(
'Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).'
);
}
$offlineTable = $this->createListTableColumns();
......@@ -466,7 +470,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
self::assertEquals(['foreign_key_test'], array_map('strtolower', $fkConstraint->getColumns()));
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
......@@ -565,7 +569,10 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
$table = $this->schemaManager->listTableDetails('alter_table');
self::assertEquals(2, count($table->getIndexes()));
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->fromTable = $table;
......@@ -577,15 +584,22 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
self::assertEquals(2, count($table->getIndexes()));
self::assertTrue($table->hasIndex('bar_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')->isUnique());
$tableDiff = new TableDiff('alter_table');
$tableDiff->fromTable = $table;
$tableDiff->removedIndexes['bar_idx'] = new Index('bar_idx', ['foo', 'foreign_key_test']);
$fk = new ForeignKeyConstraint(['foreign_key_test'], 'alter_table_foreign', ['id']);
$tableDiff->addedForeignKeys[] = $fk;
$tableDiff->addedForeignKeys[] = new ForeignKeyConstraint(
['foreign_key_test'],
'alter_table_foreign',
['id']
);
$this->schemaManager->alterTable($tableDiff);
$table = $this->schemaManager->listTableDetails('alter_table');
......@@ -1198,7 +1212,9 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
public function testGenerateAnIndexWithPartialColumnLength(): void
{
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');
......@@ -1260,7 +1276,11 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
$diff = Comparator::compareSchemas($offlineSchema, $schema);
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;
}
......
......@@ -177,8 +177,11 @@ SQL;
/**
* @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';
$offlineTable = new Table($tableName);
......
......@@ -71,8 +71,8 @@ class TemporaryTableTest extends FunctionalTestCase
$this->connection->rollBack();
$rows = $this->connection->fetchAllAssociative('SELECT * FROM nontemporary');
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.');
// In an event of an error this result has one row, because of an implicit commit
self::assertEquals([], $this->connection->fetchAllAssociative('SELECT * FROM nontemporary'));
}
public function testCreateTemporaryTableNotAutoCommitTransaction(): void
......@@ -116,7 +116,7 @@ class TemporaryTableTest extends FunctionalTestCase
} catch (Throwable $e) {
}
$rows = $this->connection->fetchAllAssociative('SELECT * FROM nontemporary');
self::assertEquals([], $rows, 'In an event of an error this result has one row, because of an implicit commit.');
// In an event of an error this result has one row, because of an implicit commit
self::assertEquals([], $this->connection->fetchAllAssociative('SELECT * FROM nontemporary'));
}
}
......@@ -243,7 +243,10 @@ class TypeConversionTest extends FunctionalTestCase
{
$columnName = 'test_' . $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]);
......
......@@ -125,9 +125,23 @@ class WriteTest extends FunctionalTestCase
{
$this->insertRows();
self::assertEquals(1, $this->connection->update('write_table', ['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']));
self::assertEquals(1, $this->connection->update(
'write_table',
['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
......@@ -171,8 +185,13 @@ class WriteTest extends FunctionalTestCase
public function testLastInsertIdNoSequenceGiven(): void
{
if (! $this->connection->getDatabasePlatform()->supportsSequences() || $this->connection->getDatabasePlatform()->supportsIdentityColumns()) {
self::markTestSkipped("Test only works consistently on platforms that support sequences and don't support identity columns.");
if (
! $this->connection->getDatabasePlatform()->supportsSequences()
|| $this->connection->getDatabasePlatform()->supportsIdentityColumns()
) {
self::markTestSkipped(
"Test only works consistently on platforms that support sequences and don't support identity columns."
);
}
$this->expectException(DriverException::class);
......@@ -191,7 +210,10 @@ class WriteTest extends FunctionalTestCase
$data = $this->connection->fetchOne('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
......@@ -215,7 +237,10 @@ class WriteTest extends FunctionalTestCase
$data = $this->connection->fetchOne('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
......@@ -227,7 +252,13 @@ class WriteTest extends FunctionalTestCase
['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->fetchOne('SELECT test_string FROM write_table WHERE test_int = 30');
......@@ -286,7 +317,10 @@ class WriteTest extends FunctionalTestCase
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->fetchAllAssociative('SELECT * FROM write_table WHERE test_int = 30');
......
......@@ -108,7 +108,8 @@ abstract class FunctionalTestCase extends TestCase
$traceMsg .= $part['file'] . ':' . $part['line'] . PHP_EOL;
}
$message = '[' . get_class($t) . '] ' . $t->getMessage() . PHP_EOL . PHP_EOL . 'With queries:' . PHP_EOL . $queries . PHP_EOL . 'Trace:' . PHP_EOL . $traceMsg;
$message = '[' . get_class($t) . '] ' . $t->getMessage() . PHP_EOL . PHP_EOL
. 'With queries:' . PHP_EOL . $queries . PHP_EOL . 'Trace:' . PHP_EOL . $traceMsg;
throw new Exception($message, (int) $t->getCode(), $t);
}
......
......@@ -380,7 +380,10 @@ abstract class AbstractPlatformTestCase extends TestCase
->method('onSchemaCreateTableColumn');
$eventManager = new EventManager();
$eventManager->addEventListener([Events::onSchemaCreateTable, Events::onSchemaCreateTableColumn], $listenerMock);
$eventManager->addEventListener([
Events::onSchemaCreateTable,
Events::onSchemaCreateTableColumn,
], $listenerMock);
$this->platform->setEventManager($eventManager);
......@@ -635,27 +638,63 @@ abstract class AbstractPlatformTestCase extends TestCase
// Foreign table with reserved keyword as name (needs quotation).
$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).
$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).
$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);
self::assertEquals($this->getQuotedColumnInForeignKeySQL(), $sql);
......@@ -957,17 +996,32 @@ abstract class AbstractPlatformTestCase extends TestCase
$toTable = new Table('mytable');
$toTable->addColumn('unquoted', 'integer', ['comment' => 'Unquoted 1']); // unquoted -> unquoted
$toTable->addColumn('where', 'integer', ['comment' => 'Unquoted 2']); // unquoted -> reserved keyword
$toTable->addColumn('`foo`', 'integer', ['comment' => 'Unquoted 3']); // unquoted -> quoted
// unquoted -> unquoted
$toTable->addColumn('unquoted', 'integer', ['comment' => 'Unquoted 1']);
// 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
$toTable->addColumn('from', 'integer', ['comment' => 'Reserved keyword 2']); // reserved keyword -> reserved keyword
$toTable->addColumn('`bar`', 'integer', ['comment' => 'Reserved keyword 3']); // reserved keyword -> quoted
// reserved keyword -> reserved keyword
$toTable->addColumn('from', 'integer', ['comment' => 'Reserved keyword 2']);
$toTable->addColumn('quoted', 'integer', ['comment' => 'Quoted 1']); // quoted -> unquoted
$toTable->addColumn('and', 'integer', ['comment' => 'Quoted 2']); // quoted -> reserved keyword
$toTable->addColumn('`baz`', 'integer', ['comment' => 'Quoted 3']); // quoted -> quoted
// reserved keyword -> quoted
$toTable->addColumn('`bar`', 'integer', ['comment' => 'Reserved keyword 3']);
// 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();
......@@ -1255,7 +1309,9 @@ abstract class AbstractPlatformTestCase extends TestCase
}
$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->platform->getInlineColumnCommentSQL('unsupported');
......
......@@ -68,7 +68,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
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
......@@ -81,7 +82,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['onDelete' => 'CASCADE']
);
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)
);
......@@ -93,7 +95,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['match' => 'full']
);
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)
);
......@@ -105,7 +108,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['deferrable' => true]
);
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)
);
......@@ -117,7 +121,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['deferred' => true]
);
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)
);
......@@ -129,7 +134,8 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['deferred' => true]
);
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)
);
......@@ -141,18 +147,28 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
['deferrable' => true, 'deferred' => true, 'match' => 'full']
);
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)
);
}
public function testGeneratesSqlSnippets(): void
{
self::assertEquals('SIMILAR TO', $this->platform->getRegexpExpression(), 'Regular expression operator is not correct');
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
self::assertEquals('column1 || column2 || column3', $this->platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
self::assertEquals('SUBSTRING(column FROM 5)', $this->platform->getSubstringExpression('column', '5'), 'Substring expression without length is not correct');
self::assertEquals('SUBSTRING(column FROM 1 FOR 5)', $this->platform->getSubstringExpression('column', '1', '5'), 'Substring expression with length is not correct');
self::assertEquals('SIMILAR TO', $this->platform->getRegexpExpression());
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter());
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 1 FOR 5)',
$this->platform->getSubstringExpression('column', '1', '5')
);
}
public function testGeneratesTransactionCommands(): void
......@@ -188,7 +204,10 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
$column = $table->addColumn('id', 'integer');
$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)
);
}
/**
......@@ -401,10 +420,14 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
protected function getQuotedColumnInForeignKeySQL(): array
{
return [
'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" 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',
'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',
'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, '
. 'foo VARCHAR(255) NOT NULL, "bar" 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',
'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',
];
}
......@@ -454,8 +477,12 @@ abstract class AbstractPostgreSQLPlatformTestCase extends AbstractPlatformTestCa
/**
* @dataProvider pgBooleanProvider
*/
public function testConvertFromBoolean(string $databaseValue, string $prepareStatementValue, int $integerValue, bool $booleanValue): void
{
public function testConvertFromBoolean(
string $databaseValue,
string $prepareStatementValue,
int $integerValue,
bool $booleanValue
): void {
self::assertSame($booleanValue, $this->platform->convertFromBoolean($databaseValue));
}
......
This diff is collapsed.
......@@ -112,7 +112,8 @@ class OraclePlatformTest extends AbstractPlatformTestCase
{
return [
'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 RENAME TO userlist',
];
......@@ -122,13 +123,16 @@ class OraclePlatformTest extends AbstractPlatformTestCase
{
$this->expectException(DBALException::class);
self::assertEquals('RLIKE', $this->platform->getRegexpExpression(), 'Regular expression operator is not correct');
self::assertEquals('RLIKE', $this->platform->getRegexpExpression());
}
public function testGeneratesSqlSnippets(): void
{
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
self::assertEquals('column1 || column2 || column3', $this->platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
self::assertEquals('"', $this->platform->getIdentifierQuoteCharacter());
self::assertEquals(
'column1 || column2 || column3',
$this->platform->getConcatExpression('column1', 'column2', 'column3')
);
}
public function testGeneratesTransactionsCommands(): void
......@@ -277,13 +281,25 @@ class OraclePlatformTest extends AbstractPlatformTestCase
public function testModifyLimitQueryWithNonEmptyOffset(): void
{
$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
{
$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
......@@ -309,7 +325,17 @@ class OraclePlatformTest extends AbstractPlatformTestCase
$targets = [
sprintf('CREATE TABLE %s (%s NUMBER(10) NOT NULL)', $tableName, $columnName),
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,
......@@ -317,7 +343,20 @@ class OraclePlatformTest extends AbstractPlatformTestCase
),
sprintf('CREATE SEQUENCE %s_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1', $tableName),
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,
......@@ -425,10 +464,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase
protected function getQuotedColumnInForeignKeySQL(): array
{
return [
'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, "bar" VARCHAR2(255) NOT NULL)',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", 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")',
'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, '
. '"bar" VARCHAR2(255) NOT NULL)',
'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", 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")',
];
}
......@@ -477,7 +520,11 @@ class OraclePlatformTest extends AbstractPlatformTestCase
['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));
}
......
This diff is collapsed.
......@@ -70,8 +70,13 @@ class ConverterTest extends TestCase
*
* @dataProvider convertAssociativeProvider
*/
public function testConvertAssociative($row, bool $convertEmptyStringToNull, bool $rightTrimString, ?int $case, $expected): void
{
public function testConvertAssociative(
$row,
bool $convertEmptyStringToNull,
bool $rightTrimString,
?int $case,
$expected
): void {
self::assertSame(
$expected,
$this->createConverter($convertEmptyStringToNull, $rightTrimString, $case)
......
......@@ -175,7 +175,11 @@ class QueryBuilderTest extends TestCase
->orWhere('u.name = ?')
->andWhere('u.name = ?');
self::assertEquals('SELECT u.*, p.* FROM users u WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)', (string) $qb);
self::assertEquals(
'SELECT u.*, p.* FROM users u'
. ' WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)',
(string) $qb
);
}
public function testSelectGroupBy(): void
......@@ -247,7 +251,10 @@ class QueryBuilderTest extends TestCase
->having('u.name = ?')
->andHaving('u.username = ?');
self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)', (string) $qb);
self::assertEquals(
'SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)',
(string) $qb
);
}
public function testSelectHavingOrHaving(): void
......@@ -260,7 +267,10 @@ class QueryBuilderTest extends TestCase
->having('u.name = ?')
->orHaving('u.username = ?');
self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
self::assertEquals(
'SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)',
(string) $qb
);
}
public function testSelectOrHavingOrHaving(): void
......@@ -273,7 +283,10 @@ class QueryBuilderTest extends TestCase
->orHaving('u.name = ?')
->orHaving('u.username = ?');
self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
self::assertEquals(
'SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)',
(string) $qb
);
}
public function testSelectHavingAndOrHaving(): void
......@@ -287,7 +300,10 @@ class QueryBuilderTest extends TestCase
->orHaving('u.username = ?')
->andHaving('u.username = ?');
self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)', (string) $qb);
self::assertEquals(
'SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)',
(string) $qb
);
}
public function testSelectOrderBy(): void
......@@ -565,7 +581,10 @@ class QueryBuilderTest extends TestCase
->where('nt.lang = :lang AND n.deleted != 1');
$this->expectException(QueryException::class);
$this->expectExceptionMessage('The given alias "invalid" is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.');
$this->expectExceptionMessage(
'The given alias "invalid" is not part of any FROM or JOIN clause table. '
. 'The currently registered aliases are: news, nv.'
);
self::assertEquals('', $qb->getSQL());
}
......@@ -581,7 +600,13 @@ class QueryBuilderTest extends TestCase
->where('nt.lang = ?')
->andWhere('n.deleted = 0');
self::assertEquals("SELECT COUNT(DISTINCT news.id) FROM newspages news INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)", $qb->getSQL());
self::assertEquals(
'SELECT COUNT(DISTINCT news.id) FROM newspages news'
. " INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News'"
. ' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id'
. ' INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)',
$qb->getSQL()
);
}
public function testSelectWithMultipleFromAndJoins(): void
......@@ -596,7 +621,13 @@ class QueryBuilderTest extends TestCase
->where('u.id = a.user_id')
->andWhere('p.read = 1');
self::assertEquals('SELECT DISTINCT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles a INNER JOIN comments c ON c.article_id = a.id WHERE (u.id = a.user_id) AND (p.read = 1)', $qb->getSQL());
self::assertEquals(
'SELECT DISTINCT u.id FROM users u'
. ' INNER JOIN permissions p ON p.user_id = u.id, articles a'
. ' INNER JOIN comments c ON c.article_id = a.id'
. ' WHERE (u.id = a.user_id) AND (p.read = 1)',
$qb->getSQL()
);
}
public function testSelectWithJoinsWithMultipleOnConditionsParseOrder(): void
......@@ -709,7 +740,13 @@ class QueryBuilderTest extends TestCase
->where('users.id = articles.user_id')
->andWhere('p.read = 1');
self::assertEquals('SELECT DISTINCT users.id FROM users INNER JOIN permissions p ON p.user_id = users.id, articles INNER JOIN comments c ON c.article_id = articles.id WHERE (users.id = articles.user_id) AND (p.read = 1)', $qb->getSQL());
self::assertEquals(
'SELECT DISTINCT users.id FROM users'
. ' INNER JOIN permissions p ON p.user_id = users.id, articles'
. ' INNER JOIN comments c ON c.article_id = articles.id'
. ' WHERE (users.id = articles.user_id) AND (p.read = 1)',
$qb->getSQL()
);
}
public function testComplexSelectWithSomeTableAliases(): void
......@@ -722,7 +759,12 @@ class QueryBuilderTest extends TestCase
->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id');
self::assertEquals('SELECT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles INNER JOIN comments c ON c.article_id = articles.id', $qb->getSQL());
self::assertEquals(
'SELECT u.id FROM users u'
. ' INNER JOIN permissions p ON p.user_id = u.id, articles'
. ' INNER JOIN comments c ON c.article_id = articles.id',
$qb->getSQL()
);
}
public function testSelectAllFromTableWithoutTableAlias(): void
......@@ -796,7 +838,9 @@ class QueryBuilderTest extends TestCase
->join('a', 'table_b', 'a', 'a.fk_b = a.id');
$this->expectException(QueryException::class);
$this->expectExceptionMessage('The given alias "a" is not unique in FROM and JOIN clause table. The currently registered aliases are: a.');
$this->expectExceptionMessage(
'The given alias "a" is not unique in FROM and JOIN clause table. The currently registered aliases are: a.'
);
$qb->getSQL();
}
......
......@@ -43,9 +43,15 @@ class SQLParserUtilsTest extends TestCase
['SELECT "Doctrine\DBAL?" FROM foo WHERE bar = ?', [45]], // Ticket DBAL-558
['SELECT `Doctrine\DBAL?` FROM foo WHERE bar = ?', [45]], // Ticket DBAL-558
['SELECT [Doctrine\DBAL?] FROM foo WHERE bar = ?', [45]], // Ticket DBAL-558
["SELECT * FROM FOO WHERE bar = 'it\\'s a trap? \\\\' OR bar = ?\nAND baz = \"\\\"quote\\\" me on it? \\\\\" OR baz = ?", [58, 104]],
[
<<<'SQL'
SELECT * FROM FOO WHERE bar = 'it\'s a trap? \\' OR bar = ?
AND baz = "\"quote\" me on it? \\" OR baz = ?
SQL
,
[58, 104],
],
['SELECT * FROM foo WHERE foo = ? AND bar = ?', [1 => 42, 0 => 30]], // explicit keys
];
}
......@@ -66,16 +72,57 @@ class SQLParserUtilsTest extends TestCase
['SELECT :foo_id', [7 => 'foo_id']], // Ticket DBAL-231
['SELECT @rank := 1', []], // Ticket DBAL-398
['SELECT @rank := 1 AS rank, :foo AS foo FROM :bar', [27 => 'foo', 44 => 'bar']], // Ticket DBAL-398
['SELECT * FROM Foo WHERE bar > :start_date AND baz > :start_date', [30 => 'start_date', 52 => 'start_date']], // Ticket GH-113
['SELECT foo::date as date FROM Foo WHERE bar > :start_date AND baz > :start_date', [46 => 'start_date', 68 => 'start_date']], // Ticket GH-259
['SELECT `d.ns:col_name` FROM my_table d WHERE `d.date` >= :param1', [57 => 'param1']], // Ticket DBAL-552
['SELECT [d.ns:col_name] FROM my_table d WHERE [d.date] >= :param1', [57 => 'param1']], // Ticket DBAL-552
// Ticket GH-113
[
'SELECT * FROM Foo WHERE bar > :start_date AND baz > :start_date',
[
30 => 'start_date',
52 => 'start_date',
],
],
// Ticket GH-259
[
'SELECT foo::date as date FROM Foo WHERE bar > :start_date AND baz > :start_date',
[
46 => 'start_date',
68 => 'start_date',
],
],
// Ticket DBAL-552
[
'SELECT `d.ns:col_name` FROM my_table d WHERE `d.date` >= :param1',
[57 => 'param1'],
],
// Ticket DBAL-552
['SELECT [d.ns:col_name] FROM my_table d WHERE [d.date] >= :param1', [57 => 'param1']],
['SELECT * FROM foo WHERE jsonb_exists_any(foo.bar, ARRAY[:foo])', [56 => 'foo']], // Ticket GH-2295
['SELECT * FROM foo WHERE jsonb_exists_any(foo.bar, array[:foo])', [56 => 'foo']],
['SELECT table.column1, ARRAY[\'3\'] FROM schema.table table WHERE table.f1 = :foo AND ARRAY[\'3\']', [74 => 'foo']],
['SELECT table.column1, ARRAY[\'3\']::integer[] FROM schema.table table WHERE table.f1 = :foo AND ARRAY[\'3\']::integer[]', [85 => 'foo']],
['SELECT table.column1, ARRAY[:foo] FROM schema.table table WHERE table.f1 = :bar AND ARRAY[\'3\']', [28 => 'foo', 75 => 'bar']],
['SELECT table.column1, ARRAY[:foo]::integer[] FROM schema.table table WHERE table.f1 = :bar AND ARRAY[\'3\']::integer[]', [28 => 'foo', 86 => 'bar']],
['SELECT * FROM foo WHERE jsonb_exists_any(foo.bar, array[:foo])', [56 => 'foo']],[
'SELECT table.column1, ARRAY[\'3\'] FROM schema.table table WHERE table.f1 = :foo AND ARRAY[\'3\']',
[74 => 'foo'],
],
[
'SELECT table.column1, ARRAY[\'3\']::integer[] FROM schema.table table'
. ' WHERE table.f1 = :foo AND ARRAY[\'3\']::integer[]',
[85 => 'foo'],
],
[
'SELECT table.column1, ARRAY[:foo] FROM schema.table table WHERE table.f1 = :bar AND ARRAY[\'3\']',
[
28 => 'foo',
75 => 'bar',
],
],
[
'SELECT table.column1, ARRAY[:foo]::integer[] FROM schema.table table'
. ' WHERE table.f1 = :bar AND ARRAY[\'3\']::integer[]',
[
28 => 'foo',
86 => 'bar',
],
],
[
<<<'SQLDATA'
SELECT * FROM foo WHERE
......@@ -93,12 +140,60 @@ SQLDATA
189 => 'a_param3',
],
],
["SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE '\\\\') AND (data.description LIKE :condition_1 ESCAPE '\\\\') ORDER BY id ASC", [121 => 'condition_0', 174 => 'condition_1']],
['SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE "\\\\") AND (data.description LIKE :condition_1 ESCAPE "\\\\") ORDER BY id ASC', [121 => 'condition_0', 174 => 'condition_1']],
['SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE "\\\\") AND (data.description LIKE :condition_1 ESCAPE \'\\\\\') ORDER BY id ASC', [121 => 'condition_0', 174 => 'condition_1']],
['SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE `\\\\`) AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC', [121 => 'condition_0', 174 => 'condition_1']],
['SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE \'\\\\\') AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC', [121 => 'condition_0', 174 => 'condition_1']],
["SELECT * FROM Foo WHERE (foo.bar LIKE :condition_0 ESCAPE '\') AND (foo.baz = :condition_1) AND (foo.bak LIKE :condition_2 ESCAPE '\')", [38 => 'condition_0', 78 => 'condition_1', 110 => 'condition_2']],
[
'SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data'
. " WHERE (data.description LIKE :condition_0 ESCAPE '\\\\')"
. " AND (data.description LIKE :condition_1 ESCAPE '\\\\') ORDER BY id ASC",
[
121 => 'condition_0',
174 => 'condition_1',
],
],
[
'SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data'
. ' WHERE (data.description LIKE :condition_0 ESCAPE "\\\\")'
. ' AND (data.description LIKE :condition_1 ESCAPE "\\\\") ORDER BY id ASC',
[
121 => 'condition_0',
174 => 'condition_1',
],
],
[
'SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data'
. ' WHERE (data.description LIKE :condition_0 ESCAPE "\\\\")'
. ' AND (data.description LIKE :condition_1 ESCAPE \'\\\\\') ORDER BY id ASC',
[
121 => 'condition_0',
174 => 'condition_1',
],
],
[
'SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data'
. ' WHERE (data.description LIKE :condition_0 ESCAPE `\\\\`)'
. ' AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC',
[
121 => 'condition_0',
174 => 'condition_1',
],
],
[
'SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data'
. ' WHERE (data.description LIKE :condition_0 ESCAPE \'\\\\\')'
. ' AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC',
[
121 => 'condition_0',
174 => 'condition_1',
],
],
[
"SELECT * FROM Foo WHERE (foo.bar LIKE :condition_0 ESCAPE '\')"
. " AND (foo.baz = :condition_1) AND (foo.bak LIKE :condition_2 ESCAPE '\')",
[
38 => 'condition_0',
78 => 'condition_1',
110 => 'condition_2',
],
],
];
}
......
......@@ -76,7 +76,8 @@ class ComparatorTest extends TestCase
public function testCompareMissingTable(): void
{
$schemaConfig = new SchemaConfig();
$table = new Table('bugdb', ['integercolumn1' => new Column('integercolumn1', Type::getType('integer'))]);
$table = new Table('bugdb', ['integercolumn1' => new Column('integercolumn1', Type::getType('integer'))]);
$table->setSchemaConfig($schemaConfig);
$schema1 = new Schema([$table], [], $schemaConfig);
......@@ -90,7 +91,8 @@ class ComparatorTest extends TestCase
public function testCompareNewTable(): void
{
$schemaConfig = new SchemaConfig();
$table = new Table('bugdb', ['integercolumn1' => new Column('integercolumn1', Type::getType('integer'))]);
$table = new Table('bugdb', ['integercolumn1' => new Column('integercolumn1', Type::getType('integer'))]);
$table->setSchemaConfig($schemaConfig);
$schema1 = new Schema([], [], $schemaConfig);
......@@ -256,12 +258,12 @@ class ComparatorTest extends TestCase
$tableDiff = $c->diffTable($tableA, $tableB);
self::assertNotNull($tableDiff);
self::assertCount(1, $tableDiff->renamedColumns, 'we should have one rename datecolumn1 => new_datecolumn1.');
self::assertArrayHasKey('datecolumn1', $tableDiff->renamedColumns, "'datecolumn1' should be set to be renamed to new_datecolumn1");
self::assertCount(1, $tableDiff->addedColumns, "'new_datecolumn2' should be added");
self::assertArrayHasKey('new_datecolumn2', $tableDiff->addedColumns, "'new_datecolumn2' should be added, not created through renaming!");
self::assertCount(0, $tableDiff->removedColumns, 'Nothing should be removed.');
self::assertCount(0, $tableDiff->changedColumns, 'Nothing should be changed as all columns old & new have diff names.');
self::assertCount(1, $tableDiff->renamedColumns);
self::assertArrayHasKey('datecolumn1', $tableDiff->renamedColumns);
self::assertCount(1, $tableDiff->addedColumns);
self::assertArrayHasKey('new_datecolumn2', $tableDiff->addedColumns);
self::assertCount(0, $tableDiff->removedColumns);
self::assertCount(0, $tableDiff->changedColumns);
}
public function testCompareRemovedIndex(): void
......@@ -747,12 +749,12 @@ class ComparatorTest extends TestCase
$tableDiff = $c->diffTable($tableA, $tableB);
self::assertNotNull($tableDiff);
self::assertCount(1, $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
self::assertArrayHasKey('baz', $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
self::assertCount(2, $tableDiff->removedColumns, "'foo' and 'bar' should both be dropped, an ambiguity exists which one could be renamed to 'baz'.");
self::assertArrayHasKey('foo', $tableDiff->removedColumns, "'foo' should be removed.");
self::assertArrayHasKey('bar', $tableDiff->removedColumns, "'bar' should be removed.");
self::assertCount(0, $tableDiff->renamedColumns, 'no renamings should take place.');
self::assertCount(1, $tableDiff->addedColumns);
self::assertArrayHasKey('baz', $tableDiff->addedColumns);
self::assertCount(2, $tableDiff->removedColumns);
self::assertArrayHasKey('foo', $tableDiff->removedColumns);
self::assertArrayHasKey('bar', $tableDiff->removedColumns);
self::assertCount(0, $tableDiff->renamedColumns);
}
public function testDetectRenameIndex(): void
......@@ -1037,11 +1039,14 @@ class ComparatorTest extends TestCase
$table = $newSchema->createTable('foo');
$table->addColumn('id', 'string');
$expected = new SchemaDiff();
$expected->fromSchema = $oldSchema;
$tableDiff = $expected->changedTables['foo'] = new TableDiff('foo');
$tableDiff->fromTable = $tableFoo;
$columnDiff = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
$expected = new SchemaDiff();
$expected->fromSchema = $oldSchema;
$tableDiff = $expected->changedTables['foo'] = new TableDiff('foo');
$tableDiff->fromTable = $tableFoo;
$columnDiff = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
$columnDiff->fromColumn = $tableFoo->getColumn('id');
$columnDiff->changedProperties = ['type'];
......@@ -1059,11 +1064,14 @@ class ComparatorTest extends TestCase
$table = $newSchema->createTable('foo');
$table->addColumn('id', 'binary', ['length' => 42, 'fixed' => true]);
$expected = new SchemaDiff();
$expected->fromSchema = $oldSchema;
$tableDiff = $expected->changedTables['foo'] = new TableDiff('foo');
$tableDiff->fromTable = $tableFoo;
$columnDiff = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
$expected = new SchemaDiff();
$expected->fromSchema = $oldSchema;
$tableDiff = $expected->changedTables['foo'] = new TableDiff('foo');
$tableDiff->fromTable = $tableFoo;
$columnDiff = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
$columnDiff->fromColumn = $tableFoo->getColumn('id');
$columnDiff->changedProperties = ['length', 'fixed'];
......@@ -1081,8 +1089,12 @@ class ComparatorTest extends TestCase
self::assertFalse($diff);
}
public function assertSchemaTableChangeCount(SchemaDiff $diff, int $newTableCount = 0, int $changeTableCount = 0, int $removeTableCount = 0): void
{
public function assertSchemaTableChangeCount(
SchemaDiff $diff,
int $newTableCount = 0,
int $changeTableCount = 0,
int $removeTableCount = 0
): void {
self::assertCount($newTableCount, $diff->newTables);
self::assertCount($changeTableCount, $diff->changedTables);
self::assertCount($removeTableCount, $diff->removedTables);
......@@ -1094,16 +1106,34 @@ class ComparatorTest extends TestCase
int $changeSequenceCount = 0,
int $removeSequenceCount = 0
): void {
self::assertCount($newSequenceCount, $diff->newSequences, 'Expected number of new sequences is wrong.');
self::assertCount($changeSequenceCount, $diff->changedSequences, 'Expected number of changed sequences is wrong.');
self::assertCount($removeSequenceCount, $diff->removedSequences, 'Expected number of removed sequences is wrong.');
self::assertCount($newSequenceCount, $diff->newSequences);
self::assertCount($changeSequenceCount, $diff->changedSequences);
self::assertCount($removeSequenceCount, $diff->removedSequences);
}
public function testDiffColumnPlatformOptions(): void
{
$column1 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'bar']]);
$column2 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'foobar' => 'foobar']]);
$column3 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'rab']]);
$column1 = new Column('foo', Type::getType('string'), [
'platformOptions' => [
'foo' => 'foo',
'bar' => 'bar',
],
]);
$column2 = new Column('foo', Type::getType('string'), [
'platformOptions' => [
'foo' => 'foo',
'foobar' => 'foobar',
],
]);
$column3 = new Column('foo', Type::getType('string'), [
'platformOptions' => [
'foo' => 'foo',
'bar' => 'rab',
],
]);
$column4 = new Column('foo', Type::getType('string'));
$comparator = new Comparator();
......
......@@ -44,24 +44,32 @@ class MySqlInheritCharsetTest extends TestCase
// default, no overrides
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
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
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8');
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
$table = new Table('foobar', [new Column('aa', Type::getType('integer'))]);
$table->addOption('charset', 'utf8mb4');
self::assertSame(
$platform->getCreateTableSQL($table),
['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB']
['CREATE TABLE foobar (aa INT NOT NULL)'
. ' DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB',
],
$platform->getCreateTableSQL($table)
);
}
......
......@@ -42,12 +42,24 @@ class MySqlSchemaManagerTest extends TestCase
public function testCompositeForeignKeys(): void
{
$this->conn->expects(self::once())->method('fetchAllAssociative')->will(self::returnValue($this->getFKDefinition()));
$this->conn->expects(self::once())
->method('fetchAllAssociative')
->willReturn($this->getFKDefinition());
$fkeys = $this->manager->listTableForeignKeys('dummy', 'dummy');
self::assertCount(1, $fkeys, 'Table has to have one foreign key.');
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()));
}
/**
......
......@@ -60,7 +60,13 @@ class MySQLSchemaTest extends TestCase
$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
......
......@@ -22,9 +22,17 @@ class SchemaDiffTest extends TestCase
$sql = $diff->toSql($platform);
$expected = ['create_schema', 'drop_orphan_fk', 'alter_seq', 'drop_seq', 'create_seq', 'create_table', 'create_foreign_key', 'drop_table', 'alter_table'];
self::assertEquals($expected, $sql);
self::assertEquals([
'create_schema',
'drop_orphan_fk',
'alter_seq',
'drop_seq',
'create_seq',
'create_table',
'create_foreign_key',
'drop_table',
'alter_table',
], $sql);
}
public function testSchemaDiffToSaveSql(): void
......
......@@ -32,22 +32,99 @@ class SqliteSchemaManagerTest extends TestCase
public static function getDataColumnCollation(): iterable
{
return [
['RTRIM', 'a', 'CREATE TABLE "a" ("a" text DEFAULT "aa" COLLATE "RTRIM" NOT NULL)'],
['utf-8', 'a', 'CREATE TABLE "a" ("b" text UNIQUE NOT NULL COLLATE NOCASE, "a" text DEFAULT "aa" COLLATE "utf-8" NOT NULL)'],
['NOCASE', 'a', 'CREATE TABLE "a" ("a" text DEFAULT (lower(ltrim(" a") || rtrim("a "))) CHECK ("a") NOT NULL COLLATE NOCASE UNIQUE, "b" text COLLATE RTRIM)'],
[null, 'a', 'CREATE TABLE "a" ("a" text CHECK ("a") NOT NULL, "b" text COLLATE RTRIM)'],
['RTRIM', 'a"b', 'CREATE TABLE "a" ("a""b" text COLLATE RTRIM)'],
['BINARY', 'b', 'CREATE TABLE "a" (bb TEXT COLLATE RTRIM, b VARCHAR(42) NOT NULL COLLATE BINARY)'],
['BINARY', 'b', 'CREATE TABLE "a" (bbb TEXT COLLATE NOCASE, bb TEXT COLLATE RTRIM, b VARCHAR(42) NOT NULL COLLATE BINARY)'],
['BINARY', 'b', 'CREATE TABLE "a" (b VARCHAR(42) NOT NULL COLLATE BINARY, bb TEXT COLLATE RTRIM)'],
['utf-8', 'bar#', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, "bar#" VARCHAR(255) COLLATE "utf-8" NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))'],
[null, 'bar#', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, "bar#" VARCHAR(255) NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))'],
['utf-8', 'baz', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, "bar#" INTEGER NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))'],
[null, 'baz', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, "bar#" INTEGER NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))'],
['utf-8', 'bar/', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, "bar/" VARCHAR(255) COLLATE "utf-8" NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))'],
[null, 'bar/', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, "bar/" VARCHAR(255) NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))'],
['utf-8', 'baz', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, "bar/" INTEGER NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))'],
[null, 'baz', 'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, "bar/" INTEGER NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))'],
[
'RTRIM',
'a',
'CREATE TABLE "a" ("a" text DEFAULT "aa" COLLATE "RTRIM" NOT NULL)',
],
[
'utf-8',
'a',
'CREATE TABLE "a" ("b" text UNIQUE NOT NULL COLLATE NOCASE, '
. '"a" text DEFAULT "aa" COLLATE "utf-8" NOT NULL)',
],
[
'NOCASE',
'a',
'CREATE TABLE "a" ("a" text DEFAULT (lower(ltrim(" a") || rtrim("a ")))'
. ' CHECK ("a") NOT NULL COLLATE NOCASE UNIQUE, "b" text COLLATE RTRIM)',
],
[
null,
'a',
'CREATE TABLE "a" ("a" text CHECK ("a") NOT NULL, "b" text COLLATE RTRIM)',
],
[
'RTRIM',
'a"b',
'CREATE TABLE "a" ("a""b" text COLLATE RTRIM)',
],
[
'BINARY',
'b',
'CREATE TABLE "a" (bb TEXT COLLATE RTRIM, b VARCHAR(42) NOT NULL COLLATE BINARY)',
],
[
'BINARY',
'b',
'CREATE TABLE "a" (bbb TEXT COLLATE NOCASE, bb TEXT COLLATE RTRIM, '
. 'b VARCHAR(42) NOT NULL COLLATE BINARY)',
],
[
'BINARY',
'b',
'CREATE TABLE "a" (b VARCHAR(42) NOT NULL COLLATE BINARY, bb TEXT COLLATE RTRIM)',
],
[
'utf-8',
'bar#',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, '
. '"bar#" VARCHAR(255) COLLATE "utf-8" NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, '
. 'PRIMARY KEY(id))',
],
[
null,
'bar#',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL,'
. ' "bar#" VARCHAR(255) NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))',
],
[
'utf-8',
'baz',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL,'
. ' "bar#" INTEGER NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))',
],
[
null,
'baz',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, "bar#" INTEGER NOT NULL, '
. 'baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))',
],
[
'utf-8',
'bar/',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, '
. '"bar/" VARCHAR(255) COLLATE "utf-8" NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL,'
. ' PRIMARY KEY(id))',
],
[
null,
'bar/',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL, '
. '"bar/" VARCHAR(255) NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))',
],
[
'utf-8',
'baz',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) COLLATE "utf-8" NOT NULL, '
. '"bar/" INTEGER NOT NULL, baz VARCHAR(255) COLLATE "utf-8" NOT NULL, PRIMARY KEY(id))',
],
[
null,
'baz',
'CREATE TABLE dummy_table (id INTEGER NOT NULL, foo VARCHAR(255) NOT NULL,'
. ' "bar/" INTEGER NOT NULL, baz VARCHAR(255) NOT NULL, PRIMARY KEY(id))',
],
];
}
......@@ -85,13 +162,15 @@ class SqliteSchemaManagerTest extends TestCase
'Multiple similar columns with type comment 1' => [
'',
'b',
'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "b" TEXT DEFAULT "a" COLLATE RTRIM, "bb" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "b" TEXT DEFAULT "a" COLLATE RTRIM, '
. '"bb" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
)',
],
'Multiple similar columns with type comment 2' => [
'(DC2Type:x)',
'b',
'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "bb" TEXT DEFAULT "a" COLLATE RTRIM, "b" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "bb" TEXT DEFAULT "a" COLLATE RTRIM, '
. '"b" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
)',
],
'Multiple similar columns on different lines, with type comment 1' => [
......
......@@ -476,7 +476,9 @@ class TableTest extends TestCase
$table->setPrimaryKey(['baz']);
$indexes = $table->getIndexes();
self::assertCount(2, $indexes, 'Table should only contain both the primary key table index and the unique one, even though it was overruled.');
// Table should only contain both the primary key table index and the unique one, even though it was overruled
self::assertCount(2, $indexes);
self::assertTrue($table->hasPrimaryKey());
self::assertTrue($table->hasIndex('idx_unique'));
......@@ -533,7 +535,7 @@ class TableTest extends TestCase
self::assertTrue($localTable->hasIndex('explicit_idx'));
}
public function testAddingFulfillingExplicitIndexOverridingImplicitForeignKeyConstraintIndexWithSameNameDoesNotThrowException(): void
public function testAddingFulfillingExplicitIndexOverridingImplicitForeignKeyConstraintIndexWithSameName(): void
{
$foreignTable = new Table('foreign');
$foreignTable->addColumn('id', 'integer');
......
......@@ -27,7 +27,7 @@ class RemoveNamespacedAssetsTest extends TestCase
$schema->visit(new RemoveNamespacedAssets());
$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
......
......@@ -9,6 +9,9 @@ use ArrayObject;
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use Doctrine\DBAL\Tests\Tools\TestAsset\ChildClass;
use Doctrine\DBAL\Tests\Tools\TestAsset\ChildWithSameAttributesClass;
use Doctrine\DBAL\Tests\Tools\TestAsset\ParentClass;
use Doctrine\DBAL\Tools\Dumper;
use PHPUnit\Framework\TestCase;
use stdClass;
......@@ -120,23 +123,23 @@ class DumperTest extends TestCase
{
return [
'different-attributes' => [
new TestAsset\ChildClass(),
new ChildClass(),
[
'childPublicAttribute' => 4,
'childProtectedAttribute:protected' => 5,
'childPrivateAttribute:Doctrine\DBAL\Tests\Tools\TestAsset\ChildClass:private' => 6,
'childPrivateAttribute:' . ChildClass::class . ':private' => 6,
'parentPublicAttribute' => 1,
'parentProtectedAttribute:protected' => 2,
'parentPrivateAttribute:Doctrine\DBAL\Tests\Tools\TestAsset\ParentClass:private' => 3,
'parentPrivateAttribute:' . ParentClass::class . ':private' => 3,
],
],
'same-attributes' => [
new TestAsset\ChildWithSameAttributesClass(),
new ChildWithSameAttributesClass(),
[
'parentPublicAttribute' => 4,
'parentProtectedAttribute:protected' => 5,
'parentPrivateAttribute:Doctrine\DBAL\Tests\Tools\TestAsset\ChildWithSameAttributesClass:private' => 6,
'parentPrivateAttribute:Doctrine\DBAL\Tests\Tools\TestAsset\ParentClass:private' => 3,
'parentPrivateAttribute:' . ChildWithSameAttributesClass::class . ':private' => 6,
'parentPrivateAttribute:' . ParentClass::class . ':private' => 3,
],
],
];
......
......@@ -39,7 +39,11 @@ class ArrayTest extends TestCase
public function testConversionFailure(): void
{
$this->expectException(ConversionException::class);
$this->expectExceptionMessage('Could not convert database value to "array" as an error was triggered by the unserialization: unserialize(): Error at offset 0 of 7 bytes');
$this->expectExceptionMessage(
'Could not convert database value to "array" as an error was triggered by the unserialization:'
. ' unserialize(): Error at offset 0 of 7 bytes'
);
$this->type->convertToPHPValue('abcdefg', $this->platform);
}
......
......@@ -41,7 +41,8 @@ class ConversionExceptionTest extends TestCase
self::assertSame(
sprintf(
'Could not convert PHP value "%s" of type "%s" to type "foo". Expected one of the following types: bar, baz.',
'Could not convert PHP value "%s" of type "%s" to type "foo". '
. 'Expected one of the following types: bar, baz.',
$scalarValue,
$type
),
......@@ -61,7 +62,11 @@ class ConversionExceptionTest extends TestCase
$type = is_object($nonScalar) ? get_class($nonScalar) : gettype($nonScalar);
self::assertSame(
sprintf('Could not convert PHP value of type "%s" to type "foo". Expected one of the following types: bar, baz.', $type),
sprintf(
'Could not convert PHP value of type "%s" to type "foo".'
. ' Expected one of the following types: bar, baz.',
$type
),
$exception->getMessage()
);
}
......
......@@ -22,7 +22,8 @@ class SerializationFailedTest extends TestCase
$exception = SerializationFailed::new($value, 'json', json_last_error_msg());
self::assertSame(
'Could not convert PHP type "double" to "json". An error was triggered by the serialization: Inf and NaN cannot be JSON encoded',
'Could not convert PHP type "double" to "json". An error was triggered by the serialization: '
. 'Inf and NaN cannot be JSON encoded',
$exception->getMessage()
);
}
......
......@@ -40,8 +40,10 @@ class ObjectTest extends TestCase
public function testConversionFailure(): void
{
$this->expectException(ConversionException::class);
$this->expectExceptionMessage('Could not convert database value to "object" as an error was triggered by the unserialization: unserialize(): Error at offset 0 of 7 bytes');
$this->expectExceptionMessage(
'Could not convert database value to "object" as an error was triggered by the unserialization:'
. ' unserialize(): Error at offset 0 of 7 bytes'
);
$this->type->convertToPHPValue('abcdefg', $this->platform);
}
......
......@@ -45,7 +45,7 @@ class StringTest extends TestCase
public function testSQLConversion(): void
{
self::assertFalse($this->type->canRequireSQLConversion(), 'String type can never require SQL conversion to work.');
self::assertFalse($this->type->canRequireSQLConversion());
self::assertEquals('t.foo', $this->type->convertToDatabaseValueSQL('t.foo', $this->platform));
self::assertEquals('t.foo', $this->type->convertToPHPValueSQL('t.foo', $this->platform));
}
......
<?php
declare(strict_types=1);
// PHPStan does not read global constants from the stubs yet, remove this when it does
if (defined('OCI_NO_AUTO_COMMIT')) {
return;
}
define('OCI_NO_AUTO_COMMIT', 0);
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