Completed
Pull Request — master (#949)
by Grégoire
02:40
created

MigrationStatusInfosHelper   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Test Coverage

Coverage 94.68%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 99
c 1
b 0
f 0
dl 0
loc 191
ccs 89
cts 94
cp 0.9468
rs 10
wmc 28

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
B listVersions() 0 47 9
B showMigrationsInfo() 0 74 9
B getFormattedVersionAlias() 0 32 9
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
134
        $dataGroup = [
135 1
            'Storage' => [
136 1
                'Type' => $storage!== null ? get_class($storage) : null,
137
            ],
138
            'Database' => [
139 1
                'Driver' => get_class($this->connection->getDriver()),
140 1
                'Name' => $this->connection->getDatabase(),
141
            ],
142
            'Versions' => [
143 1
                'Previous' => $this->getFormattedVersionAlias('prev', $executedMigrations),
144 1
                'Current' => $this->getFormattedVersionAlias('current', $executedMigrations),
145 1
                'Next' => $this->getFormattedVersionAlias('next', $executedMigrations),
146 1
                'Latest' => $this->getFormattedVersionAlias('latest', $executedMigrations),
147
            ],
148
149
            'Migrations' => [
150 1
                'Executed' => count($executedMigrations),
151 1
                'Executed Unavailable' => count($executedUnavailableMigrations) > 0 ? ('<error>' . count($executedUnavailableMigrations) . '</error>') : '0',
152 1
                'Available' => count($availableMigrations),
153 1
                'New' => count($newMigrations) > 0 ? ('<question>' . count($newMigrations) . '</question>') : '0',
154
            ],
155 1
            'Migration Namespaces' => $this->configuration->getMigrationDirectories(),
156
157
        ];
158 1
        if ($storage instanceof TableMetadataStorageConfiguration) {
159
            $dataGroup['Storage'] += [
160 1
                'Table Name' => $storage->getTableName(),
161 1
                'Column Name' => $storage->getVersionColumnName(),
162
            ];
163
        }
164
165 1
        $first = true;
166 1
        foreach ($dataGroup as $group => $dataValues) {
167 1
            $nsRows = [];
168 1
            foreach ($dataValues as $k => $v) {
169 1
                $nsRows[] = [
170 1
                    $k,
171 1
                    $v,
172
                ];
173
            }
174
175 1
            if (count($nsRows) <= 0) {
176
                continue;
177
            }
178
179 1
            if (! $first) {
180 1
                $table->addRow([new TableSeparator(['colspan' => 3])]);
181
            }
182
183 1
            $first = false;
184 1
            array_unshift(
185 1
                $nsRows[0],
186 1
                new TableCell('<info>' . $group . '</info>', ['rowspan' => count($dataValues)])
187
            );
188 1
            $table->addRows($nsRows);
189
        }
190
191 1
        $table->render();
192 1
    }
193
194 1
    private function getFormattedVersionAlias(string $alias, ExecutedMigrationsSet $executedMigrationsSet) : string
195
    {
196
        try {
197 1
            $version = $this->aliasResolver->resolveVersionAlias($alias);
198 1
        } catch (Throwable $e) {
199 1
            $version = null;
200
        }
201
202
        // No version found
203 1
        if ($version === null) {
204 1
            if ($alias === 'next') {
205 1
                return 'Already at latest version';
206
            }
207
208 1
            if ($alias === 'prev') {
209
                return 'Already at first version';
210
            }
211
        }
212
213 1
        if ($alias === 'latest' && $version!== null && $executedMigrationsSet->hasMigration($version)) {
214
            return 'Already at latest version';
215
        }
216
217
        // Before first version "virtual" version number
218 1
        if ((string) $version === '0') {
219
            return '<comment>0</comment>';
220
        }
221
222
        // Show normal version number
223 1
        return sprintf(
224 1
            '<comment>%s </comment>',
225 1
            (string) $version
226
        );
227
    }
228
}
229