From 962258bfd9d2fd7f6baac8f3e536698ae9681be7 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 16 Oct 2026 15:43:43 +0700 Subject: [PATCH 1/3] Removed `MissingDatabaseOptionPolicy` --- src/Command/CreateCommand.php | 4 +- src/Command/DatabaseCommand.php | 64 ++++++++++++--------- src/Command/DownCommand.php | 5 -- src/Command/HistoryCommand.php | 4 +- src/Command/MarkCommand.php | 5 -- src/Command/MissingDatabaseOptionPolicy.php | 28 --------- src/Command/NewCommand.php | 15 +++-- src/Command/RedoCommand.php | 5 -- src/Command/UpdateCommand.php | 15 +++-- 9 files changed, 54 insertions(+), 91 deletions(-) delete mode 100644 src/Command/MissingDatabaseOptionPolicy.php diff --git a/src/Command/CreateCommand.php b/src/Command/CreateCommand.php index d1f14d71..a1f1fddd 100644 --- a/src/Command/CreateCommand.php +++ b/src/Command/CreateCommand.php @@ -96,9 +96,9 @@ protected function configure(): void ->setHelp('This command generates new migration file.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy + protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array { - return MissingDatabaseOptionPolicy::ProcessDefaultDatabase; + return [DatabaseRegistry::DEFAULT_DATABASE]; } protected function createDefaultContext(): CreateContext diff --git a/src/Command/DatabaseCommand.php b/src/Command/DatabaseCommand.php index ade86aff..c2d35fe6 100644 --- a/src/Command/DatabaseCommand.php +++ b/src/Command/DatabaseCommand.php @@ -13,7 +13,6 @@ use Yiisoft\Db\Migration\DatabaseRegistry; use Yiisoft\Db\Migration\DatabaseSetup; -use function count; use function implode; use function in_array; use function is_string; @@ -33,22 +32,22 @@ public function __construct(private readonly ?DatabaseRegistry $additionalDataba final protected function execute(InputInterface $input, OutputInterface $output): int { - $availableNames = [DatabaseRegistry::DEFAULT_DATABASE, ...($this->additionalDatabases?->getNames() ?? [])]; - $multipleDatabases = count($availableNames) > 1; $io = new SymfonyStyle($input, $output); - $names = $this->resolveDatabaseNames($input, $availableNames, $multipleDatabases); + $names = $this->resolveDatabaseNames($input); if (is_string($names)) { $io->error($names); return Command::INVALID; } + $multipleDatabases = $this->isMultipleDatabases(); $hasResults = false; foreach ($names as $name) { - if ($this->additionalDatabases === null || $name === DatabaseRegistry::DEFAULT_DATABASE) { + if (!$multipleDatabases || $name === DatabaseRegistry::DEFAULT_DATABASE) { $context = $this->createDefaultContext(); } else { + /** @psalm-var DatabaseRegistry $this->additionalDatabases */ $context = $this->createContext($this->additionalDatabases->createSetup($name)); } @@ -70,15 +69,20 @@ final protected function execute(InputInterface $input, OutputInterface $output) } /** - * Returns how the command behaves when the `--db` option isn't specified. - */ - abstract protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy; - - /** - * Returns the error message shown when the `--db` option is required, but isn't specified. + * Resolves the database names or returns a message indicating that an option is missing if multiple databases + * are configured. + * + * @param InputInterface $input The input interface containing the command options and arguments. + * + * @return string[]|string + * @psalm-return non-empty-list|string */ - protected function getMissingDatabaseOptionError(): string + protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array|string { + if (!$this->isMultipleDatabases()) { + return [DatabaseRegistry::DEFAULT_DATABASE]; + } + return 'The --db option is required when multiple databases are configured.'; } @@ -110,34 +114,38 @@ abstract protected function executeForDatabase( object $context, ): ?int; + /** + * @return string[] + * @psalm-return non-empty-list + */ + protected function getAllDatabaseNames(): array + { + return [DatabaseRegistry::DEFAULT_DATABASE, ...($this->additionalDatabases?->getNames() ?? [])]; + } + + protected function isMultipleDatabases(): bool + { + return $this->additionalDatabases !== null; + } + /** * Resolves names of databases to process. * - * @param string[] $availableNames * @return string[]|string The database names, or an error message if the databases can't be resolved. * - * @psalm-param list $availableNames - * @psalm-return list|string + * @psalm-return non-empty-list|string */ - private function resolveDatabaseNames( - InputInterface $input, - array $availableNames, - bool $multipleDatabases, - ): array|string { + private function resolveDatabaseNames(InputInterface $input): array|string + { /** @var string|null $name */ $name = $input->getOption('db'); if ($name === null) { - $policy = $this->getMissingDatabaseOptionPolicy($input); - if ($multipleDatabases && $policy === MissingDatabaseOptionPolicy::RejectIfMultiple) { - return $this->getMissingDatabaseOptionError(); - } - - return $policy === MissingDatabaseOptionPolicy::ProcessDefaultDatabase - ? [DatabaseRegistry::DEFAULT_DATABASE] - : $availableNames; + return $this->resolveDatabaseNamesWithMissingOption($input); } + $availableNames = $this->getAllDatabaseNames(); + if (!in_array($name, $availableNames, true)) { return 'Unknown database "' . OutputFormatter::escape($name) . '". Available databases: ' . OutputFormatter::escape(implode(', ', $availableNames)) . '.'; diff --git a/src/Command/DownCommand.php b/src/Command/DownCommand.php index 3b0c721c..0277929b 100644 --- a/src/Command/DownCommand.php +++ b/src/Command/DownCommand.php @@ -63,11 +63,6 @@ protected function configure(): void ->addOption('force-yes', 'y', InputOption::VALUE_NONE, 'Force yes to all questions.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy - { - return MissingDatabaseOptionPolicy::RejectIfMultiple; - } - protected function createDefaultContext(): DownContext { return new DownContext($this->migrator, $this->migrationService, $this->downRunner); diff --git a/src/Command/HistoryCommand.php b/src/Command/HistoryCommand.php index 055798d3..12087184 100644 --- a/src/Command/HistoryCommand.php +++ b/src/Command/HistoryCommand.php @@ -52,9 +52,9 @@ protected function configure(): void ->addOption('all', 'a', InputOption::VALUE_NONE, 'All migrations.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy + protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array { - return MissingDatabaseOptionPolicy::ProcessAllDatabases; + return $this->getAllDatabaseNames(); } protected function createDefaultContext(): MigrationContext diff --git a/src/Command/MarkCommand.php b/src/Command/MarkCommand.php index 96b931d7..1553f4dd 100644 --- a/src/Command/MarkCommand.php +++ b/src/Command/MarkCommand.php @@ -66,11 +66,6 @@ protected function configure(): void ->addOption('force-yes', 'y', InputOption::VALUE_NONE, 'Force yes to all questions.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy - { - return MissingDatabaseOptionPolicy::RejectIfMultiple; - } - protected function createDefaultContext(): MigrationContext { return new MigrationContext($this->migrator, $this->migrationService); diff --git a/src/Command/MissingDatabaseOptionPolicy.php b/src/Command/MissingDatabaseOptionPolicy.php deleted file mode 100644 index b8066269..00000000 --- a/src/Command/MissingDatabaseOptionPolicy.php +++ /dev/null @@ -1,28 +0,0 @@ -addOption('namespace', 'ns', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Namespace of migrations to display.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy + protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array|string { - return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] - ? MissingDatabaseOptionPolicy::RejectIfMultiple - : MissingDatabaseOptionPolicy::ProcessAllDatabases; - } + if (!$this->isMultipleDatabases()) { + return [DatabaseRegistry::DEFAULT_DATABASE]; + } - protected function getMissingDatabaseOptionError(): string - { - return 'The --db option is required with --path or --namespace when multiple databases are configured.'; + return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] + ? 'The --db option is required with --path or --namespace when multiple databases are configured.' + : $this->getAllDatabaseNames(); } protected function createDefaultContext(): MigrationContext diff --git a/src/Command/RedoCommand.php b/src/Command/RedoCommand.php index cd839889..6b5a6ee9 100644 --- a/src/Command/RedoCommand.php +++ b/src/Command/RedoCommand.php @@ -64,11 +64,6 @@ protected function configure(): void ->addOption('force-yes', 'y', InputOption::VALUE_NONE, 'Force yes to all questions.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy - { - return MissingDatabaseOptionPolicy::RejectIfMultiple; - } - protected function createDefaultContext(): RedoContext { return new RedoContext($this->migrator, $this->migrationService, $this->downRunner, $this->updateRunner); diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php index a0a797e6..98ac5a4b 100644 --- a/src/Command/UpdateCommand.php +++ b/src/Command/UpdateCommand.php @@ -61,16 +61,15 @@ protected function configure(): void ->addOption('force-yes', 'y', InputOption::VALUE_NONE, 'Force yes to all questions.'); } - protected function getMissingDatabaseOptionPolicy(InputInterface $input): MissingDatabaseOptionPolicy + protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array|string { - return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] - ? MissingDatabaseOptionPolicy::RejectIfMultiple - : MissingDatabaseOptionPolicy::ProcessAllDatabases; - } + if (!$this->isMultipleDatabases()) { + return [DatabaseRegistry::DEFAULT_DATABASE]; + } - protected function getMissingDatabaseOptionError(): string - { - return 'The --db option is required with --path or --namespace when multiple databases are configured.'; + return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] + ? 'The --db option is required with --path or --namespace when multiple databases are configured.' + : $this->getAllDatabaseNames(); } protected function createDefaultContext(): UpdateContext From ad634383301abf87b2c13c09ed62b008f15cea2f Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 16 Oct 2026 16:00:33 +0700 Subject: [PATCH 2/3] Fix --- src/Command/DatabaseCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Command/DatabaseCommand.php b/src/Command/DatabaseCommand.php index c2d35fe6..43f65614 100644 --- a/src/Command/DatabaseCommand.php +++ b/src/Command/DatabaseCommand.php @@ -125,7 +125,7 @@ protected function getAllDatabaseNames(): array protected function isMultipleDatabases(): bool { - return $this->additionalDatabases !== null; + return $this->additionalDatabases !== null && $this->additionalDatabases->getNames() !== []; } /** From 20eecdc0a6262f6c4629a525d34537acac355ddc Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 16 Oct 2026 16:10:24 +0700 Subject: [PATCH 3/3] Rename `getAllDatabaseNames()` to `getAvailableDatabaseNames()` --- src/Command/DatabaseCommand.php | 4 ++-- src/Command/HistoryCommand.php | 2 +- src/Command/NewCommand.php | 2 +- src/Command/UpdateCommand.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Command/DatabaseCommand.php b/src/Command/DatabaseCommand.php index 43f65614..8d271563 100644 --- a/src/Command/DatabaseCommand.php +++ b/src/Command/DatabaseCommand.php @@ -118,7 +118,7 @@ abstract protected function executeForDatabase( * @return string[] * @psalm-return non-empty-list */ - protected function getAllDatabaseNames(): array + protected function getAvailableDatabaseNames(): array { return [DatabaseRegistry::DEFAULT_DATABASE, ...($this->additionalDatabases?->getNames() ?? [])]; } @@ -144,7 +144,7 @@ private function resolveDatabaseNames(InputInterface $input): array|string return $this->resolveDatabaseNamesWithMissingOption($input); } - $availableNames = $this->getAllDatabaseNames(); + $availableNames = $this->getAvailableDatabaseNames(); if (!in_array($name, $availableNames, true)) { return 'Unknown database "' . OutputFormatter::escape($name) . '". Available databases: ' diff --git a/src/Command/HistoryCommand.php b/src/Command/HistoryCommand.php index 12087184..196446af 100644 --- a/src/Command/HistoryCommand.php +++ b/src/Command/HistoryCommand.php @@ -54,7 +54,7 @@ protected function configure(): void protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): array { - return $this->getAllDatabaseNames(); + return $this->getAvailableDatabaseNames(); } protected function createDefaultContext(): MigrationContext diff --git a/src/Command/NewCommand.php b/src/Command/NewCommand.php index 11dcbb6d..17150d3b 100644 --- a/src/Command/NewCommand.php +++ b/src/Command/NewCommand.php @@ -68,7 +68,7 @@ protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] ? 'The --db option is required with --path or --namespace when multiple databases are configured.' - : $this->getAllDatabaseNames(); + : $this->getAvailableDatabaseNames(); } protected function createDefaultContext(): MigrationContext diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php index 98ac5a4b..97a3d214 100644 --- a/src/Command/UpdateCommand.php +++ b/src/Command/UpdateCommand.php @@ -69,7 +69,7 @@ protected function resolveDatabaseNamesWithMissingOption(InputInterface $input): return $input->getOption('path') !== [] || $input->getOption('namespace') !== [] ? 'The --db option is required with --path or --namespace when multiple databases are configured.' - : $this->getAllDatabaseNames(); + : $this->getAvailableDatabaseNames(); } protected function createDefaultContext(): UpdateContext