Completed
Pull Request — master (#15)
by Łukasz
02:05
created

ProvisionDispatcher::terminate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Tworzenieweb\SqlProvisioner\Controller;
4
5
use RuntimeException;
6
use Symfony\Component\Console\Style\SymfonyStyle;
7
use Tworzenieweb\SqlProvisioner\Check\HasSyntaxCorrectCheck;
8
use Tworzenieweb\SqlProvisioner\Database\Exception;
9
use Tworzenieweb\SqlProvisioner\Database\Executor;
10
use Tworzenieweb\SqlProvisioner\Formatter\Sql;
11
use Tworzenieweb\SqlProvisioner\Model\Candidate;
12
use Tworzenieweb\SqlProvisioner\Processor\CandidateProcessor;
13
14
/**
15
 * Class ActionDispatcher
16
 *
17
 * @package Tworzenieweb\SqlProvisioner\Controller
18
 */
19
class ProvisionDispatcher
20
{
21
    /** @var Executor */
22
    private $executor;
23
24
    /** @var CandidateProcessor */
25
    private $processor;
26
27
    /** @var HasSyntaxCorrectCheck */
28
    private $syntaxCheck;
29
30
    /** @var Sql */
31
    private $sqlFormatter;
32
33
    /** @var SymfonyStyle */
34
    private $input;
35
36
    /** @var int */
37
    private $startTimestamp;
38
39
    /** @var int */
40
    private $candidateIndexValue = 1;
41
42
43
    /**
44
     * ActionDispatcher constructor.
45
     *
46
     * @param Executor $executor
47
     * @param CandidateProcessor $processor
48
     * @param HasSyntaxCorrectCheck $check
49
     * @param Sql $sqlFormatter
50
     */
51 1
    public function __construct(
52
        Executor $executor,
53
        CandidateProcessor $processor,
54
        HasSyntaxCorrectCheck $check,
55
        Sql $sqlFormatter
56
    ) {
57 1
        $this->executor = $executor;
58 1
        $this->processor = $processor;
59 1
        $this->syntaxCheck = $check;
60 1
        $this->sqlFormatter = $sqlFormatter;
61 1
        $this->startTimestamp = time();
62 1
    }
63
64
65
66
    /**
67
     * @param SymfonyStyle $io
68
     */
69
    public function setInputOutput(SymfonyStyle $io)
70
    {
71
        $this->input = $io;
72
    }
73
74
75
76
    /**
77
     * @param Candidate[] $workingDirectoryCandidates
78
     * @param int $queuedCandidatesCount
79
     */
80
    public function deploy(array $workingDirectoryCandidates, $queuedCandidatesCount)
81
    {
82
        while (!empty($workingDirectoryCandidates)) {
83
            $candidate = array_shift($workingDirectoryCandidates);
84
85
            if ($candidate->isQueued()) {
86
                $this->executeCandidateScript($candidate, $queuedCandidatesCount);
87
            }
88
        }
89
        $this->input->writeln('<info>All candidates scripts were executed</info>');
90
        $this->finalizeAndExit();
91
    }
92
93
94
95
    /**
96
     * @param Candidate $candidate
97
     */
98
    public function validate(Candidate $candidate)
99
    {
100
        if ($this->processor->isValid($candidate)) {
101
            $candidate->markAsQueued();
102
            $candidate->setIndex($this->candidateIndexValue++);
103
        } else {
104
            $candidate->markAsIgnored($this->processor->getLastError());
105
            $lastErrorMessage = $this->processor->getLastErrorMessage();
106
107
            if (null !== $lastErrorMessage) {
108
                throw new RuntimeException($lastErrorMessage);
109
            }
110
        }
111
    }
112
113
114
    public function skipSyntaxCheck()
115
    {
116
        $this->input->warning('SQL parsing disabled. This could lead to executing invalid queries.');
117
        $this->processor->removeCheck($this->syntaxCheck);
118
    }
119
120
121
122
    /**
123
     * @param Candidate $candidate
124
     * @param int $queuedCandidatesCount
125
     */
126
    private function executeCandidateScript(Candidate $candidate, $queuedCandidatesCount)
127
    {
128
        if ($candidate->isQueued()) {
129
            $this->input->warning(
130
                sprintf(
131
                    'PROCESSING [%d/%d] %s',
132
                    $candidate->getIndex(),
133
                    $queuedCandidatesCount,
134
                    $candidate->getName()
135
                )
136
            );
137
            $this->input->text($this->sqlFormatter->format($candidate->getContent()));
138
            $action = $this->input->choice(
139
                sprintf('What action to perform for "%s"', $candidate->getName()),
140
                ['DEPLOY', 'SKIP', 'QUIT']
141
            );
142
143
            switch ($action) {
144
                case 'DEPLOY':
145
                    $this->deployCandidate($candidate);
146
                    break;
147
                case 'QUIT':
148
                    $this->finalizeAndExit();
149
                    break;
150
            }
151
        }
152
    }
153
154
155
156
    /**
157
     * @param Candidate $candidate
158
     */
159
    private function deployCandidate(Candidate $candidate)
160
    {
161
        try {
162
            $this->executor->execute($candidate);
163
            $this->processor->postValidate($candidate);
164
        } catch (Exception $databaseException) {
165
            $this->input->error($databaseException->getMessage());
166
            $this->input->writeln(
167
                sprintf(
168
                    "<bg=yellow>%s\n\r%s</>",
169
                    $databaseException->getPrevious()->getMessage(),
170
                    $candidate->getContent()
171
                )
172
            );
173
            $this->terminate();
174
        } catch (RuntimeException $runtimeException) {
175
            $this->input->error($runtimeException->getMessage());
176
            $this->terminate();
177
        }
178
    }
179
180
181
182
    public function finalizeAndExit()
183
    {
184
        $this->input->text(sprintf('Provisioning ended at %s', date('Y-m-d H:i:s')));
185
        $this->input->writeln(str_repeat('=', 120));
186
        $this->input->writeln(
187
            sprintf(
188
                '<info>Memory used: %s MB. Total Time of provisioning: %s seconds</info>',
189
                memory_get_peak_usage(true) / (pow(1024, 2)),
190
                time() - $this->startTimestamp
191
            )
192
        );
193
        die(0);
1 ignored issue
show
Coding Style Compatibility introduced by
The method finalizeAndExit() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
194
    }
195
196
197
198
    private function terminate()
199
    {
200
        $this->input->text(sprintf('Provisioning ended with error at %s', date('Y-m-d H:i:s')));
201
        die(1);
202
    }
203
}