Failed Conditions
Push — master ( 0469de...12f4fc )
by Jonathan
02:19
created

Migration::getSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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