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

Migration   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 68
ccs 0
cts 50
cp 0
rs 10
c 0
b 0
f 0
wmc 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 7 2
A getVersion() 0 7 2
A __invoke() 0 13 2
A hasExecuted() 0 3 1
A __construct() 0 3 1
A toNative() 0 14 2
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