ExecuteCommand::execute()   B
last analyzed

Complexity

Conditions 8
Paths 7

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 8.0291

Importance

Changes 0
Metric Value
dl 0
loc 51
ccs 24
cts 26
cp 0.9231
rs 7.8246
c 0
b 0
f 0
cc 8
nc 7
nop 2
crap 8.0291

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Command;
6
7
use Doctrine\Migrations\Version\Direction;
8
use Doctrine\Migrations\Version\Version;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use function array_map;
14
use function getcwd;
15
use function implode;
16
use function is_string;
17
use function is_writable;
18
use function sprintf;
19
20
/**
21
 * The ExecuteCommand class is responsible for executing migration versions up or down manually.
22
 */
23
final class ExecuteCommand extends DoctrineCommand
24
{
25
    /** @var string */
26
    protected static $defaultName = 'migrations:execute';
27
28 9 View Code Duplication
    protected function configure() : void
29
    {
30
        $this
31 9
            ->setAliases(['execute'])
32 9
            ->setDescription(
33 9
                'Execute one or more migration versions up or down manually.'
34
            )
35 9
            ->addArgument(
36 9
                'versions',
37 9
                InputArgument::REQUIRED|InputArgument::IS_ARRAY,
38 9
                'The versions to execute.',
39 9
                null
40
            )
41 9
            ->addOption(
42 9
                'write-sql',
43 9
                null,
44 9
                InputOption::VALUE_OPTIONAL,
45 9
                'The path to output the migration SQL file. Defaults to current working directory.',
46 9
                false
47
            )
48 9
            ->addOption(
49 9
                'dry-run',
50 9
                null,
51 9
                InputOption::VALUE_NONE,
52 9
                'Execute the migration as a dry run.'
53
            )
54 9
            ->addOption(
55 9
                'up',
56 9
                null,
57 9
                InputOption::VALUE_NONE,
58 9
                'Execute the migration up.'
59
            )
60 9
            ->addOption(
61 9
                'down',
62 9
                null,
63 9
                InputOption::VALUE_NONE,
64 9
                'Execute the migration down.'
65
            )
66 9
            ->addOption(
67 9
                'query-time',
68 9
                null,
69 9
                InputOption::VALUE_NONE,
70 9
                'Time all the queries individually.'
71
            )
72 9
            ->setHelp(<<<EOT
73 9
The <info>%command.name%</info> command executes migration versions up or down manually:
74
75
    <info>%command.full_name% FQCN</info>
76
77
You can show more information about the process by increasing the verbosity level. To see the
78
executed queries, set the level to debug with <comment>-vv</comment>:
79
80
    <info>%command.full_name% FQCN -vv</info>
81
82
If no <comment>--up</comment> or <comment>--down</comment> option is specified it defaults to up:
83
84
    <info>%command.full_name% FQCN --down</info>
85
86
You can also execute the migration as a <comment>--dry-run</comment>:
87
88
    <info>%command.full_name% FQCN --dry-run</info>
89
90
You can output the prepared SQL statements to a file with <comment>--write-sql</comment>:
91
92
    <info>%command.full_name% FQCN --write-sql</info>
93
94
Or you can also execute the migration without a warning message which you need to interact with:
95
96
    <info>%command.full_name% FQCN --no-interaction</info>
97
98
All the previous commands accept multiple migration versions, allowing you run execute more than
99
one migration at once:
100 9
101 9
    <info>%command.full_name% FQCN-1 FQCN-2 ...FQCN-n </info>
102
103 9
EOT
104
        );
105 9
106 9
        parent::configure();
107
    }
108 9
109 9
    protected function execute(InputInterface $input, OutputInterface $output) : int
110 1
    {
111
        $migratorConfigurationFactory = $this->getDependencyFactory()->getConsoleInputMigratorConfigurationFactory();
112 1
        $migratorConfiguration        = $migratorConfigurationFactory->getMigratorConfiguration($input);
113
114
        $question = 'WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue?';
115 8
        if (! $migratorConfiguration->isDryRun() && ! $this->canExecute($question, $input)) {
116
            $this->io->error('Migration cancelled!');
117 8
118 8
            return 1;
119 8
        }
120 8
121
        $this->getDependencyFactory()->getMetadataStorage()->ensureInitialized();
122 8
123 8
        $versions  = $input->getArgument('versions');
124
        $direction = $input->getOption('down') !== false
125
            ? Direction::DOWN
126
            : Direction::UP;
127
128
        $path = $input->getOption('write-sql') ?? getcwd();
129 8
        if (is_string($path) && ! is_writable($path)) {
130
            $this->io->error(sprintf('The path "%s" not writeable!', $path));
131 8
132 8
            return 1;
133
        }
134 8
135 8
        $planCalculator = $this->getDependencyFactory()->getMigrationPlanCalculator();
136
        $plan           = $planCalculator->getPlanForVersions(array_map(static function (string $version) : Version {
137 8
            return new Version($version);
138 8
        }, $versions), $direction);
139
140
        $this->getDependencyFactory()->getLogger()->notice(
141
            'Executing' . ($migratorConfiguration->isDryRun() ? ' (dry-run)' : '') . ' {versions} {direction}',
142 8
            [
143 8
                'direction' => $plan->getDirection(),
144
                'versions' => implode(', ', $versions),
145 8
            ]
146 4
        );
147 4
148
        $migrator = $this->getDependencyFactory()->getMigrator();
149
        $sql      = $migrator->migrate($plan, $migratorConfiguration);
150 8
151
        if (is_string($path)) {
152 8
            $writer = $this->getDependencyFactory()->getQueryWriter();
153
            $writer->write($path, $direction, $sql);
154
        }
155
156
        $this->io->newLine();
157
158
        return 0;
159
    }
160
}
161