Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
37 / 37
69.70% covered (warning)
69.70%
23 / 33
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Runner
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
37 / 37
69.70% covered (warning)
69.70%
23 / 33
100.00% covered (success)
100.00%
4 / 4
31.13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 run
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
17 / 17
50.00% covered (danger)
50.00%
8 / 16
100.00% covered (success)
100.00%
1 / 1
19.12
 finish
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
16 / 16
85.71% covered (warning)
85.71%
12 / 14
100.00% covered (success)
100.00%
1 / 1
8.19
 begin
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Quma\Migrations;
6
7use Celema\Console\Io;
8use Celema\Quma\Database;
9use Celema\Quma\Environment;
10
11final readonly class Runner
12{
13    // Internal wiring, constructed by the Migrations command only.
14    // @mago-expect lint:excessive-parameter-list
15    public function __construct(
16        private Environment $env,
17        private DriverPolicy $driverPolicy,
18        private Planner $planner,
19        private Log $log,
20        private Executor $executor,
21        private Io $io,
22    ) {}
23
24    /** @param list<string> $migrations */
25    public function run(string $namespace, array $migrations, RunOptions $options): int
26    {
27        $db = $this->env->db;
28
29        $this->begin($db);
30
31        if (!$options->tableExists) {
32            $result = ($options->createMigrationsTable)();
33
34            if ($result !== 0) {
35                if ($this->driverPolicy->supportsTransactions()) {
36                    $db->rollback();
37                }
38
39                return $result;
40            }
41        }
42
43        $appliedMigrations = $this->log->applied($db);
44        $result = Executor::STARTED;
45        $numApplied = 0;
46
47        foreach ($migrations as $migration) {
48            $migrationId = $this->planner->migrationId($namespace, $migration);
49
50            if (in_array($migrationId, $appliedMigrations, strict: true)) {
51                continue;
52            }
53
54            if (!$this->driverPolicy->supportsMigration($migration)) {
55                continue;
56            }
57
58            $result = $this->executor->migrate($namespace, $migration, $options->showStacktrace);
59
60            if ($result === Executor::ERROR) {
61                break;
62            }
63
64            if ($result === Executor::SUCCESS) {
65                $numApplied++;
66            }
67        }
68
69        return $this->finish($db, $result, $options->apply, $numApplied);
70    }
71
72    public function finish(
73        Database $db,
74        string $result,
75        bool $apply,
76        int $numApplied,
77    ): int {
78        $io = $this->io;
79        $plural = $numApplied > 1 ? 's' : '';
80
81        if ($this->driverPolicy->supportsTransactions()) {
82            if ($result === Executor::ERROR) {
83                $db->rollback();
84                $io->error("\nDue to errors no migrations applied");
85
86                return 1;
87            }
88
89            if ($numApplied === 0) {
90                $db->rollback();
91                $io->line("\nNo migrations applied");
92
93                return 0;
94            }
95
96            if ($apply) {
97                $db->commit();
98                $io->line("\n{$numApplied} migration{$plural} successfully applied");
99
100                return 0;
101            }
102            $io->line("\n<bright-red>Notice</bright-red>: Test run only");
103            $io->write("Rolled back {$numApplied} migration{$plural}. ");
104            $io->line('Use --apply to commit them');
105            $db->rollback();
106
107            return 0;
108        }
109
110        if ($result === Executor::ERROR) {
111            $io->error("\n{$numApplied} migration{$plural} applied until the error occured");
112
113            return 1;
114        }
115
116        if ($numApplied > 0) {
117            $io->line("\n{$numApplied} migration{$plural} successfully applied");
118
119            return 0;
120        }
121
122        $io->line("\nNo migrations applied");
123
124        return 0;
125    }
126
127    private function begin(Database $db): void
128    {
129        if ($this->driverPolicy->supportsTransactions()) {
130            $db->begin();
131        }
132    }
133}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

Runner->__construct
16        private Environment $env,
17        private DriverPolicy $driverPolicy,
18        private Planner $planner,
19        private Log $log,
20        private Executor $executor,
21        private Io $io,
22    ) {}
Runner->begin
127    private function begin(Database $db): void
128    {
129        if ($this->driverPolicy->supportsTransactions()) {
130            $db->begin();
131        }
132    }
132    }
Runner->finish
73        Database $db,
74        string $result,
75        bool $apply,
76        int $numApplied,
77    ): int {
78        $io = $this->io;
79        $plural = $numApplied > 1 ? 's' : '';
79        $plural = $numApplied > 1 ? 's' : '';
79        $plural = $numApplied > 1 ? 's' : '';
79        $plural = $numApplied > 1 ? 's' : '';
80
81        if ($this->driverPolicy->supportsTransactions()) {
82            if ($result === Executor::ERROR) {
83                $db->rollback();
84                $io->error("\nDue to errors no migrations applied");
85
86                return 1;
89            if ($numApplied === 0) {
90                $db->rollback();
91                $io->line("\nNo migrations applied");
92
93                return 0;
96            if ($apply) {
97                $db->commit();
98                $io->line("\n{$numApplied} migration{$plural} successfully applied");
99
100                return 0;
102            $io->line("\n<bright-red>Notice</bright-red>: Test run only");
103            $io->write("Rolled back {$numApplied} migration{$plural}. ");
104            $io->line('Use --apply to commit them');
105            $db->rollback();
106
107            return 0;
110        if ($result === Executor::ERROR) {
111            $io->error("\n{$numApplied} migration{$plural} applied until the error occured");
112
113            return 1;
116        if ($numApplied > 0) {
117            $io->line("\n{$numApplied} migration{$plural} successfully applied");
118
119            return 0;
122        $io->line("\nNo migrations applied");
123
124        return 0;
125    }
Runner->run
25    public function run(string $namespace, array $migrations, RunOptions $options): int
26    {
27        $db = $this->env->db;
28
29        $this->begin($db);
30
31        if (!$options->tableExists) {
32            $result = ($options->createMigrationsTable)();
33
34            if ($result !== 0) {
35                if ($this->driverPolicy->supportsTransactions()) {
36                    $db->rollback();
37                }
38
39                return $result;
39                return $result;
43        $appliedMigrations = $this->log->applied($db);
44        $result = Executor::STARTED;
45        $numApplied = 0;
46
47        foreach ($migrations as $migration) {
47        foreach ($migrations as $migration) {
48            $migrationId = $this->planner->migrationId($namespace, $migration);
49
50            if (in_array($migrationId, $appliedMigrations, strict: true)) {
51                continue;
54            if (!$this->driverPolicy->supportsMigration($migration)) {
55                continue;
58            $result = $this->executor->migrate($namespace, $migration, $options->showStacktrace);
59
60            if ($result === Executor::ERROR) {
61                break;
64            if ($result === Executor::SUCCESS) {
47        foreach ($migrations as $migration) {
48            $migrationId = $this->planner->migrationId($namespace, $migration);
49
50            if (in_array($migrationId, $appliedMigrations, strict: true)) {
51                continue;
52            }
53
54            if (!$this->driverPolicy->supportsMigration($migration)) {
55                continue;
56            }
57
58            $result = $this->executor->migrate($namespace, $migration, $options->showStacktrace);
59
60            if ($result === Executor::ERROR) {
61                break;
62            }
63
64            if ($result === Executor::SUCCESS) {
65                $numApplied++;
47        foreach ($migrations as $migration) {
47        foreach ($migrations as $migration) {
48            $migrationId = $this->planner->migrationId($namespace, $migration);
49
50            if (in_array($migrationId, $appliedMigrations, strict: true)) {
51                continue;
52            }
53
54            if (!$this->driverPolicy->supportsMigration($migration)) {
55                continue;
56            }
57
58            $result = $this->executor->migrate($namespace, $migration, $options->showStacktrace);
59
60            if ($result === Executor::ERROR) {
61                break;
62            }
63
64            if ($result === Executor::SUCCESS) {
65                $numApplied++;
66            }
67        }
68
69        return $this->finish($db, $result, $options->apply, $numApplied);
70    }