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

Configuration::isAllOrNothing()   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 0
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\Configuration;
6
7
use DateTime;
8
use DateTimeInterface;
9
use DateTimeZone;
10
use Doctrine\Common\EventArgs;
11
use Doctrine\DBAL\Connection;
12
use Doctrine\DBAL\Connections\MasterSlaveConnection;
13
use Doctrine\Migrations\Configuration\Exception\MigrationsNamespaceRequired;
14
use Doctrine\Migrations\Configuration\Exception\ParameterIncompatibleWithFinder;
15
use Doctrine\Migrations\DependencyFactory;
16
use Doctrine\Migrations\Exception\MigrationException;
17
use Doctrine\Migrations\Exception\MigrationsDirectoryRequired;
18
use Doctrine\Migrations\Finder\MigrationDeepFinder;
19
use Doctrine\Migrations\Finder\MigrationFinder;
20
use Doctrine\Migrations\OutputWriter;
21
use Doctrine\Migrations\QueryWriter;
22
use Doctrine\Migrations\Version;
23
use function str_replace;
24
25
class Configuration
26
{
27
    public const VERSIONS_ORGANIZATION_BY_YEAR = 'year';
28
29
    public const VERSIONS_ORGANIZATION_BY_YEAR_AND_MONTH = 'year_and_month';
30
31
    public const VERSION_FORMAT = 'YmdHis';
32
33
    /** @var string|null */
34
    private $name;
35
36
    /** @var string */
37
    private $migrationsTableName = 'doctrine_migration_versions';
38
39
    /** @var string */
40
    private $migrationsColumnName = 'version';
41
42
    /** @var int */
43
    private $migrationsColumnLength = 255;
44
45
    /** @var string */
46
    private $migrationsExecutedAtColumnName = 'executed_at';
47
48
    /** @var string|null */
49
    private $migrationsDirectory;
50
51
    /** @var string|null */
52
    private $migrationsNamespace;
53
54
    /** @var bool */
55
    private $migrationsAreOrganizedByYear = false;
56
57
    /** @var bool */
58
    private $migrationsAreOrganizedByYearAndMonth = false;
59
60
    /** @var string|null */
61
    private $customTemplate;
62
63
    /** @var bool */
64
    private $isDryRun = false;
65
66
    /** @var bool */
67
    private $allOrNothing = false;
68
69
    /** @var Connection */
70
    private $connection;
71
72
    /** @var OutputWriter|null */
73
    private $outputWriter;
74
75
    /** @var MigrationFinder|null */
76
    private $migrationFinder;
77
78
    /** @var QueryWriter|null */
79
    private $queryWriter;
80
81
    /** @var DependencyFactory|null */
82
    private $dependencyFactory;
83
84 273
    public function __construct(
85
        Connection $connection,
86
        ?OutputWriter $outputWriter = null,
87
        ?MigrationFinder $migrationFinder = null,
88
        ?QueryWriter $queryWriter = null,
89
        ?DependencyFactory $dependencyFactory = null
90
    ) {
91 273
        $this->connection        = $connection;
92 273
        $this->outputWriter      = $outputWriter;
93 273
        $this->migrationFinder   = $migrationFinder;
94 273
        $this->queryWriter       = $queryWriter;
95 273
        $this->dependencyFactory = $dependencyFactory;
96 273
    }
97
98 69
    public function setName(string $name) : void
99
    {
100 69
        $this->name = $name;
101 69
    }
102
103 15
    public function getName() : ?string
104
    {
105 15
        return $this->name;
106
    }
107
108 196
    public function getConnection() : Connection
109
    {
110 196
        return $this->connection;
111
    }
112
113 93
    public function setMigrationsTableName(string $tableName) : void
114
    {
115 93
        $this->migrationsTableName = $tableName;
116 93
    }
117
118 83
    public function getMigrationsTableName() : string
119
    {
120 83
        return $this->migrationsTableName;
121
    }
122
123 70
    public function setMigrationsColumnName(string $columnName) : void
124
    {
125 70
        $this->migrationsColumnName = $columnName;
126 70
    }
127
128 77
    public function getMigrationsColumnName() : string
129
    {
130 77
        return $this->migrationsColumnName;
131
    }
132
133 69
    public function getQuotedMigrationsColumnName() : string
134
    {
135 69
        return $this->getDependencyFactory()
136 69
            ->getMigrationTable()
137 69
            ->getMigrationsColumn()
138 69
            ->getQuotedName($this->connection->getDatabasePlatform());
139
    }
140
141 47
    public function setMigrationsColumnLength(int $columnLength) : void
142
    {
143 47
        $this->migrationsColumnLength = $columnLength;
144 47
    }
145
146 77
    public function getMigrationsColumnLength() : int
147
    {
148 77
        return $this->migrationsColumnLength;
149
    }
150
151 49
    public function setMigrationsExecutedAtColumnName(string $migrationsExecutedAtColumnName) : void
152
    {
153 49
        $this->migrationsExecutedAtColumnName = $migrationsExecutedAtColumnName;
154 49
    }
155
156 77
    public function getMigrationsExecutedAtColumnName() : string
157
    {
158 77
        return $this->migrationsExecutedAtColumnName;
159
    }
160
161 54
    public function getQuotedMigrationsExecutedAtColumnName() : string
162
    {
163 54
        return $this->getDependencyFactory()
164 54
            ->getMigrationTable()
165 54
            ->getExecutedAtColumn()
166 54
            ->getQuotedName($this->connection->getDatabasePlatform());
167
    }
168
169 186
    public function setMigrationsDirectory(string $migrationsDirectory) : void
170
    {
171 186
        $this->migrationsDirectory = $migrationsDirectory;
172 186
    }
173
174 80
    public function getMigrationsDirectory() : ?string
175
    {
176 80
        return $this->migrationsDirectory;
177
    }
178
179 189
    public function setMigrationsNamespace(string $migrationsNamespace) : void
180
    {
181 189
        $this->migrationsNamespace = $migrationsNamespace;
182 189
    }
183
184 99
    public function getMigrationsNamespace() : ?string
185
    {
186 99
        return $this->migrationsNamespace;
187
    }
188
189 4
    public function setCustomTemplate(?string $customTemplate) : void
190
    {
191 4
        $this->customTemplate = $customTemplate;
192 4
    }
193
194 9
    public function getCustomTemplate() : ?string
195
    {
196 9
        return $this->customTemplate;
197
    }
198
199 22
    public function areMigrationsOrganizedByYear() : bool
200
    {
201 22
        return $this->migrationsAreOrganizedByYear;
202
    }
203
204
    /**
205
     * @throws MigrationException
206
     */
207 9
    public function setMigrationsAreOrganizedByYear(
208
        bool $migrationsAreOrganizedByYear = true
209
    ) : void {
210 9
        $this->ensureOrganizeMigrationsIsCompatibleWithFinder();
211
212 5
        $this->migrationsAreOrganizedByYear = $migrationsAreOrganizedByYear;
213 5
    }
214
215
    /**
216
     * @throws MigrationException
217
     */
218 10
    public function setMigrationsAreOrganizedByYearAndMonth(
219
        bool $migrationsAreOrganizedByYearAndMonth = true
220
    ) : void {
221 10
        $this->ensureOrganizeMigrationsIsCompatibleWithFinder();
222
223 10
        $this->migrationsAreOrganizedByYear         = $migrationsAreOrganizedByYearAndMonth;
224 10
        $this->migrationsAreOrganizedByYearAndMonth = $migrationsAreOrganizedByYearAndMonth;
225 10
    }
226
227 22
    public function areMigrationsOrganizedByYearAndMonth() : bool
228
    {
229 22
        return $this->migrationsAreOrganizedByYearAndMonth;
230
    }
231
232
    /** @throws MigrationException */
233 8
    public function setMigrationsFinder(MigrationFinder $migrationFinder) : void
234
    {
235 8
        if (($this->migrationsAreOrganizedByYear || $this->migrationsAreOrganizedByYearAndMonth)
236 8
            && ! ($migrationFinder instanceof MigrationDeepFinder)) {
237 4
            throw ParameterIncompatibleWithFinder::new(
238 4
                'organize-migrations',
239 4
                $migrationFinder
240
            );
241
        }
242
243 4
        $this->migrationFinder = $migrationFinder;
244 4
    }
245
246 159
    public function getMigrationsFinder() : MigrationFinder
247
    {
248 159
        if ($this->migrationFinder === null) {
249 155
            $this->migrationFinder = $this->getDependencyFactory()->getRecursiveRegexFinder();
250
        }
251
252 159
        return $this->migrationFinder;
253
    }
254
255
    /** @throws MigrationException */
256 125
    public function validate() : void
257
    {
258 125
        if ($this->migrationsNamespace === null) {
259 1
            throw MigrationsNamespaceRequired::new();
260
        }
261
262 124
        if ($this->migrationsDirectory === null) {
263 1
            throw MigrationsDirectoryRequired::new();
264
        }
265 123
    }
266
267 20
    public function hasVersionMigrated(Version $version) : bool
268
    {
269 20
        return $this->getDependencyFactory()->getMigrationRepository()->hasVersionMigrated($version);
270
    }
271
272
    /**
273
     * @return mixed[]
274
     */
275 2
    public function getVersionData(Version $version) : ?array
276
    {
277 2
        return $this->getDependencyFactory()->getMigrationRepository()->getVersionData($version);
278
    }
279
280 8
    public function resolveVersionAlias(string $alias) : ?string
281
    {
282 8
        return $this->getDependencyFactory()->getVersionAliasResolver()->resolveVersionAlias($alias);
283
    }
284
285 2
    public function setIsDryRun(bool $isDryRun) : void
286
    {
287 2
        $this->isDryRun = $isDryRun;
288 2
    }
289
290 65
    public function isDryRun() : bool
291
    {
292 65
        return $this->isDryRun;
293
    }
294
295 45
    public function setAllOrNothing(bool $allOrNothing) : void
296
    {
297 45
        $this->allOrNothing = $allOrNothing;
298 45
    }
299
300 6
    public function isAllOrNothing() : bool
301
    {
302 6
        return $this->allOrNothing;
303
    }
304
305 45
    public function isMigrationTableCreated() : bool
306
    {
307 45
        return $this->getDependencyFactory()->getMigrationTableStatus()->isCreated();
308
    }
309
310 63
    public function createMigrationTable() : bool
311
    {
312 63
        return $this->getDependencyFactory()->getMigrationTableManipulator()->createMigrationTable();
313
    }
314
315 14
    public function getDateTime(string $version) : string
316
    {
317 14
        $datetime = str_replace('Version', '', $version);
318 14
        $datetime = DateTime::createFromFormat('YmdHis', $datetime);
319
320 14
        if ($datetime === false) {
321 4
            return '';
322
        }
323
324 11
        return $datetime->format('Y-m-d H:i:s');
325
    }
326
327 9
    public function generateVersionNumber(?DateTimeInterface $now = null) : string
328
    {
329 9
        $now = $now ?: new DateTime('now', new DateTimeZone('UTC'));
330
331 9
        return $now->format(self::VERSION_FORMAT);
332
    }
333
334
    /**
335
     * Explicitely opens the database connection. This is done to play nice
336
     * with DBAL's MasterSlaveConnection. Which, in some cases, connects to a
337
     * follower when fetching the executed migrations. If a follower is lagging
338
     * significantly behind that means the migrations system may see unexecuted
339
     * migrations that were actually executed earlier.
340
     */
341 59
    public function connect() : bool
342
    {
343 59
        if ($this->connection instanceof MasterSlaveConnection) {
344 1
            return $this->connection->connect('master');
345
        }
346
347 58
        return $this->connection->connect();
348
    }
349
350 27
    public function dispatchMigrationEvent(string $eventName, string $direction, bool $dryRun) : void
351
    {
352 27
        $this->getDependencyFactory()->getEventDispatcher()->dispatchMigrationEvent(
353 27
            $eventName,
354 27
            $direction,
355 27
            $dryRun
356
        );
357 27
    }
358
359 53
    public function dispatchVersionEvent(
360
        Version $version,
361
        string $eventName,
362
        string $direction,
363
        bool $dryRun
364
    ) : void {
365 53
        $this->getDependencyFactory()->getEventDispatcher()->dispatchVersionEvent(
366 53
            $version,
367 53
            $eventName,
368 53
            $direction,
369 53
            $dryRun
370
        );
371 53
    }
372
373 1
    public function dispatchEvent(string $eventName, ?EventArgs $args = null) : void
374
    {
375 1
        $this->getDependencyFactory()->getEventDispatcher()->dispatchEvent(
376 1
            $eventName,
377 1
            $args
378
        );
379 1
    }
380
381 1
    public function getNumberOfExecutedMigrations() : int
382
    {
383 1
        return $this->getDependencyFactory()->getMigrationRepository()->getNumberOfExecutedMigrations();
384
    }
385
386 3
    public function getNumberOfAvailableMigrations() : int
387
    {
388 3
        return $this->getDependencyFactory()->getMigrationRepository()->getNumberOfAvailableMigrations();
389
    }
390
391 4
    public function getLatestVersion() : string
392
    {
393 4
        return $this->getDependencyFactory()->getMigrationRepository()->getLatestVersion();
394
    }
395
396
    /** @return string[] */
397 1
    public function getMigratedVersions() : array
398
    {
399 1
        return $this->getDependencyFactory()->getMigrationRepository()->getMigratedVersions();
400
    }
401
402
    /** @return string[] */
403 3
    public function getAvailableVersions() : array
404
    {
405 3
        return $this->getDependencyFactory()->getMigrationRepository()->getAvailableVersions();
406
    }
407
408 11
    public function getCurrentVersion() : string
409
    {
410 11
        return $this->getDependencyFactory()->getMigrationRepository()->getCurrentVersion();
411
    }
412
413
    /** @return Version[] */
414 63
    public function registerMigrationsFromDirectory(string $path) : array
415
    {
416 63
        $this->validate();
417
418 63
        return $this->getDependencyFactory()->getMigrationRepository()->registerMigrationsFromDirectory($path);
419
    }
420
421
    /** @throws MigrationException */
422 40
    public function registerMigration(string $version, string $class) : Version
423
    {
424 40
        return $this->getDependencyFactory()->getMigrationRepository()->registerMigration($version, $class);
425
    }
426
427
    /**
428
     * @param string[] $migrations
429
     *
430
     * @return Version[]
431
     */
432 5
    public function registerMigrations(array $migrations) : array
433
    {
434 5
        return $this->getDependencyFactory()->getMigrationRepository()->registerMigrations($migrations);
435
    }
436
437
    /**
438
     * @return Version[]
439
     */
440 10
    public function getMigrations() : array
441
    {
442 10
        return $this->getDependencyFactory()->getMigrationRepository()->getMigrations();
443
    }
444
445 20
    public function getVersion(string $version) : Version
446
    {
447 20
        return $this->getDependencyFactory()->getMigrationRepository()->getVersion($version);
448
    }
449
450 3
    public function hasVersion(string $version) : bool
451
    {
452 3
        return $this->getDependencyFactory()->getMigrationRepository()->hasVersion($version);
453
    }
454
455
    /** @return Version[] */
456 33
    public function getMigrationsToExecute(string $direction, string $to) : array
457
    {
458 33
        return $this->getDependencyFactory()->getMigrationPlanCalculator()->getMigrationsToExecute($direction, $to);
459
    }
460
461 2
    public function getPrevVersion() : ?string
462
    {
463 2
        return $this->getDependencyFactory()->getMigrationRepository()->getPrevVersion();
464
    }
465
466 3
    public function getNextVersion() : ?string
467
    {
468 3
        return $this->getDependencyFactory()->getMigrationRepository()->getNextVersion();
469
    }
470
471 3
    public function getRelativeVersion(string $version, int $delta) : ?string
472
    {
473 3
        return $this->getDependencyFactory()->getMigrationRepository()->getRelativeVersion($version, $delta);
474
    }
475
476 1
    public function getDeltaVersion(string $delta) : ?string
477
    {
478 1
        return $this->getDependencyFactory()->getMigrationRepository()->getDeltaVersion($delta);
479
    }
480
481 1
    public function setOutputWriter(OutputWriter $outputWriter) : void
482
    {
483 1
        $this->outputWriter = $outputWriter;
484 1
    }
485
486 127
    public function getOutputWriter() : OutputWriter
487
    {
488 127
        if ($this->outputWriter === null) {
489 96
            $this->outputWriter = $this->getDependencyFactory()->getOutputWriter();
490
        }
491
492 127
        return $this->outputWriter;
493
    }
494
495 7
    public function getQueryWriter() : QueryWriter
496
    {
497 7
        if ($this->queryWriter === null) {
498 6
            $this->queryWriter = $this->getDependencyFactory()->getQueryWriter();
499
        }
500
501 7
        return $this->queryWriter;
502
    }
503
504 198
    public function getDependencyFactory() : DependencyFactory
505
    {
506 198
        if ($this->dependencyFactory === null) {
507 197
            $this->dependencyFactory = new DependencyFactory($this);
508
        }
509
510 198
        return $this->dependencyFactory;
511
    }
512
513
    /**
514
     * @throws MigrationException
515
     */
516 19
    private function ensureOrganizeMigrationsIsCompatibleWithFinder() : void
517
    {
518 19
        if (! ($this->getMigrationsFinder() instanceof MigrationDeepFinder)) {
519 4
            throw ParameterIncompatibleWithFinder::new(
520 4
                'organize-migrations',
521 4
                $this->getMigrationsFinder()
522
            );
523
        }
524 15
    }
525
}
526