DbalMigrator::endMigrations()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 9
cts 9
cp 1
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\Migrations\Metadata\MigrationPlanList;
9
use Doctrine\Migrations\Query\Query;
10
use Doctrine\Migrations\Tools\BytesFormatter;
11
use Doctrine\Migrations\Version\Executor;
12
use Psr\Log\LoggerInterface;
13
use Symfony\Component\Stopwatch\Stopwatch;
14
use Symfony\Component\Stopwatch\StopwatchEvent;
15
use Throwable;
16
use function count;
17
use const COUNT_RECURSIVE;
18
19
/**
20
 * The DbalMigrator class is responsible for generating and executing the SQL for a migration.
21
 *
22
 * @internal
23
 */
24
class DbalMigrator implements Migrator
25
{
26
    /** @var Stopwatch */
27
    private $stopwatch;
28
29
    /** @var LoggerInterface */
30
    private $logger;
31
32
    /** @var Executor */
33
    private $executor;
34
35
    /** @var Connection */
36
    private $connection;
37
38
    /** @var EventDispatcher */
39
    private $dispatcher;
40
41 5
    public function __construct(
42
        Connection $connection,
43
        EventDispatcher $dispatcher,
44
        Executor $executor,
45
        LoggerInterface $logger,
46
        Stopwatch $stopwatch
47
    ) {
48 5
        $this->stopwatch  = $stopwatch;
49 5
        $this->logger     = $logger;
50 5
        $this->executor   = $executor;
51 5
        $this->connection = $connection;
52 5
        $this->dispatcher = $dispatcher;
53 5
    }
54
55
    /**
56
     * @return array<string, Query[]>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
57
     */
58 4
    private function executeMigrations(
59
        MigrationPlanList $migrationsPlan,
60
        MigratorConfiguration $migratorConfiguration
61
    ) : array {
62 4
        $allOrNothing = $migratorConfiguration->isAllOrNothing();
63
64 4
        if ($allOrNothing) {
65 2
            $this->connection->beginTransaction();
66
        }
67
68
        try {
69 4
            $this->dispatcher->dispatchMigrationEvent(Events::onMigrationsMigrating, $migrationsPlan, $migratorConfiguration);
70
71 4
            $sql = $this->executePlan($migrationsPlan, $migratorConfiguration);
72
73 3
            $this->dispatcher->dispatchMigrationEvent(Events::onMigrationsMigrated, $migrationsPlan, $migratorConfiguration);
74 1
        } catch (Throwable $e) {
75 1
            if ($allOrNothing) {
76 1
                $this->connection->rollBack();
77
            }
78
79 1
            throw $e;
80
        }
81
82 3
        if ($allOrNothing) {
83 1
            $this->connection->commit();
84
        }
85
86 3
        return $sql;
87
    }
88
89
    /**
90
     * @return array<string, Query[]>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
91
     */
92 4
    private function executePlan(MigrationPlanList $migrationsPlan, MigratorConfiguration $migratorConfiguration) : array
93
    {
94 4
        $sql  = [];
95 4
        $time = 0;
96
97 4
        foreach ($migrationsPlan->getItems() as $plan) {
98 4
            $versionExecutionResult = $this->executor->execute($plan, $migratorConfiguration);
99
100
            // capture the to Schema for the migration so we have the ability to use
101
            // it as the from Schema for the next migration when we are running a dry run
102
            // $toSchema may be null in the case of skipped migrations
103 3
            if (! $versionExecutionResult->isSkipped()) {
104 3
                $migratorConfiguration->setFromSchema($versionExecutionResult->getToSchema());
105
            }
106
107 3
            $sql[(string) $plan->getVersion()] = $versionExecutionResult->getSql();
108 3
            $time                             += $versionExecutionResult->getTime();
109
        }
110
111 3
        return $sql;
112
    }
113
114
    /**
115
     * @param array<string, Query[]> $sql
116
     */
117 3
    private function endMigrations(
118
        StopwatchEvent $stopwatchEvent,
119
        MigrationPlanList $migrationsPlan,
120
        array $sql
121
    ) : void {
122 3
        $stopwatchEvent->stop();
123
124 3
        $this->logger->notice(
125 3
            'finished in {duration}ms, used {memory} memory, {migrations_count} migrations executed, {queries_count} sql queries',
126
            [
127 3
                'duration' => $stopwatchEvent->getDuration(),
128 3
                'memory' => BytesFormatter::formatBytes($stopwatchEvent->getMemory()),
129 3
                'migrations_count' => count($migrationsPlan),
130 3
                'queries_count' => count($sql, COUNT_RECURSIVE) - count($sql),
131
            ]
132
        );
133 3
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138 5
    public function migrate(MigrationPlanList $migrationsPlan, MigratorConfiguration $migratorConfiguration) : array
139
    {
140 5
        if (count($migrationsPlan) === 0) {
141 1
            $this->logger->notice('No migrations to execute.');
142
143 1
            return [];
144
        }
145
146 4
        $stopwatchEvent = $this->stopwatch->start('migrate');
147
148 4
        $sql = $this->executeMigrations($migrationsPlan, $migratorConfiguration);
149
150 3
        $this->endMigrations($stopwatchEvent, $migrationsPlan, $sql);
151
152 3
        return $sql;
153
    }
154
}
155