diff --git a/src/BaseSeed.php b/src/BaseSeed.php
index a9d909244..8d115ef2f 100644
--- a/src/BaseSeed.php
+++ b/src/BaseSeed.php
@@ -204,7 +204,9 @@ public function shouldExecute(): bool
public function call(string $seeder, array $options = []): void
{
$io = $this->getIo();
- assert($io !== null, 'Requires ConsoleIo');
+ if ($io === null) {
+ throw new RuntimeException('ConsoleIo is required for calling other seeders.');
+ }
$io->out('');
$io->out(
' ====' .
@@ -245,7 +247,9 @@ protected function runCall(string $seeder, array $options = []): void
'connection' => $options['connection'] ?? $connection,
]);
$io = $this->getIo();
- assert($io !== null, 'Missing ConsoleIo instance');
+ if ($io === null) {
+ throw new RuntimeException('ConsoleIo is required for running seeders.');
+ }
$manager = $factory->createManager($io);
$manager->seed($seeder);
}
diff --git a/src/Command/DumpCommand.php b/src/Command/DumpCommand.php
index 0e694b41c..53c79026e 100644
--- a/src/Command/DumpCommand.php
+++ b/src/Command/DumpCommand.php
@@ -141,7 +141,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int
return self::CODE_SUCCESS;
}
- $io->error("An error occurred while writing dump file `{$filePath}`");
+ $io->err("An error occurred while writing dump file `{$filePath}`");
return self::CODE_ERROR;
}
diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php
index 76b71f4dc..b00048885 100644
--- a/src/Db/Adapter/MysqlAdapter.php
+++ b/src/Db/Adapter/MysqlAdapter.php
@@ -612,7 +612,9 @@ protected function getRenameColumnInstructions(string $tableName, string $column
foreach ($rows as $row) {
if (strcasecmp($row['Field'], $columnName) === 0) {
$null = $row['Null'] === 'NO' ? 'NOT NULL' : 'NULL';
- $comment = isset($row['Comment']) ? ' COMMENT ' . '\'' . addslashes($row['Comment']) . '\'' : '';
+ $comment = isset($row['Comment']) && $row['Comment'] !== ''
+ ? ' COMMENT ' . $this->getConnection()->getDriver()->schemaValue($row['Comment'])
+ : '';
// create the extra string by also filtering out the DEFAULT_GENERATED option (MySQL 8 fix)
$extras = array_filter(
diff --git a/src/Db/Adapter/PostgresAdapter.php b/src/Db/Adapter/PostgresAdapter.php
index e77e7a445..bb204b688 100644
--- a/src/Db/Adapter/PostgresAdapter.php
+++ b/src/Db/Adapter/PostgresAdapter.php
@@ -972,7 +972,11 @@ public function getPhinxType(string $sqlType): string
public function createDatabase(string $name, array $options = []): void
{
$charset = $options['charset'] ?? 'utf8';
- $this->execute(sprintf("CREATE DATABASE %s WITH ENCODING = '%s'", $name, $charset));
+ $this->execute(sprintf(
+ 'CREATE DATABASE %s WITH ENCODING = %s',
+ $this->quoteSchemaName($name),
+ $this->quoteString($charset),
+ ));
}
/**
@@ -995,7 +999,7 @@ public function hasDatabase(string $name): bool
public function dropDatabase($name): void
{
$this->disconnect();
- $this->execute(sprintf('DROP DATABASE IF EXISTS %s', $name));
+ $this->execute(sprintf('DROP DATABASE IF EXISTS %s', $this->quoteSchemaName($name)));
$this->createdTables = [];
$this->connect();
}
@@ -1091,10 +1095,11 @@ protected function getForeignKeySqlDefinition(ForeignKey $foreignKey, string $ta
$constraintName = $foreignKey->getName() ?: (
$parts['table'] . '_' . implode('_', $foreignKey->getColumns()) . '_fkey'
);
+ $columnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getColumns()));
+ $refColumnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getReferencedColumns()));
$def = ' CONSTRAINT ' . $this->quoteColumnName($constraintName) .
- ' FOREIGN KEY ("' . implode('", "', $foreignKey->getColumns()) . '")' .
- " REFERENCES {$this->quoteTableName($foreignKey->getReferencedTable()->getName())} (\"" .
- implode('", "', $foreignKey->getReferencedColumns()) . '")';
+ ' FOREIGN KEY (' . $columnList . ')' .
+ ' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()->getName()) . ' (' . $refColumnList . ')';
if ($foreignKey->getOnDelete()) {
$def .= " ON DELETE {$foreignKey->getOnDelete()}";
}
diff --git a/src/Db/Adapter/SqlserverAdapter.php b/src/Db/Adapter/SqlserverAdapter.php
index 32d662ee5..ec7bf4865 100644
--- a/src/Db/Adapter/SqlserverAdapter.php
+++ b/src/Db/Adapter/SqlserverAdapter.php
@@ -248,9 +248,9 @@ protected function getRenameTableInstructions(string $tableName, string $newTabl
{
$this->updateCreatedTableName($tableName, $newTableName);
$sql = sprintf(
- "EXEC sp_rename '%s', '%s'",
- $tableName,
- $newTableName,
+ 'EXEC sp_rename %s, %s',
+ $this->quoteString($tableName),
+ $this->quoteString($newTableName),
);
return new AlterInstructions([], [$sql]);
@@ -404,23 +404,21 @@ protected function getRenameColumnInstructions(string $tableName, string $column
$oldConstraintName = "DF_{$tableName}_{$columnName}";
$newConstraintName = "DF_{$tableName}_{$newColumnName}";
- $sql = <<addPostStep(sprintf(
- $sql,
- $oldConstraintName,
- $newConstraintName,
- ));
+ EXECUTE sp_rename %s, %s, N\'OBJECT\'
+END',
+ $this->quoteString($oldConstraintName),
+ $this->quoteString($oldConstraintName),
+ $this->quoteString($newConstraintName),
+ );
+ $instructions->addPostStep($sql);
$instructions->addPostStep(sprintf(
- "EXECUTE sp_rename N'%s.%s', N'%s', 'COLUMN' ",
- $tableName,
- $columnName,
- $newColumnName,
+ 'EXECUTE sp_rename %s, %s, N\'COLUMN\'',
+ $this->quoteString($tableName . '.' . $columnName),
+ $this->quoteString($newColumnName),
));
return $instructions;
@@ -970,12 +968,17 @@ public function getPhinxType(string $sqlType): string
*/
public function createDatabase(string $name, array $options = []): void
{
+ $quotedName = $this->quoteSchemaName($name);
if (isset($options['collation'])) {
- $this->execute(sprintf('CREATE DATABASE [%s] COLLATE [%s]', $name, $options['collation']));
+ $this->execute(sprintf(
+ 'CREATE DATABASE %s COLLATE %s',
+ $quotedName,
+ $this->quoteSchemaName($options['collation']),
+ ));
} else {
- $this->execute(sprintf('CREATE DATABASE [%s]', $name));
+ $this->execute(sprintf('CREATE DATABASE %s', $quotedName));
}
- $this->execute(sprintf('USE [%s]', $name));
+ $this->execute(sprintf('USE %s', $quotedName));
}
/**
@@ -997,12 +1000,16 @@ public function hasDatabase(string $name): bool
*/
public function dropDatabase(string $name): void
{
- $sql = <<quoteSchemaName($name);
+ $sql = sprintf(
+ 'USE master;
+IF EXISTS(select * from sys.databases where name=%s)
+ALTER DATABASE %s SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
+DROP DATABASE %s;',
+ $this->quoteString($name),
+ $quotedName,
+ $quotedName,
+ );
$this->execute($sql);
$this->createdTables = [];
}
@@ -1061,10 +1068,12 @@ protected function getIndexSqlDefinition(Index $index, string $tableName): strin
protected function getForeignKeySqlDefinition(ForeignKey $foreignKey, string $tableName): string
{
$constraintName = $foreignKey->getName() ?: $tableName . '_' . implode('_', $foreignKey->getColumns());
+ $columnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getColumns()));
+ $refColumnList = implode(', ', array_map($this->quoteColumnName(...), $foreignKey->getReferencedColumns()));
$def = ' CONSTRAINT ' . $this->quoteColumnName($constraintName);
- $def .= ' FOREIGN KEY ("' . implode('", "', $foreignKey->getColumns()) . '")';
- $def .= " REFERENCES {$this->quoteTableName($foreignKey->getReferencedTable()->getName())} (\"" . implode('", "', $foreignKey->getReferencedColumns()) . '")';
+ $def .= ' FOREIGN KEY (' . $columnList . ')';
+ $def .= ' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()->getName()) . ' (' . $refColumnList . ')';
if ($foreignKey->getOnDelete()) {
$def .= " ON DELETE {$foreignKey->getOnDelete()}";
}
diff --git a/src/Db/Table.php b/src/Db/Table.php
index eb2e29b93..d1c8a34ea 100644
--- a/src/Db/Table.php
+++ b/src/Db/Table.php
@@ -793,7 +793,7 @@ public function saveData(): void
$c = array_keys($row);
foreach ($this->getData() as $row) {
$k = array_keys($row);
- if ($k != $c) {
+ if ($k !== $c) {
$bulk = false;
break;
}
diff --git a/src/Migrations.php b/src/Migrations.php
index 993136f23..b889667c3 100644
--- a/src/Migrations.php
+++ b/src/Migrations.php
@@ -64,7 +64,7 @@ class Migrations
*
* @var string
*/
- protected string $command;
+ protected string $command = '';
/**
* Stub input to feed the manager class since we might not have an input ready when we get the Manager using
diff --git a/src/TestSuite/Migrator.php b/src/TestSuite/Migrator.php
index 598a0780f..6f2400d50 100644
--- a/src/TestSuite/Migrator.php
+++ b/src/TestSuite/Migrator.php
@@ -199,7 +199,7 @@ protected function shouldDropTables(Migrations $migrations, array $options): boo
if (!empty($messages['missing'])) {
$hasProblems = true;
$output[] = 'Applied but missing migrations:';
- $output = array_merge($output, array_map($itemize, $messages['down']));
+ $output = array_merge($output, array_map($itemize, $messages['missing']));
$output[] = '';
}
if ($output) {