Atomizer::revertChanges()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Migrations\Atomizer;
6
7
use Cycle\Database\Schema\AbstractTable;
8
use Cycle\Database\Schema\Reflector;
9
use Spiral\Reactor\Partial\Source;
10
11
/**
12
 * Atomizer provides ability to convert given AbstractTables and their changes into set of
13
 * migration commands.
14
 */
15
final class Atomizer
16
{
17
    /** @var AbstractTable[] */
18
    protected array $tables = [];
19
20 144
    public function __construct(private RendererInterface $renderer)
21
    {
22
    }
23
24
    /**
25
     * Add new table into atomizer.
26
     */
27 144
    public function addTable(AbstractTable $table): self
28
    {
29 144
        $this->tables[] = $table;
30
31 144
        return $this;
32
    }
33
34
    /**
35
     * Get all atomizer tables.
36
     *
37
     * @return AbstractTable[]
38
     */
39 144
    public function getTables(): array
40
    {
41 144
        return $this->tables;
42
    }
43
44
    /**
45
     * Generate set of commands needed to describe migration (up command).
46
     */
47 144
    public function declareChanges(Source $source): void
48
    {
49 144
        foreach ($this->sortedTables() as $table) {
50 144
            if (!$table->getComparator()->hasChanges()) {
51 24
                continue;
52
            }
53
54
            //New operations block
55 144
            $this->declareBlock($source);
56
57 144
            if (!$table->exists()) {
58 144
                $this->renderer->createTable($source, $table);
59
            } else {
60 104
                $this->renderer->updateTable($source, $table);
61
            }
62
        }
63
    }
64
65
    /**
66
     * Generate set of lines needed to rollback migration (down command).
67
     */
68 144
    public function revertChanges(Source $source): void
69
    {
70 144
        foreach ($this->sortedTables(true) as $table) {
71 144
            if (!$table->getComparator()->hasChanges()) {
72 24
                continue;
73
            }
74
75
            //New operations block
76 144
            $this->declareBlock($source);
77
78 144
            if (!$table->exists()) {
79 144
                $this->renderer->dropTable($source, $table);
80
            } else {
81 104
                $this->renderer->revertTable($source, $table);
82
            }
83
        }
84
    }
85
86
    /**
87
     * Tables sorted in order of their dependencies.
88
     *
89
     * @param bool $reverse
90
     *
91
     * @return AbstractTable[]
92
     */
93 144
    protected function sortedTables($reverse = false): array
94
    {
95 144
        $reflector = new Reflector();
96 144
        foreach ($this->tables as $table) {
97 144
            $reflector->addTable($table);
98
        }
99
100 144
        $sorted = $reflector->sortedTables();
101 144
        if ($reverse) {
102 144
            return array_reverse($sorted);
103
        }
104
105 144
        return $sorted;
106
    }
107
108
    /**
109
     * Add spacing between commands, only if required.
110
     */
111 144
    private function declareBlock(Source $source): void
112
    {
113 144
        if ($source->getLines() !== []) {
114 40
            $source->addLine('');
115
        }
116
    }
117
}
118