Passed
Pull Request — master (#683)
by Jonathan
02:21
created

Version::writeSqlFile()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 2
dl 0
loc 24
ccs 11
cts 11
cp 1
crap 2
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use DateTimeImmutable;
8
use Doctrine\DBAL\Connection;
9
use Doctrine\DBAL\Types\Type;
10
use Doctrine\Migrations\Configuration\Configuration;
11
use Doctrine\Migrations\Exception\MigrationNotConvertibleToSql;
12
use function assert;
13
use function count;
14
use function in_array;
15
use function str_replace;
16
17
class Version implements VersionInterface
18
{
19
    /** @var Configuration */
20
    private $configuration;
21
22
    /** @var OutputWriter */
23
    private $outputWriter;
24
25
    /** @var string */
26
    private $version;
27
28
    /** @var AbstractMigration */
29
    private $migration;
30
31
    /** @var Connection */
32
    private $connection;
33
34
    /** @var string */
35
    private $class;
36
37
    /** @var int */
38
    private $state = VersionState::NONE;
39
40
    /** @var VersionExecutorInterface */
41
    private $versionExecutor;
42
43 125
    public function __construct(
44
        Configuration $configuration,
45
        string $version,
46
        string $class,
47
        VersionExecutorInterface $versionExecutor
48
    ) {
49 125
        $this->configuration   = $configuration;
50 125
        $this->outputWriter    = $configuration->getOutputWriter();
51 125
        $this->class           = $class;
52 125
        $this->connection      = $configuration->getConnection();
53 125
        $this->migration       = new $class($this);
54 125
        $this->version         = $version;
55 125
        $this->versionExecutor = $versionExecutor;
56 125
    }
57
58 55
    public function __toString() : string
59
    {
60 55
        return $this->version;
61
    }
62
63 79
    public function getVersion() : string
64
    {
65 79
        return $this->version;
66
    }
67
68 1
    public function getDateTime() : string
69
    {
70 1
        $datetime = str_replace('Version', '', $this->version);
71 1
        $datetime = DateTimeImmutable::createFromFormat('YmdHis', $datetime);
72
73 1
        if ($datetime === false) {
74 1
            return '';
75
        }
76
77 1
        return $datetime->format('Y-m-d H:i:s');
78
    }
79
80 125
    public function getConfiguration() : Configuration
81
    {
82 125
        return $this->configuration;
83
    }
84
85 14
    public function getMigration() : AbstractMigration
86
    {
87 14
        return $this->migration;
88
    }
89
90 16
    public function isMigrated() : bool
91
    {
92 16
        return $this->configuration->hasVersionMigrated($this);
93
    }
94
95 1
    public function getExecutedAt() : ?DateTimeImmutable
96
    {
97 1
        $versionData          = $this->configuration->getVersionData($this);
98 1
        $executedAtColumnName = $this->configuration->getMigrationsExecutedAtColumnName();
99
100 1
        return isset($versionData[$executedAtColumnName])
101 1
            ? new DateTimeImmutable($versionData[$executedAtColumnName])
102 1
            : null;
103
    }
104
105 55
    public function setState(int $state) : void
106
    {
107 55
        assert(in_array($state, VersionState::STATES, true));
108
109 55
        $this->state = $state;
110 55
    }
111
112 11
    public function getExecutionState() : string
113
    {
114 11
        switch ($this->state) {
115 11
            case VersionState::PRE:
116 1
                return 'Pre-Checks';
117
118 10
            case VersionState::POST:
119 1
                return 'Post-Checks';
120
121 9
            case VersionState::EXEC:
122 3
                return 'Execution';
123
124
            default:
125 6
                return 'No State';
126
        }
127
    }
128
129
    /**
130
     * @param mixed[] $params
131
     * @param mixed[] $types
132
     */
133 32
    public function addSql(string $sql, array $params = [], array $types = []) : void
134
    {
135 32
        $this->versionExecutor->addSql($sql, $params, $types);
136 32
    }
137
138 9
    public function writeSqlFile(
139
        string $path,
140
        string $direction = VersionDirection::UP
141
    ) : bool {
142 9
        $versionExecutionResult = $this->execute(
143 9
            $direction,
144 9
            $this->getWriteSqlFileMigratorConfig()
145
        );
146
147 9
        if (count($versionExecutionResult->getParams()) !== 0) {
148 1
            throw MigrationNotConvertibleToSql::new($this->class);
149
        }
150
151 8
        $this->outputWriter->write("\n-- Version " . $this->version . "\n");
152
153 8
        $sqlQueries = [$this->version => $versionExecutionResult->getSql()];
154
155
        /*
156
         * Since the configuration object changes during the creation we cannot inject things
157
         * properly, so I had to violate LoD here (so please, let's find a way to solve it on v2).
158
         */
159 8
        return $this->configuration
160 8
            ->getQueryWriter()
161 8
            ->write($path, $direction, $sqlQueries);
162
    }
163
164 53
    public function execute(
165
        string $direction,
166
        ?MigratorConfig $migratorConfig = null
167
    ) : VersionExecutionResult {
168 53
        return $this->versionExecutor->execute(
169 53
            $this,
170 53
            $this->migration,
171 53
            $direction,
172 53
            $migratorConfig
173
        );
174
    }
175
176 11
    public function markMigrated() : void
177
    {
178 11
        $this->markVersion(VersionDirection::UP);
179 11
    }
180
181 3
    public function markNotMigrated() : void
182
    {
183 3
        $this->markVersion(VersionDirection::DOWN);
184 3
    }
185
186 47
    public function markVersion(string $direction) : void
187
    {
188 47
        $this->configuration->createMigrationTable();
189
190 47
        $migrationsColumnName = $this->configuration
191 47
            ->getQuotedMigrationsColumnName();
192
193 47
        $migrationsExecutedAtColumnName = $this->configuration
194 47
            ->getQuotedMigrationsExecutedAtColumnName();
195
196 47
        if ($direction === VersionDirection::UP) {
197 46
            $this->connection->insert(
198 46
                $this->configuration->getMigrationsTableName(),
199
                [
200 46
                    $migrationsColumnName => $this->version,
201 46
                    $migrationsExecutedAtColumnName => $this->getExecutedAtDatabaseValue(),
202
                ]
203
            );
204
205 46
            return;
206
        }
207
208 10
        $this->connection->delete(
209 10
            $this->configuration->getMigrationsTableName(),
210
            [
211 10
                $migrationsColumnName => $this->version,
212
            ]
213
        );
214 10
    }
215
216 9
    private function getWriteSqlFileMigratorConfig() : MigratorConfig
217
    {
218 9
        return (new MigratorConfig())->setDryRun(true);
219
    }
220
221 46
    private function getExecutedAtDatabaseValue() : string
222
    {
223 46
        return Type::getType(MigrationTable::MIGRATION_EXECUTED_AT_COLUMN_TYPE)->convertToDatabaseValue(
0 ignored issues
show
Bug Best Practice introduced by
The expression return Doctrine\DBAL\Typ...>getDatabasePlatform()) returns the type DateTimeImmutable which is incompatible with the type-hinted return string.
Loading history...
224 46
            new DateTimeImmutable(),
225 46
            $this->connection->getDatabasePlatform()
226
        );
227
    }
228
}
229