Passed
Push — master ( b398b7...1e9029 )
by Alexander
05:58
created

Migrator::getSignature()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
4
namespace Quantick\DeployMigration\Lib\Service;
5
6
use Carbon\Carbon;
7
use Illuminate\Console\OutputStyle;
8
use Illuminate\Container\Container;
9
use Illuminate\Database\Connection;
10
use Illuminate\Support\Collection;
11
use Illuminate\Support\Facades\Artisan;
12
13
class Migrator
14
{
15
    /**
16
     * @var Connection
17
     */
18
    private $connection;
19
    /**
20
     * @var Container
21
     */
22
    private $container;
23
24
25
    /**
26
     * Migrator constructor.
27
     * @param Connection $connection
28
     * @param Container $container
29
     */
30
    public function __construct(
31
        Connection $connection,
32
        Container $container
33
    )
34
    {
35
        $this->connection = $connection;
36
        $this->container = $container;
37
    }
38
39
    /**
40
     * @param Collection $migrations
41
     * @param OutputStyle $deployCommandOutput
42
     * @throws \Throwable
43
     */
44
    public function run(Collection $migrations, OutputStyle $deployCommandOutput)
45
    {
46
        foreach ($migrations as $migration) {
47
            $outputs = [];
48
            $currentMigration = $migration;
49
            $currentCommand = null;
50
51
            try {
52
                $this->connection->beginTransaction();
53
54
                $tableQuery = $this->getTableQuery();
55
56
                $alreadyExecuted = $tableQuery->where('migration', '=', get_class($migration))->count() > 0;
57
58
                if ($alreadyExecuted === true) {
59
                    continue;
60
                }
61
62
                $commands = $migration->getCommands();
63
64
                foreach ($commands as $commandName => $arguments) {
65
                    $currentCommand = $commandName;
66
67
                    $signature = $this->getSignature($commandName);
68
69
                    Artisan::call($signature, $arguments);
70
                    $output = Artisan::output();
71
72
                    $outputs[$commandName] = $output;
73
                }
74
75
                $deployCommandOutput->progressAdvance();
76
77
                $tableQuery->insert([
78
                    'migration' => get_class($migration),
79
                    'created_at' => Carbon::now()
80
81
                ]);
82
83
                $this->getInfoTableQuery()->insert([
84
                    'migration' => get_class($migration),
85
                    'output' => json_encode($outputs),
86
                    'created_at' => Carbon::now()
87
                ]);
88
89
                $this->connection->commit();
90
            } catch (\Throwable $e) {
91
                $migrationClass = $currentMigration !== null ? get_class($currentMigration) : null;
92
                $commandClass = $currentCommand;
93
94
                $deployCommandOutput->writeln('');
95
                $deployCommandOutput->writeln(sprintf('<error>Error during %s migration; %s command</error>', $migrationClass, $commandClass));
96
                $deployCommandOutput->writeln(sprintf('<error>%s</error>', (string)$e));
97
                $this->connection->rollBack();
98
99
                $this->getInfoTableQuery()->insert([
100
                    'migration' => $migrationClass,
101
                    'output' => json_encode($outputs),
102
                    'error' => json_encode([
103
                        'trace' => $e->getTraceAsString(),
104
                        'message' => $e->getMessage(),
105
                        'code' => $e->getCode(),
106
                        'file' => $e->getFile(),
107
                        'line' => $e->getLine(),
108
                        'error_command' => $commandClass
109
                    ]),
110
                    'created_at' => Carbon::now()
111
                ]);
112
113
                throw $e;
114
            }
115
116
        }
117
    }
118
119
    /**
120
     * @param string $className
121
     * @return string|null
122
     * @throws \ReflectionException
123
     */
124
    private function getSignature(string $className): ?string
125
    {
126
        $migrationReflection = new \ReflectionClass($className);
127
        $properties = $migrationReflection->getDefaultProperties();
128
        $signature = $properties['signature'] ?? $properties['name'] ?? null;
129
130
        return $signature;
131
    }
132
133
    /**
134
     * @return \Illuminate\Database\Query\Builder
135
     */
136
    private function getTableQuery(): \Illuminate\Database\Query\Builder
137
    {
138
        return $this->connection->table('deploy_migrations');
139
    }
140
141
142
    /**
143
     * @return \Illuminate\Database\Query\Builder
144
     */
145
    private function getInfoTableQuery(): \Illuminate\Database\Query\Builder
146
    {
147
        return $this->connection->table('deploy_migrations_info');
148
    }
149
}