Passed
Pull Request — master (#784)
by Mathias
02:38
created

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