Failed Conditions
Pull Request — master (#917)
by Asmir
02:36
created

MigrationStatusInfosHelper::listVersions()   B

Complexity

Conditions 9
Paths 19

Size

Total Lines 47
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 31
c 0
b 0
f 0
nc 19
nop 2
dl 0
loc 47
ccs 30
cts 30
cp 1
crap 9
rs 8.0555
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Helper;
6
7
use DateTimeInterface;
8
use Doctrine\DBAL\Connection;
9
use Doctrine\Migrations\Configuration\Configuration;
10
use Doctrine\Migrations\Metadata\AvailableMigrationsList;
11
use Doctrine\Migrations\Metadata\ExecutedMigrationsSet;
12
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
13
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
14
use Doctrine\Migrations\MigrationRepository;
15
use Doctrine\Migrations\Version\AliasResolver;
16
use Doctrine\Migrations\Version\Version;
17
use Symfony\Component\Console\Helper\Table;
18
use Symfony\Component\Console\Helper\TableCell;
19
use Symfony\Component\Console\Helper\TableSeparator;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Throwable;
22
use function array_unshift;
23
use function count;
24
use function get_class;
25
use function sprintf;
26
27
/**
28
 * The MigrationStatusInfosHelper class is responsible for building the array of information used when displaying
29
 * the status of your migrations.
30
 *
31
 * @internal
32
 *
33
 * @see Doctrine\Migrations\Tools\Console\Command\StatusCommand
34
 */
35
class MigrationStatusInfosHelper
36
{
37
    /** @var Configuration */
38
    private $configuration;
39
40
    /** @var Connection */
41
    private $connection;
42
43
    /** @var AliasResolver */
44
    private $aliasResolver;
45
46
    /** @var MetadataStorage */
47
    private $metadataStorage;
48
49
    /** @var MigrationRepository */
50
    private $migrationRepository;
51
52 3
    public function __construct(
53
        Configuration $configuration,
54
        Connection $connection,
55
        AliasResolver $aliasResolver,
56
        MigrationRepository $migrationRepository,
57
        MetadataStorage $metadataStorage
58
    ) {
59 3
        $this->configuration       = $configuration;
60 3
        $this->connection          = $connection;
61 3
        $this->aliasResolver       = $aliasResolver;
62 3
        $this->migrationRepository = $migrationRepository;
63 3
        $this->metadataStorage     = $metadataStorage;
64 3
    }
65
66
    /**
67
     * @param Version[] $versions
68
     */
69 2
    public function listVersions(array $versions, OutputInterface $output) : void
70
    {
71 2
        $table = new Table($output);
72 2
        $table->setHeaders(
73
            [
74 2
                [new TableCell('Migration Versions', ['colspan' => 4])],
75
                ['Migration', 'Status', 'Migrated At', 'Execution Time', 'Description'],
76
            ]
77
        );
78 2
        $executedMigrations  = $this->metadataStorage->getExecutedMigrations();
79 2
        $availableMigrations = $this->migrationRepository->getMigrations();
80
81 2
        foreach ($versions as $version) {
82 2
            $description   = null;
83 2
            $executedAt    = null;
84 2
            $executionTime = null;
85
86 2
            if ($executedMigrations->hasMigration($version)) {
87 2
                $executedMigration = $executedMigrations->getMigration($version);
88 2
                $executionTime     = $executedMigration->getExecutionTime();
89 2
                $executedAt        = $executedMigration->getExecutedAt() instanceof DateTimeInterface
90 2
                    ? $executedMigration->getExecutedAt()->format('Y-m-d H:i:s')
91 2
                    : null;
92
            }
93
94 2
            if ($availableMigrations->hasMigration($version)) {
95 2
                $description = $availableMigrations->getMigration($version)->getMigration()->getDescription();
96
            }
97
98 2
            if ($executedMigrations->hasMigration($version) && $availableMigrations->hasMigration($version)) {
99 1
                $status = '<info>migrated</info>';
100 2
            } elseif ($executedMigrations->hasMigration($version)) {
101 2
                $status = '<error>migrated, not available</error>';
102
            } else {
103 2
                $status = '<comment>not migrated</comment>';
104
            }
105
106 2
            $table->addRow([
107 2
                (string) $version,
108 2
                $status,
109 2
                (string) $executedAt,
110 2
                $executionTime !== null ? $executionTime . 's': '',
111 2
                $description,
112
            ]);
113
        }
114
115 2
        $table->render();
116 2
    }
117
118 1
    public function showMigrationsInfo(
119
        OutputInterface $output,
120
        AvailableMigrationsList $availableMigrations,
121
        ExecutedMigrationsSet $executedMigrations,
122
        AvailableMigrationsList $newMigrations,
123
        ExecutedMigrationsSet $executedUnavailableMigrations
124
    ) : void {
125 1
        $storage = $this->configuration->getMetadataStorageConfiguration();
126
127 1
        $table = new Table($output);
128 1
        $table->setHeaders(
129
            [
130 1
                [new TableCell('Configuration', ['colspan' => 3])],
131
            ]
132
        );
133
        $data = [
134 1
            'Project' => $this->configuration->getName() ?? 'Doctrine Database Migrations',
135
        ];
136 1
        foreach ($data as $k => $v) {
137 1
            $table->addRow([
138 1
                '<info>' . $k . '</info>',
139 1
                new TableCell($v, ['colspan' => 2]),
140
            ]);
141
        }
142
143
        $dataGroup = [
144 1
            'Storage' => [
145 1
                'Type' => $storage!== null ? get_class($storage) : null,
146
            ],
147
            'Database' => [
148 1
                'Driver' => $this->connection->getDriver()->getName(),
149 1
                'Host' => $this->connection->getHost(),
150 1
                'Name' => $this->connection->getDatabase(),
151
            ],
152
            'Versions' => [
153 1
                'Previous' => $this->getFormattedVersionAlias('prev', $executedMigrations),
154 1
                'Current' => $this->getFormattedVersionAlias('current', $executedMigrations),
155 1
                'Next' => $this->getFormattedVersionAlias('next', $executedMigrations),
156 1
                'Latest' => $this->getFormattedVersionAlias('latest', $executedMigrations),
157
            ],
158
159
            'Migrations' => [
160 1
                'Executed' => count($executedMigrations),
161 1
                'Executed Unavailable' => count($executedUnavailableMigrations) > 0 ? ('<error>' . count($executedUnavailableMigrations) . '</error>') : '0',
162 1
                'Available' => count($availableMigrations),
163 1
                'New' => count($newMigrations) > 0 ? ('<question>' . count($newMigrations) . '</question>') : '0',
164
            ],
165 1
            'Migration Namespaces' => $this->configuration->getMigrationDirectories(),
166
167
        ];
168 1
        if ($storage instanceof TableMetadataStorageConfiguration) {
169
            $dataGroup['Storage'] += [
170 1
                'Table Name' => $storage->getTableName(),
171 1
                'Column Name' => $storage->getVersionColumnName(),
172
            ];
173 1
            $table->addRow([new TableSeparator(['colspan' => 3])]);
174 1
            foreach ($data as $k => $v) {
175 1
                $table->addRow([
176 1
                    '<info>' . $k . '</info>',
177 1
                    new TableCell($v, ['colspan' => 2]),
178
                ]);
179
            }
180
        }
181
182 1
        foreach ($dataGroup as $group => $dataValues) {
183 1
            $nsRows = [];
184 1
            foreach ($dataValues as $k => $v) {
185 1
                $nsRows[] = [
186 1
                    $k,
187 1
                    $v,
188
                ];
189
            }
190
191 1
            if (count($nsRows) <= 0) {
192
                continue;
193
            }
194
195 1
            $table->addRow([new TableSeparator(['colspan' => 3])]);
196 1
            array_unshift(
197 1
                $nsRows[0],
198 1
                new TableCell('<info>' . $group . '</info>', ['rowspan' => count($dataValues)])
199
            );
200 1
            $table->addRows($nsRows);
201
        }
202
203 1
        $table->render();
204 1
    }
205
206 1
    private function getFormattedVersionAlias(string $alias, ExecutedMigrationsSet $executedMigrationsSet) : string
207
    {
208
        try {
209 1
            $version = $this->aliasResolver->resolveVersionAlias($alias);
210 1
        } catch (Throwable $e) {
211 1
            $version = null;
212
        }
213
214
        // No version found
215 1
        if ($version === null) {
216 1
            if ($alias === 'next') {
217 1
                return 'Already at latest version';
218
            }
219
220 1
            if ($alias === 'prev') {
221
                return 'Already at first version';
222
            }
223
        }
224
225 1
        if ($alias === 'latest' && $version!== null && $executedMigrationsSet->hasMigration($version)) {
226
            return 'Already at latest version';
227
        }
228
229
        // Before first version "virtual" version number
230 1
        if ((string) $version === '0') {
231
            return '<comment>0</comment>';
232
        }
233
234
        // Show normal version number
235 1
        return sprintf(
236 1
            '<comment>%s </comment>',
237 1
            (string) $version
238
        );
239
    }
240
}
241