Skip to content
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ includes:
- phpstan-baseline.neon

parameters:
level: 7
level: 8
paths:
- src/
bootstrapFiles:
Expand Down
4 changes: 2 additions & 2 deletions src/BaseSeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ protected function runCall(string $seeder, array $options = []): void

$options += [
'connection' => $connection,
'plugin' => $pluginName ?? $config['plugin'],
'source' => $config['source'],
'plugin' => $pluginName ?? ($config !== null ? $config['plugin'] : null),
'source' => $config !== null ? $config['source'] : null,
];
$factory = new ManagerFactory([
'connection' => $options['connection'],
Expand Down
31 changes: 24 additions & 7 deletions src/Command/BakeMigrationDiffCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,16 +275,24 @@ protected function getColumns(): void
// changes in columns meta-data
foreach ($currentColumns as $columnName) {
$column = $currentSchema->getColumn($columnName);
if ($column === null) {
continue;
}
$oldColumn = $this->dumpSchema[$table]->getColumn($columnName);
unset(
$column['collate'],
$column['fixed'],
$oldColumn['collate'],
$oldColumn['fixed'],
);
if ($oldColumn !== null) {
unset(
$oldColumn['collate'],
$oldColumn['fixed'],
);
}

if (
in_array($columnName, $oldColumns, true) &&
$oldColumn !== null &&
$column !== $oldColumn
) {
$changedAttributes = array_diff_assoc($column, $oldColumn);
Expand Down Expand Up @@ -381,9 +389,10 @@ protected function getConstraints(): void
// brand new constraints
$addedConstraints = array_diff($currentConstraints, $oldConstraints);
foreach ($addedConstraints as $constraintName) {
$this->templateData[$table]['constraints']['add'][$constraintName] =
$currentSchema->getConstraint($constraintName);
$constraint = $currentSchema->getConstraint($constraintName);
if ($constraint === null) {
continue;
}
if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
$this->templateData[$table]['constraints']['add'][$constraintName] = $constraint;
} else {
Expand All @@ -395,13 +404,18 @@ protected function getConstraints(): void
// if present in both, check if they are the same : if not, remove the old one and add the new one
foreach ($currentConstraints as $constraintName) {
$constraint = $currentSchema->getConstraint($constraintName);
if ($constraint === null) {
continue;
}

$oldConstraint = $this->dumpSchema[$table]->getConstraint($constraintName);
if (
in_array($constraintName, $oldConstraints, true) &&
$constraint !== $this->dumpSchema[$table]->getConstraint($constraintName)
$constraint !== $oldConstraint
) {
$this->templateData[$table]['constraints']['remove'][$constraintName] =
$this->dumpSchema[$table]->getConstraint($constraintName);
if ($oldConstraint !== null) {
$this->templateData[$table]['constraints']['remove'][$constraintName] = $oldConstraint;
}
$this->templateData[$table]['constraints']['add'][$constraintName] =
$constraint;
}
Expand All @@ -411,6 +425,9 @@ protected function getConstraints(): void
$removedConstraints = array_diff($oldConstraints, $currentConstraints);
foreach ($removedConstraints as $constraintName) {
$constraint = $this->dumpSchema[$table]->getConstraint($constraintName);
if ($constraint === null) {
continue;
}
if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
$this->templateData[$table]['constraints']['remove'][$constraintName] = $constraint;
} else {
Expand Down
8 changes: 4 additions & 4 deletions src/Command/BakeSimpleMigrationCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ abstract class BakeSimpleMigrationCommand extends SimpleBakeCommand
/**
* Console IO
*
* @var \Cake\Console\ConsoleIo|null
* @var \Cake\Console\ConsoleIo
*/
protected ?ConsoleIo $io = null;
protected ConsoleIo $io;

/**
* Arguments
*
* @var \Cake\Console\Arguments|null
* @var \Cake\Console\Arguments
*/
protected ?Arguments $args = null;
protected Arguments $args;

/**
* @inheritDoc
Expand Down
2 changes: 1 addition & 1 deletion src/Db/Action/ChangeColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct(TableMetadata $table, string $columnName, Column $co
$this->column = $column;

// if the name was omitted use the existing column name
if ($column->getName() === null || strlen((string)$column->getName()) === 0) {
if ($column->getName() === null || strlen($column->getName()) === 0) {
$column->setName($columnName);
}
}
Expand Down
25 changes: 18 additions & 7 deletions src/Db/Adapter/AbstractAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ public function getConnection(): Connection
$this->connection = $this->getOption('connection');
$this->connect();
}
if ($this->connection === null) {
throw new RuntimeException('Unable to establish database connection. Ensure a connection is configured.');
}

return $this->connection;
}
Expand Down Expand Up @@ -1681,23 +1684,23 @@ public function executeActions(TableMetadata $table, array $actions): void
/** @var \Migrations\Db\Action\DropForeignKey $action */
$instructions->merge($this->getDropForeignKeyByColumnsInstructions(
$table->getName(),
$action->getForeignKey()->getColumns(),
$action->getForeignKey()->getColumns() ?? [],
));
break;

case $action instanceof DropForeignKey && $action->getForeignKey()->getName():
case $action instanceof DropForeignKey && ($fkName = $action->getForeignKey()->getName()):
/** @var \Migrations\Db\Action\DropForeignKey $action */
$instructions->merge($this->getDropForeignKeyInstructions(
$table->getName(),
(string)$action->getForeignKey()->getName(),
$fkName,
));
break;

case $action instanceof DropIndex && $action->getIndex()->getName():
case $action instanceof DropIndex && ($indexName = $action->getIndex()->getName()):
/** @var \Migrations\Db\Action\DropIndex $action */
$instructions->merge($this->getDropIndexByNameInstructions(
$table->getName(),
(string)$action->getIndex()->getName(),
$indexName,
));
break;

Expand All @@ -1718,17 +1721,25 @@ public function executeActions(TableMetadata $table, array $actions): void

case $action instanceof RemoveColumn:
/** @var \Migrations\Db\Action\RemoveColumn $action */
$columnName = $action->getColumn()->getName();
if ($columnName === null) {
throw new InvalidArgumentException('Column name must be set.');
}
$instructions->merge($this->getDropColumnInstructions(
$table->getName(),
(string)$action->getColumn()->getName(),
$columnName,
));
break;

case $action instanceof RenameColumn:
/** @var \Migrations\Db\Action\RenameColumn $action */
$columnName = $action->getColumn()->getName();
if ($columnName === null) {
throw new InvalidArgumentException('Column name must be set.');
}
$instructions->merge($this->getRenameColumnInstructions(
$table->getName(),
(string)$action->getColumn()->getName(),
$columnName,
$action->getNewName(),
));
break;
Expand Down
14 changes: 9 additions & 5 deletions src/Db/Adapter/MysqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@
$targetColumn = null;

foreach ($columns as $column) {
if (strcasecmp($column->getName(), $columnName) === 0) {
if ($column->getName() !== null && strcasecmp($column->getName(), $columnName) === 0) {
$targetColumn = $column;
break;
}
Expand Down Expand Up @@ -1180,19 +1180,23 @@
protected function getForeignKeySqlDefinition(ForeignKey $foreignKey): string
{
$def = '';
if ($foreignKey->getName()) {
$def .= ' CONSTRAINT ' . $this->quoteColumnName((string)$foreignKey->getName());
if ($name = $foreignKey->getName()) {

Check failure on line 1183 in src/Db/Adapter/MysqlAdapter.php

View workflow job for this annotation

GitHub Actions / cs-stan / Coding Standard & Static Analysis

Assignment in if condition is not allowed.
$def .= ' CONSTRAINT ' . $this->quoteColumnName($name);
}
$columnNames = [];
foreach ($foreignKey->getColumns() as $column) {
foreach ($foreignKey->getColumns() ?? [] as $column) {
$columnNames[] = $this->quoteColumnName($column);
}
$def .= ' FOREIGN KEY (' . implode(',', $columnNames) . ')';
$refColumnNames = [];
foreach ($foreignKey->getReferencedColumns() as $column) {
$refColumnNames[] = $this->quoteColumnName($column);
}
$def .= ' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()) . ' (' . implode(',', $refColumnNames) . ')';
$referencedTable = $foreignKey->getReferencedTable();
if ($referencedTable === null) {
throw new InvalidArgumentException('Foreign key must have a referenced table.');
}
$def .= ' REFERENCES ' . $this->quoteTableName($referencedTable) . ' (' . implode(',', $refColumnNames) . ')';
$onDelete = $foreignKey->getOnDelete();
if ($onDelete) {
$def .= ' ON DELETE ' . $onDelete;
Expand Down
49 changes: 31 additions & 18 deletions src/Db/Adapter/PostgresAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,9 @@

$columnSql = $dialect->columnDefinitionSql($this->mapColumnData($newColumn->toArray()));
// Remove the column name from $columnSql
$columnType = preg_replace('/^"?(?:[^"]+)"?\s+/', '', $columnSql);
$columnType = (string)preg_replace('/^"?(?:[^"]+)"?\s+/', '', $columnSql);
// Remove generated clause
$columnType = preg_replace('/GENERATED (?:ALWAYS|BY DEFAULT) AS IDENTITY/', '', $columnType);
$columnType = (string)preg_replace('/GENERATED (?:ALWAYS|BY DEFAULT) AS IDENTITY/', '', $columnType);

$sql = sprintf(
'ALTER COLUMN %s TYPE %s',
Expand All @@ -477,10 +477,10 @@
);
}
// NULL and DEFAULT cannot be set while changing column type
$sql = preg_replace('/ NOT NULL/', '', $sql);
$sql = preg_replace('/ DEFAULT NULL/', '', $sql);
$sql = (string)preg_replace('/ NOT NULL/', '', $sql);
$sql = (string)preg_replace('/ DEFAULT NULL/', '', $sql);
// If it is set, DEFAULT is the last definition
$sql = preg_replace('/DEFAULT .*/', '', $sql);
$sql = (string)preg_replace('/DEFAULT .*/', '', $sql);
if ($newColumn->getType() === 'boolean') {
$sql .= sprintf(
' USING (CASE WHEN %s IS NULL THEN NULL WHEN %s::int=0 THEN FALSE ELSE TRUE END)',
Expand All @@ -499,11 +499,11 @@
'ALTER COLUMN %s',
$quotedColumnName,
);
if ($newColumn->isIdentity() && $newColumn->getGenerated() !== null) {
if ($newColumn->isIdentity() && ($generated = $newColumn->getGenerated()) !== null) {

Check failure on line 502 in src/Db/Adapter/PostgresAdapter.php

View workflow job for this annotation

GitHub Actions / cs-stan / Coding Standard & Static Analysis

Assignment in if condition is not allowed.
if ($column->isIdentity()) {
$sql .= sprintf(' SET GENERATED %s', (string)$newColumn->getGenerated());
$sql .= sprintf(' SET GENERATED %s', $generated);
} else {
$sql .= sprintf(' ADD GENERATED %s AS IDENTITY', (string)$newColumn->getGenerated());
$sql .= sprintf(' ADD GENERATED %s AS IDENTITY', $generated);
}
} else {
$sql .= ' DROP IDENTITY IF EXISTS';
Expand Down Expand Up @@ -540,12 +540,16 @@
}

// rename column
if ($columnName !== $newColumn->getName()) {
$newColumnName = $newColumn->getName();
if ($columnName !== $newColumnName) {
if ($newColumnName === null) {
throw new InvalidArgumentException('Column name must be set.');
}
$instructions->addPostStep(sprintf(
'ALTER TABLE %s RENAME COLUMN %s TO %s',
$this->quoteTableName($tableName),
$quotedColumnName,
$this->quoteColumnName((string)$newColumn->getName()),
$this->quoteColumnName($newColumnName),
));
}

Expand Down Expand Up @@ -867,6 +871,11 @@
*/
protected function getColumnCommentSqlDefinition(Column $column, string $tableName): string
{
$columnName = $column->getName();
if ($columnName === null) {
throw new InvalidArgumentException('Column name must be set.');
}

$comment = (string)$column->getComment();
// passing 'null' is to remove column comment
$comment = strcasecmp($comment, 'NULL') !== 0
Expand All @@ -876,7 +885,7 @@
return sprintf(
'COMMENT ON COLUMN %s.%s IS %s;',
$this->quoteTableName($tableName),
$this->quoteColumnName((string)$column->getName()),
$this->quoteColumnName($columnName),
$comment,
);
}
Expand Down Expand Up @@ -917,9 +926,9 @@
} else {
$createIndexSentence .= '(%s)%s%s;';
}
$where = (string)$index->getWhere();
if ($where) {
$where = ' WHERE ' . $where;
$where = '';
if ($whereClause = $index->getWhere()) {

Check failure on line 930 in src/Db/Adapter/PostgresAdapter.php

View workflow job for this annotation

GitHub Actions / cs-stan / Coding Standard & Static Analysis

Assignment in if condition is not allowed.
$where = ' WHERE ' . $whereClause;
}

return sprintf(
Expand All @@ -946,13 +955,17 @@
$parts = $this->getSchemaName($tableName);

$constraintName = $foreignKey->getName() ?: (
$parts['table'] . '_' . implode('_', $foreignKey->getColumns()) . '_fkey'
$parts['table'] . '_' . implode('_', $foreignKey->getColumns() ?? []) . '_fkey'
);
$columnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getColumns()));
$columnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getColumns() ?? []));
$refColumnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getReferencedColumns()));
$referencedTable = $foreignKey->getReferencedTable();
if ($referencedTable === null) {
throw new InvalidArgumentException('Foreign key must have a referenced table.');
}
$def = ' CONSTRAINT ' . $this->quoteColumnName($constraintName) .
' FOREIGN KEY (' . $columnList . ')' .
' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()) . ' (' . $refColumnList . ')';
' REFERENCES ' . $this->quoteTableName($referencedTable) . ' (' . $refColumnList . ')';
if ($foreignKey->getOnDelete()) {
$def .= " ON DELETE {$foreignKey->getOnDelete()}";
}
Expand Down Expand Up @@ -1321,7 +1334,7 @@
}
$quotedConflictColumns = array_map($this->quoteColumnName(...), $conflictColumns);
$updates = [];
foreach ($updateColumns as $column) {
foreach ($updateColumns ?? [] as $column) {
$quotedColumn = $this->quoteColumnName($column);
$updates[] = $quotedColumn . ' = EXCLUDED.' . $quotedColumn;
}
Expand Down
6 changes: 5 additions & 1 deletion src/Db/Adapter/RecordingAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Migrations\Db\Action\AddForeignKey;
use Migrations\Db\Action\AddIndex;
use Migrations\Db\Action\CreateTable;
use InvalidArgumentException;

Check failure on line 15 in src/Db/Adapter/RecordingAdapter.php

View workflow job for this annotation

GitHub Actions / cs-stan / Coding Standard & Static Analysis

Use statements should be sorted alphabetically. The first wrong one is InvalidArgumentException.
use Migrations\Db\Action\DropForeignKey;
use Migrations\Db\Action\DropIndex;
use Migrations\Db\Action\DropTable;
Expand Down Expand Up @@ -89,7 +90,10 @@
case $command instanceof RenameColumn:
/** @var \Migrations\Db\Action\RenameColumn $command */
$column = clone $command->getColumn();
$name = (string)$column->getName();
$name = $column->getName();
if ($name === null) {
throw new InvalidArgumentException('Column name must be set.');
}
$column->setName($command->getNewName());
$inverted->addAction(new RenameColumn($command->getTable(), $column, $name));
break;
Expand Down
Loading
Loading