Completed
Push — master ( b31514...603a9f )
by Changwan
06:16
created

Migrator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
ccs 0
cts 6
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Database\Migrator;
3
4
use DirectoryIterator;
5
use RuntimeException;
6
use SplFileInfo;
7
use Wandu\Database\Migrator\Contracts\Adapter;
8
use Wandu\Database\Migrator\Contracts\MigrationInformation;
9
use Wandu\DI\ContainerInterface;
10
11
class Migrator
12
{
13
    /** @var \Wandu\Database\Migrator\Contracts\Adapter */
14
    protected $adapter;
15
    
16
    /** @var \Wandu\Database\Migrator\Configuration */
17
    protected $config;
18
19
    /** @var \Wandu\DI\ContainerInterface */
20
    protected $container;
21
    
22
    /**
23
     * @param \Wandu\Database\Migrator\Contracts\Adapter $adapter
24
     * @param \Wandu\Database\Migrator\Configuration $config
25
     * @param \Wandu\DI\ContainerInterface $container
26
     */
27
    public function __construct(Adapter $adapter, Configuration $config, ContainerInterface $container)
28
    {
29
        $this->adapter = $adapter;
30
        $this->config = $config;
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * @return array|\Wandu\Database\Migrator\Contracts\MigrationInformation[]
36
     */
37
    public function getMigrationInformations()
38
    {
39
        $migrations = [];
40
        foreach ($this->getAllMigrationFiles() as $file) {
41
            $migration = new FileMigrationInformation($file);
42
            $migrations[$migration->getId()] = $migration;
43
        }
44
        foreach ($this->adapter->getAppliedIds() as $version) {
45
            if (!array_key_exists($version, $migrations)) {
46
                $migrations[$version] = new UnknownMigrationInformation($version);
47
            }
48
        }
49
        ksort($migrations);
50
        return array_values($migrations);
51
    }
52
53
    /**
54
     * @param \Wandu\Database\Migrator\Contracts\MigrationInformation $information
55
     * @return bool
56
     */
57
    public function isApplied(MigrationInformation $information): bool
58
    {
59
        return $this->adapter->isApplied($information->getId());
60
    }
61
62
    /**
63
     * @param string $migrationId
64
     */
65
    public function up($migrationId)
66
    {
67
        if (!preg_match('/^\d{6}_\d{6}$/', $migrationId)) {
68
            throw new RuntimeException("invalid migration id. it must be like 000000_000000.");
69
        }
70
        if ($this->adapter->isApplied($migrationId)) {
71
            throw new RuntimeException("this {$migrationId} is already applied.");
72
        }
73
74
        $migrationInfo = $this->getFileMigrationInformation($migrationId);
75
        $migrationInfo->loadMigrationFile();
76
77
        $this->adapter->getMigrationInstance($migrationInfo->getId(), $migrationInfo->getName())->up();
78
        $this->adapter->initialize();
79
        $this->adapter->up($migrationId);
80
    }
81
82
    /**
83
     * @param string $migrationId
84
     */
85
    public function down($migrationId)
86
    {
87
        if (!preg_match('/^\d{6}_\d{6}$/', $migrationId)) {
88
            throw new RuntimeException("invalid migration id. it must be like 000000_000000.");
89
        }
90
        if (!$this->adapter->isApplied($migrationId)) {
91
            throw new RuntimeException("this {$migrationId} is not already applied.");
92
        }
93
94
        $migrationInfo = $this->getFileMigrationInformation($migrationId);
95
        $migrationInfo->loadMigrationFile();
96
97
        $this->adapter->getMigrationInstance($migrationInfo->getId(), $migrationInfo->getName())->down();
98
        $this->adapter->initialize();
99
        $this->adapter->down($migrationId);
100
    }
101
102
    /**
103
     * @return array|\Wandu\Database\Migrator\FileMigrationInformation[]
104
     */
105
    public function migrate()
106
    {
107
        $migratedMigrations = [];
108
        $migrations = $this->getMigrationInformations();
109
        foreach ($migrations as $migration) {
110
            if (!$this->adapter->isApplied($migration->getId())) {
111
                $this->up($migration->getId());
112
                $migratedMigrations[] = $migration;
113
            }
114
        }
115
        return $migratedMigrations;
116
    }
117
118
    /**
119
     * @param string $migrationId
120
     * @return \Wandu\Database\Migrator\FileMigrationInformation
121
     */
122
    protected function getFileMigrationInformation($migrationId): FileMigrationInformation
123
    {
124
        foreach ($this->getAllMigrationFiles() as $file) {
125
            if (strpos($file, $migrationId . '_') !== false) {
126
                return new FileMigrationInformation($file);
127
            }
128
        }
129
        throw new RuntimeException("there is no migration id \"{$migrationId}\".");
130
    }
131
    
132
    /**
133
     * @return array
134
     */
135
    protected function getAllMigrationFiles()
136
    {
137
        $files = [];
138
        if (!is_dir($this->config->getPath())) {
139
            mkdir($this->config->getPath());
140
        }
141
        foreach (new DirectoryIterator($this->config->getPath()) as $file) {
142
            if ($file->isDot() || $file->isDir() || $file->getFilename()[0] === '.') continue;
143
            $files[] = $file->getFileInfo();
144
        }
145
        usort($files, function (SplFileInfo $file, SplFileInfo $nextFile) {
146
            if ($file->getFilename() > $nextFile->getFilename()) {
147
                return 1;
148
            }
149
            return $file->getFilename() < $nextFile->getFilename() ? -1 : 0;
150
        });
151
        return $files;
152
    }
153
}
154