Failed Conditions
Pull Request — master (#632)
by Michael
02:44
created

Migration::migrate()   D

Complexity

Conditions 15
Paths 42

Size

Total Lines 86
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 15.0032

Importance

Changes 0
Metric Value
cc 15
eloc 40
nc 42
nop 4
dl 0
loc 86
ccs 40
cts 41
cp 0.9756
crap 15.0032
rs 4.9121
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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;
6
7
use Doctrine\Migrations\Configuration\Configuration;
8
use Doctrine\Migrations\Event\MigrationsEventArgs;
9
use const COUNT_RECURSIVE;
10
use function count;
11
use function sprintf;
12
13
class Migration
14
{
15
    /** @var OutputWriter */
16
    private $outputWriter;
17
18
    /** @var Configuration */
19
    private $configuration;
20
21
    /** @var bool */
22
    private $noMigrationException;
23
24 37
    public function __construct(Configuration $configuration)
25
    {
26 37
        $this->configuration        = $configuration;
27 37
        $this->outputWriter         = $configuration->getOutputWriter();
28 37
        $this->noMigrationException = false;
29 37
    }
30
31
    /** @return string[] */
32 2
    public function getSql(?string $to = null) : array
33
    {
34 2
        return $this->migrate($to, true);
35
    }
36
37 6
    public function writeSqlFile(string $path, ?string $to = null) : bool
38
    {
39 6
        $sql  = $this->getSql($to);
40 6
        $from = $this->configuration->getCurrentVersion();
41
42 6
        if ($to === null) {
43 1
            $to = $this->configuration->getLatestVersion();
44
        }
45
46 6
        $direction = $from > $to
47 1
            ? Version::DIRECTION_DOWN
48 6
            : Version::DIRECTION_UP;
49
50 6
        $this->outputWriter->write(
51 6
            sprintf("-- Migrating from %s to %s\n", $from, $to)
52
        );
53
54
        /**
55
         * Since the configuration object changes during the creation we cannot inject things
56
         * properly, so I had to violate LoD here (so please, let's find a way to solve it on v2).
57
         */
58 6
        return $this->configuration
59 6
            ->getQueryWriter()
60 6
            ->write($path, $direction, $sql);
61
    }
62
63 2
    public function setNoMigrationException(bool $noMigrationException = false) : void
64
    {
65 2
        $this->noMigrationException = $noMigrationException;
66 2
    }
67
68
    /**
69
     * @throws MigrationException
70
     *
71
     * @return string[]
72
     */
73 31
    public function migrate(
74
        ?string $to = null,
75
        bool $dryRun = false,
76
        bool $timeAllQueries = false,
77
        ?callable $confirm = null
78
    ) : array {
79
        /**
80
         * If no version to migrate to is given we default to the last available one.
81
         */
82 31
        if ($to === null) {
83 14
            $to = $this->configuration->getLatestVersion();
84
        }
85
86 31
        $from = $this->configuration->getCurrentVersion();
87 31
        $to   = $to;
88
89
        /**
90
         * Throw an error if we can't find the migration to migrate to in the registered
91
         * migrations.
92
         */
93 31
        $migrations = $this->configuration->getMigrations();
94 31
        if (! isset($migrations[$to]) && $to > 0) {
95 1
            throw MigrationException::unknownMigrationVersion($to);
96
        }
97
98 30
        $direction = $from > $to
99 3
            ? Version::DIRECTION_DOWN
100 30
            : Version::DIRECTION_UP;
101
102 30
        $migrationsToExecute = $this->configuration
103 30
            ->getMigrationsToExecute($direction, $to);
104
105
        /**
106
         * If
107
         *  there are no migrations to execute
108
         *  and there are migrations,
109
         *  and the migration from and to are the same
110
         * means we are already at the destination return an empty array()
111
         * to signify that there is nothing left to do.
112
         */
113 30
        if ($from === $to && empty($migrationsToExecute) && ! empty($migrations)) {
114 2
            return $this->noMigrations();
115
        }
116
117 29
        if (! $dryRun && $this->migrationsCanExecute($confirm) === false) {
118 1
            return [];
119
        }
120
121 28
        $output  = $dryRun ? 'Executing dry run of migration' : 'Migrating';
122 28
        $output .= ' <info>%s</info> to <comment>%s</comment> from <comment>%s</comment>';
123 28
        $this->outputWriter->write(sprintf($output, $direction, $to, $from));
124
125
        /**
126
         * If there are no migrations to execute throw an exception.
127
         */
128 28
        if (empty($migrationsToExecute) && ! $this->noMigrationException) {
129 1
            throw MigrationException::noMigrationsToExecute();
130
        } elseif (empty($migrationsToExecute)) {
131 1
            return $this->noMigrations();
132
        }
133
134 26
        $this->configuration->dispatchEvent(
135 26
            Events::onMigrationsMigrating,
136 26
            new MigrationsEventArgs($this->configuration, $direction, $dryRun)
137
        );
138
139 26
        $sql  = [];
140 26
        $time = 0;
141
142 26
        foreach ($migrationsToExecute as $version) {
143 26
            $versionSql                  = $version->execute($direction, $dryRun, $timeAllQueries);
144 26
            $sql[$version->getVersion()] = $versionSql;
145 26
            $time                       += $version->getTime();
146
        }
147
148 26
        $this->configuration->dispatchEvent(
149 26
            Events::onMigrationsMigrated,
150 26
            new MigrationsEventArgs($this->configuration, $direction, $dryRun)
151
        );
152
153 26
        $this->outputWriter->write("\n  <comment>------------------------</comment>\n");
154 26
        $this->outputWriter->write(sprintf('  <info>++</info> finished in %ss', $time));
155 26
        $this->outputWriter->write(sprintf('  <info>++</info> %s migrations executed', count($migrationsToExecute)));
156 26
        $this->outputWriter->write(sprintf('  <info>++</info> %s sql queries', count($sql, COUNT_RECURSIVE) - count($sql)));
157
158 26
        return $sql;
159
    }
160
161
    /** @return string[] */
162 3
    private function noMigrations() : array
163
    {
164 3
        $this->outputWriter->write('<comment>No migrations to execute.</comment>');
165
166 3
        return [];
167
    }
168
169 27
    private function migrationsCanExecute(?callable $confirm = null) : bool
170
    {
171 27
        return $confirm === null ? true : (bool) $confirm();
172
    }
173
}
174