setAliases(['dump-schema'])
->setDescription('Dump the schema for your database to a migration.')
->setHelp(<<<'EOT'
The %command.name% command dumps the schema for your database to a migration:
%command.full_name%
After dumping your schema to a migration, you can rollup your migrations using the migrations:rollup command.
EOT)
->addOption(
'formatted',
null,
InputOption::VALUE_NONE,
'Format the generated SQL.',
)
->addOption(
'namespace',
null,
InputOption::VALUE_REQUIRED,
'Namespace to use for the generated migrations (defaults to the first namespace definition).',
)
->addOption(
'filter-tables',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Filter the tables to dump via Regex.',
)
->addOption(
'line-length',
null,
InputOption::VALUE_OPTIONAL,
'Max line length of unformatted lines.',
'120',
);
}
/** @throws SchemaDumpRequiresNoMigrations */
public function execute(
InputInterface $input,
OutputInterface $output,
): int {
$formatted = $input->getOption('formatted');
$lineLength = (int) $input->getOption('line-length');
$schemaDumper = $this->getDependencyFactory()->getSchemaDumper();
if ($formatted) {
if (! class_exists(SqlFormatter::class)) {
throw InvalidOptionUsage::new(
'The "--formatted" option can only be used if the sql formatter is installed. Please run "composer require doctrine/sql-formatter".',
);
}
}
$namespace = $this->getNamespace($input, $output);
$this->checkNoPreviousDumpExistsForNamespace($namespace);
$fqcn = $this->getDependencyFactory()->getClassNameGenerator()->generateClassName($namespace);
$path = $schemaDumper->dump(
$fqcn,
$input->getOption('filter-tables'),
$formatted,
$lineLength,
);
$this->io->text([
sprintf('Dumped your schema to a new migration class at "%s"', $path),
'',
sprintf(
'To run just this migration for testing purposes, you can use migrations:execute --up "%s"',
addslashes($fqcn),
),
'',
sprintf(
'To revert the migration you can use migrations:execute --down "%s"',
addslashes($fqcn),
),
'',
'To use this as a rollup migration you can use the migrations:rollup command.',
'',
]);
return 0;
}
private function checkNoPreviousDumpExistsForNamespace(string $namespace): void
{
$migrations = $this->getDependencyFactory()->getMigrationRepository()->getMigrations();
foreach ($migrations->getItems() as $migration) {
if (str_contains((string) $migration->getVersion(), $namespace)) {
throw SchemaDumpRequiresNoMigrations::new($namespace);
}
}
}
}