SchemaUpdateCommand   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 5
dl 0
loc 137
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 28 4
A update() 0 10 4
A getStatements() 0 12 1
A dump() 0 10 2
A force() 0 10 2
A dumpAndForce() 0 13 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Model\Doctrine\DBAL\Command;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\Schema\Schema;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
final class SchemaUpdateCommand
13
{
14
    /**
15
     * @var Connection
16
     */
17
    private $connection;
18
19
    /**
20
     * @var
21
     */
22
    private $schemaPath;
23
24
    /**
25
     * @param Connection $connection
26
     * @param string     $schemaPath
27
     */
28 5
    public function __construct(Connection $connection, string $schemaPath)
29
    {
30 5
        $this->connection = $connection;
31 5
        $this->schemaPath = $schemaPath;
32 5
    }
33
34
    /**
35
     * @param InputInterface  $input
36
     * @param OutputInterface $output
37
     *
38
     * @return int|null
39
     */
40 5
    public function __invoke(InputInterface $input, OutputInterface $output)
41
    {
42 5
        $dump = true === $input->getOption('dump');
43 5
        $force = true === $input->getOption('force');
44
45 5
        if ([] === $statements = $this->getStatements()) {
46 1
            $output->writeln('<info>No schema changes required</info>');
47
48 1
            return;
49
        }
50
51 4
        if (!$dump && !$force) {
52 1
            $output->writeln('<comment>ATTENTION</comment>: Do not execute in production.');
53 1
            $output->writeln('    Use the incremental update to detect changes during development and use');
54 1
            $output->writeln('    the SQL provided to manually update your database in production.');
55 1
            $output->writeln('');
56 1
            $output->writeln(sprintf('Would execute <info>"%s"</info> queries.', count($statements)));
57 1
            $output->writeln('Please run the operation by passing one - or both - of the following options:');
58 1
            $output->writeln('    <info>--force</info> to execute the command');
59 1
            $output->writeln('    <info>--dump</info> to dump the SQL statements to the screen');
60
61 1
            return 1;
62
        }
63
64 3
        $this->update($output, $statements, $dump, $force);
65
66 3
        return 0;
67
    }
68
69
    /**
70
     * @param OutputInterface $output
71
     * @param array           $statements
72
     * @param bool            $dump
73
     * @param bool            $force
74
     */
75 3
    private function update(OutputInterface $output, array $statements, bool $dump, bool $force)
76
    {
77 3
        if ($dump && $force) {
78 1
            $this->dumpAndForce($output, $statements);
79 2
        } elseif ($dump) {
80 1
            $this->dump($output, $statements);
81
        } else {
82 1
            $this->force($statements);
83
        }
84 3
    }
85
86
    /**
87
     * @return array
88
     */
89 5
    private function getStatements(): array
90
    {
91 5
        $connection = $this->connection;
92
93 5
        $schemaManager = $connection->getSchemaManager();
94 5
        $fromSchema = $schemaManager->createSchema();
95
96
        /** @var Schema $schema */
97 5
        $schema = require $this->schemaPath;
98
99 5
        return $fromSchema->getMigrateToSql($schema, $connection->getDatabasePlatform());
100
    }
101
102
    /**
103
     * @param OutputInterface $output
104
     * @param array           $statements
105
     */
106 1
    private function dump(OutputInterface $output, array $statements)
107
    {
108 1
        $output->writeln('<info>Begin transaction</info>');
109
110 1
        foreach ($statements as $statement) {
111 1
            $output->writeln($statement);
112
        }
113
114 1
        $output->writeln('<info>Commit</info>');
115 1
    }
116
117
    /**
118
     * @param array $statements
119
     */
120 1
    private function force(array $statements)
121
    {
122 1
        $this->connection->beginTransaction();
123
124 1
        foreach ($statements as $statement) {
125 1
            $this->connection->exec($statement);
126
        }
127
128 1
        $this->connection->commit();
129 1
    }
130
131
    /**
132
     * @param OutputInterface $output
133
     * @param array           $statements
134
     */
135 1
    private function dumpAndForce(OutputInterface $output, array $statements)
136
    {
137 1
        $output->writeln('<info>Begin transaction</info>');
138 1
        $this->connection->beginTransaction();
139
140 1
        foreach ($statements as $statement) {
141 1
            $output->writeln($statement);
142 1
            $this->connection->exec($statement);
143
        }
144
145 1
        $output->writeln('<info>Commit</info>');
146 1
        $this->connection->commit();
147 1
    }
148
}
149