Completed
Pull Request — master (#902)
by Andrej
02:38
created

MigrationRepository   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Test Coverage

Coverage 98%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 45
dl 0
loc 135
ccs 49
cts 50
cp 0.98
rs 10
c 2
b 0
f 0
wmc 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getMigrations() 0 5 1
A ensureMigrationClassExists() 0 4 2
A getMigration() 0 9 2
A hasMigration() 0 5 1
A registerMigration() 0 8 1
A registerMigrations() 0 9 2
A __construct() 0 13 1
A registerMigrationInstance() 0 12 2
A loadMigrationsFromDirectories() 0 19 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use Doctrine\Migrations\Exception\DuplicateMigrationVersion;
8
use Doctrine\Migrations\Exception\MigrationClassNotFound;
9
use Doctrine\Migrations\Exception\MigrationException;
10
use Doctrine\Migrations\Finder\MigrationFinder;
11
use Doctrine\Migrations\Metadata\AvailableMigration;
12
use Doctrine\Migrations\Metadata\AvailableMigrationsList;
13
use Doctrine\Migrations\Version\MigrationFactory;
14
use Doctrine\Migrations\Version\Version;
15
use function class_exists;
16
17
/**
18
 * The MigrationRepository class is responsible for retrieving migrations, determing what the current migration
19
 * version, etc.
20
 *
21
 * @internal
22
 */
23
class MigrationRepository
24
{
25
    /** @var bool */
26
    private $migrationsLoaded = false;
27
28
    /** @var array<string, string> */
29
    private $migrationDirectories;
30
31
    /** @var MigrationFinder */
32
    private $migrationFinder;
33
34
    /** @var MigrationFactory */
35
    private $versionFactory;
36
37
    /** @var AvailableMigration[] */
38
    private $migrations = [];
39
40
    /** @var Sorter */
41
    private $sorter;
42
43
    /**
44
     * @param array<string, string> $migrationDirectories
45
     * @param string[]              $classes
46
     */
47 63
    public function __construct(
48
        array $classes,
49
        array $migrationDirectories,
50
        MigrationFinder $migrationFinder,
51
        MigrationFactory $versionFactory,
52
        Sorter $sorter
53
    ) {
54 63
        $this->migrationDirectories = $migrationDirectories;
55 63
        $this->migrationFinder      = $migrationFinder;
56 63
        $this->versionFactory       = $versionFactory;
57 63
        $this->sorter               = $sorter;
58
59 63
        $this->registerMigrations($classes);
60 63
    }
61
62
    /**
63
     * @internal DO NOT USE, THIS METHOD IS HERE ONLY TO EASE THE TESTING, WILL BE REMOVED IN UPCOMING MINOR/BUGFIX RELEASE
64
     */
65 52
    public function registerMigrationInstance(Version $version, AbstractMigration $migration) : AvailableMigration
66
    {
67 52
        if (isset($this->migrations[(string) $version])) {
68 1
            throw DuplicateMigrationVersion::new(
69 1
                (string) $version,
70 1
                (string) $version
71
            );
72
        }
73
74 52
        $this->migrations[(string) $version] = new AvailableMigration($version, $migration);
75
76 52
        return $this->migrations[(string) $version];
77
    }
78
79
    /** @throws MigrationException */
80 7
    public function registerMigration(string $migrationClassName) : AvailableMigration
81
    {
82 7
        $this->ensureMigrationClassExists($migrationClassName);
83
84 7
        $version   = new Version($migrationClassName);
85 7
        $migration = $this->versionFactory->createVersion($migrationClassName);
86
87 7
        return $this->registerMigrationInstance($version, $migration);
88
    }
89
90
    /**
91
     * @param string[] $migrations
92
     *
93
     * @return AvailableMigration[]
94
     */
95 63
    private function registerMigrations(array $migrations) : array
96
    {
97 63
        $versions = [];
98
99 63
        foreach ($migrations as $class) {
100 7
            $versions[] = $this->registerMigration($class);
101
        }
102
103 63
        return $versions;
104
    }
105
106 1
    public function hasMigration(string $version) : bool
107
    {
108 1
        $this->loadMigrationsFromDirectories();
109
110 1
        return isset($this->migrations[$version]);
111
    }
112
113 12
    public function getMigration(Version $version) : AvailableMigration
114
    {
115 12
        $this->loadMigrationsFromDirectories();
116
117 12
        if (! isset($this->migrations[(string) $version])) {
118 3
            throw MigrationClassNotFound::new((string) $version);
119
        }
120
121 10
        return $this->migrations[(string) $version];
122
    }
123
124 54
    public function getMigrations() : AvailableMigrationsList
125
    {
126 54
        $this->loadMigrationsFromDirectories();
127
128 54
        return new AvailableMigrationsList($this->migrations);
129
    }
130
131
    /** @throws MigrationException */
132 7
    private function ensureMigrationClassExists(string $class) : void
133
    {
134 7
        if (! class_exists($class)) {
135
            throw MigrationClassNotFound::new($class);
136
        }
137 7
    }
138
139 57
    private function loadMigrationsFromDirectories() : void
140
    {
141 57
        $migrationDirectories = $this->migrationDirectories;
142
143 57
        if ($this->migrationsLoaded) {
144 33
            return;
145
        }
146
147 57
        $this->migrationsLoaded = true;
148
149 57
        foreach ($migrationDirectories as $namespace => $path) {
150 37
                $migrations = $this->migrationFinder->findMigrations(
151 37
                    $path,
152 37
                    $namespace
153
                );
154 37
                $this->registerMigrations($migrations);
155
        }
156
157 57
        $this->sorter->sort($this->migrations);
158 57
    }
159
}
160