Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/BaseSeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ public function isIdempotent(): 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(
' ====' .
Expand Down Expand Up @@ -285,7 +287,9 @@ protected function runCall(string $seeder, array $options = []): void
'source' => $options['source'],
]);
$io = $this->getIo();
assert($io !== null, 'Missing ConsoleIo instance');
if ($io === null) {
throw new RuntimeException('ConsoleIo is required for calling other seeders.');
}
$manager = $factory->createManager($io);
$manager->seed($seeder);
}
Expand Down
25 changes: 23 additions & 2 deletions src/Command/BakeMigrationDiffCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\Database\Connection;
use Cake\Database\Schema\CachedCollection;
use Cake\Database\Schema\CheckConstraint;
use Cake\Database\Schema\CollectionInterface;
use Cake\Database\Schema\Column;
use Cake\Database\Schema\Constraint;
use Cake\Database\Schema\ForeignKey;
use Cake\Database\Schema\Index;
use Cake\Database\Schema\TableSchema;
use Cake\Database\Schema\UniqueKey;
use Cake\Datasource\ConnectionManager;
use Cake\Event\Event;
use Cake\Event\EventManager;
Expand Down Expand Up @@ -485,7 +492,7 @@ protected function checkSync(): bool
$lastVersion = $this->migratedItems[0]['version'];
$lastFile = end($this->migrationsFiles);

return $lastFile && (bool)strpos($lastFile, (string)$lastVersion);
return $lastFile && str_contains($lastFile, (string)$lastVersion);
}

return false;
Expand Down Expand Up @@ -546,7 +553,21 @@ protected function getDumpSchema(Arguments $args): array
$this->io->abort($msg);
}

return unserialize((string)file_get_contents($path));
$contents = (string)file_get_contents($path);

// Use allowed_classes to restrict deserialization to safe CakePHP schema classes
return unserialize($contents, [
'allowed_classes' => [
TableSchema::class,
CachedCollection::class,
Column::class,
Index::class,
Constraint::class,
UniqueKey::class,
ForeignKey::class,
CheckConstraint::class,
],
]);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Command/DumpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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("<error>An error occurred while writing dump file `{$filePath}`</error>");

return self::CODE_ERROR;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Db/Adapter/MysqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,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(
Expand Down
17 changes: 14 additions & 3 deletions src/Db/Adapter/SqlserverAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -1105,27 +1105,38 @@ private function updateSQLForIdentityInsert(string $tableName, string $sql): str

/**
* @inheritDoc
*
* Note: Check constraints are not supported for SQL Server adapter.
* This method returns an empty array. Use raw SQL via execute() if you need
* check constraints on SQL Server.
*/
protected function getCheckConstraints(string $tableName): array
{
// TODO: Implement check constraints for SQL Server
return [];
}

/**
* @inheritDoc
* @throws \BadMethodCallException Check constraints are not supported for SQL Server.
*/
protected function getAddCheckConstraintInstructions(TableMetadata $table, CheckConstraint $checkConstraint): AlterInstructions
{
throw new BadMethodCallException('Check constraints are not yet implemented for SQL Server adapter');
throw new BadMethodCallException(
'Check constraints are not supported for the SQL Server adapter. ' .
'Use $this->execute() with raw SQL to add check constraints.',
);
}

/**
* @inheritDoc
* @throws \BadMethodCallException Check constraints are not supported for SQL Server.
*/
protected function getDropCheckConstraintInstructions(string $tableName, string $constraintName): AlterInstructions
{
throw new BadMethodCallException('Check constraints are not yet implemented for SQL Server adapter');
throw new BadMethodCallException(
'Check constraints are not supported for the SQL Server adapter. ' .
'Use $this->execute() with raw SQL to drop check constraints.',
);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Db/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,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;
}
Expand Down
1 change: 1 addition & 0 deletions src/Db/Table/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@ protected function getValidOptions(): array
'update',
'comment',
'signed',
'unsigned',
'timezone',
'properties',
'values',
Expand Down
34 changes: 31 additions & 3 deletions src/Migration/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1101,18 +1101,46 @@ protected function getSeedDependenciesInstances(SeedInterface $seed): array
* Order seeds by dependencies
*
* @param \Migrations\SeedInterface[] $seeds Seeds
* @param array<string, true> $visiting Seeds currently being visited (for cycle detection)
* @param array<string, true> $visited Seeds that have been fully processed
* @return \Migrations\SeedInterface[]
* @throws \RuntimeException When a circular dependency is detected
*/
protected function orderSeedsByDependencies(array $seeds): array
protected function orderSeedsByDependencies(array $seeds, array $visiting = [], array &$visited = []): array
{
$orderedSeeds = [];
foreach ($seeds as $seed) {
$name = $seed->getName();
$orderedSeeds[$name] = $seed;

// Skip if already fully processed
if (isset($visited[$name])) {
continue;
}

// Check for circular dependency
if (isset($visiting[$name])) {
$cycle = array_keys($visiting);
$cycle[] = $name;
throw new RuntimeException(
'Circular dependency detected in seeds: ' . implode(' -> ', $cycle),
);
}

// Mark as currently visiting
$visiting[$name] = true;

$dependencies = $this->getSeedDependenciesInstances($seed);
if ($dependencies) {
$orderedSeeds = array_merge($this->orderSeedsByDependencies($dependencies), $orderedSeeds);
$orderedSeeds = array_merge(
$this->orderSeedsByDependencies($dependencies, $visiting, $visited),
$orderedSeeds,
);
}

// Mark as fully visited and add to result
$visited[$name] = true;
unset($visiting[$name]);
$orderedSeeds[$name] = $seed;
}

return $orderedSeeds;
Expand Down
2 changes: 1 addition & 1 deletion src/Migrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Migrations
*
* @var string
*/
protected string $command;
protected string $command = '';

/**
* Constructor
Expand Down
2 changes: 1 addition & 1 deletion src/TestSuite/Migrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down