Completed
Pull Request — master (#910)
by Asmir
02:27
created

MigrationRepository   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Test Coverage

Coverage 98%

Importance

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