Passed
Push — master ( 43d44e...77a103 )
by Mr
07:17
created

Migration::getName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
ccs 0
cts 7
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/dbal project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\Dbal\Migration;
10
11
use Daikon\Dbal\Connector\ConnectorInterface;
12
use Daikon\Interop\Assertion;
13
use Daikon\Interop\RuntimeException;
14
use DateTimeImmutable;
15
use ReflectionClass;
16
17
abstract class Migration implements MigrationInterface
18
{
19
    private ?DateTimeImmutable $executedAt;
20
21
    protected ConnectorInterface $connector;
22
23
    abstract protected function up(): void;
24
25
    abstract protected function down(): void;
26
27
    public function __construct(DateTimeImmutable $executedAt = null)
28
    {
29
        $this->executedAt = $executedAt;
30
    }
31
32
    public function __invoke(ConnectorInterface $connector, string $direction = MigrationInterface::MIGRATE_UP): void
33
    {
34
        $this->connector = $connector;
35
36
        if ($direction === MigrationInterface::MIGRATE_DOWN) {
37
            Assertion::true($this->isReversible(), 'Migration cannot be reversed.');
38
            Assertion::true($this->hasExecuted(), 'Migration has not previously been executed.');
39
            $this->down();
40
            $this->executedAt = null;
41
        } else {
42
            Assertion::false($this->hasExecuted(), 'Migration has already been executed.');
43
            $this->up();
44
            $this->executedAt = new DateTimeImmutable;
45
        }
46
    }
47
48
    public function getName(): string
49
    {
50
        $shortName = (new ReflectionClass(static::class))->getShortName();
51
        if (!preg_match('/^(?<name>.+?)\d+$/', $shortName, $matches)) {
52
            throw new RuntimeException('Unexpected migration name in '.$shortName);
53
        }
54
        return $matches['name'];
55
    }
56
57
    public function getVersion(): int
58
    {
59
        $shortName= (new ReflectionClass(static::class))->getShortName();
60
        if (!preg_match('/(?<version>\d{14})$/', $shortName, $matches)) {
61
            throw new RuntimeException('Unexpected migration version in '.$shortName);
62
        }
63
        return intval($matches['version']);
64
    }
65
66
    public function hasExecuted(): bool
67
    {
68
        return $this->executedAt instanceof DateTimeImmutable;
69
    }
70
71
    public function toNative(): array
72
    {
73
        $state = [
74
            '@type' => static::class,
75
            'name' => $this->getName(),
76
            'version' => $this->getVersion(),
77
            'description' => $this->getDescription()
78
        ];
79
80
        if ($this->hasExecuted()) {
81
            $state['executedAt']  = $this->executedAt->format('c');
82
        }
83
84
        return $state;
85
    }
86
}
87