Completed
Pull Request — master (#971)
by Grégoire
03:53
created

DumpSchemaCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 67.16%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 70
c 2
b 0
f 0
dl 0
loc 113
ccs 45
cts 67
cp 0.6716
rs 10
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 39 1
A checkNoPreviousDumpExistsForNamespace() 0 6 3
A execute() 0 55 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Command;
6
7
use Doctrine\Migrations\Tools\Console\Exception\InvalidOptionUsage;
8
use Doctrine\Migrations\Tools\Console\Exception\SchemaDumpRequiresNoMigrations;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use function addslashes;
13
use function assert;
14
use function class_exists;
15
use function is_string;
16
use function key;
17
use function sprintf;
18
use function strpos;
19
20
/**
21
 * The DumpSchemaCommand class is responsible for dumping your current database schema to a migration class. This is
22
 * intended to be used in conjunction with the RollupCommand.
23
 *
24
 * @see Doctrine\Migrations\Tools\Console\Command\RollupCommand
25
 */
26
final class DumpSchemaCommand extends DoctrineCommand
27
{
28
    /** @var string */
29
    protected static $defaultName = 'migrations:dump-schema';
30
31 1
    protected function configure() : void
32
    {
33 1
        parent::configure();
34
35
        $this
36 1
            ->setAliases(['dump-schema'])
37 1
            ->setDescription('Dump the schema for your database to a migration.')
38 1
            ->setHelp(<<<EOT
39 1
The <info>%command.name%</info> command dumps the schema for your database to a migration:
40
41
    <info>%command.full_name%</info>
42
43
After dumping your schema to a migration, you can rollup your migrations using the <info>migrations:rollup</info> command.
44
EOT
45
            )
46 1
            ->addOption(
47 1
                'formatted',
48 1
                null,
49 1
                InputOption::VALUE_NONE,
50 1
                'Format the generated SQL.'
51
            )
52 1
            ->addOption(
53 1
                'namespace',
54 1
                null,
55 1
                InputOption::VALUE_REQUIRED,
56 1
                'Namespace to use for the generated migrations (defaults to the first namespace definition).'
57
            )
58 1
            ->addOption(
59 1
                'filter-tables',
60 1
                null,
61 1
                InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY,
62 1
                'Filter the tables to dump via Regex.'
63
            )
64 1
            ->addOption(
65 1
                'line-length',
66 1
                null,
67 1
                InputOption::VALUE_OPTIONAL,
68 1
                'Max line length of unformatted lines.',
69 1
                120
70
            );
71 1
    }
72
73
    /**
74
     * @throws SchemaDumpRequiresNoMigrations
75
     */
76 1
    public function execute(
77
        InputInterface $input,
78
        OutputInterface $output
79
    ) : int {
80 1
        $formatted  = $input->getOption('formatted');
81 1
        $lineLength = (int) $input->getOption('line-length');
82
83 1
        $schemaDumper = $this->getDependencyFactory()->getSchemaDumper();
84
85 1
        if ($formatted) {
86
            if (! class_exists('SqlFormatter')) {
87
                throw InvalidOptionUsage::new(
88
                    'The "--formatted" option can only be used if the sql formatter is installed. Please run "composer require jdorn/sql-formatter".'
89
                );
90
            }
91
        }
92
93 1
        $configuration = $this->getDependencyFactory()->getConfiguration();
94
95 1
        $namespace = $input->getOption('namespace');
96 1
        if ($namespace === null) {
97 1
            $dirs      = $configuration->getMigrationDirectories();
98 1
            $namespace = key($dirs);
99
        }
100
101 1
        assert(is_string($namespace));
102
103 1
        $this->checkNoPreviousDumpExistsForNamespace($namespace);
104
105
        $fqcn = $this->getDependencyFactory()->getClassNameGenerator()->generateClassName($namespace);
106
107
        $path = $schemaDumper->dump(
108
            $fqcn,
109
            $input->getOption('filter-tables'),
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('filter-tables') can also be of type boolean and null and string; however, parameter $excludedTablesRegexes of Doctrine\Migrations\SchemaDumper::dump() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
            /** @scrutinizer ignore-type */ $input->getOption('filter-tables'),
Loading history...
110
            $formatted,
111
            $lineLength
112
        );
113
114
        $output->writeln([
115
            sprintf('Dumped your schema to a new migration class at "<info>%s</info>"', $path),
116
            '',
117
            sprintf(
118
                'To run just this migration for testing purposes, you can use <info>migrations:execute --up \'%s\'</info>',
119
                addslashes($fqcn)
120
            ),
121
            '',
122
            sprintf(
123
                'To revert the migration you can use <info>migrations:execute --down \'%s\'</info>',
124
                addslashes($fqcn)
125
            ),
126
            '',
127
            'To use this as a rollup migration you can use the <info>migrations:rollup</info> command.',
128
        ]);
129
130
        return 0;
131
    }
132
133 1
    private function checkNoPreviousDumpExistsForNamespace(string $namespace) : void
134
    {
135 1
        $migrations = $this->getDependencyFactory()->getMigrationRepository()->getMigrations();
136 1
        foreach ($migrations->getItems() as $migration) {
137 1
            if (strpos((string) $migration->getVersion(), $namespace) !== false) {
138 1
                throw SchemaDumpRequiresNoMigrations::new($namespace);
139
            }
140
        }
141
    }
142
}
143