Passed
Pull Request — master (#93)
by Damien
02:57
created

UpdateSchemaCommand   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 57
c 2
b 1
f 0
dl 0
loc 121
rs 10
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A unlock() 0 3 1
A setContainer() 0 3 1
A configure() 0 7 1
C execute() 0 93 12
1
<?php
2
3
namespace DH\DoctrineAuditBundle\Command;
4
5
use DH\DoctrineAuditBundle\Helper\UpdateHelper;
6
use DH\DoctrineAuditBundle\Manager\AuditManager;
7
use DH\DoctrineAuditBundle\Reader\AuditReader;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Command\LockableTrait;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Style\SymfonyStyle;
14
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
17
class UpdateSchemaCommand extends Command implements ContainerAwareInterface
18
{
19
    use LockableTrait;
20
21
    private $container;
22
23
    protected static $defaultName = 'audit:schema:update';
24
25
    protected function configure()
26
    {
27
        $this
28
            ->setDescription('Update audit tables structure')
29
            ->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Dumps the generated SQL statements to the screen (does not execute them).')
30
            ->addOption('force', 'f', InputOption::VALUE_NONE, 'Causes the generated SQL statements to be physically executed against your database.')
31
            ->setName(self::$defaultName)
32
        ;
33
    }
34
35
    protected function execute(InputInterface $input, OutputInterface $output)
36
    {
37
        if (!$this->lock()) {
38
            $output->writeln('The command is already running in another process.');
39
40
            return 0;
41
        }
42
43
        $io = new SymfonyStyle($input, $output);
44
45
        $dumpSql = true === $input->getOption('dump-sql');
46
        $force = true === $input->getOption('force');
47
48
        /**
49
         * @var AuditManager
50
         */
51
        $manager = $this->container->get('dh_doctrine_audit.manager');
52
53
        /**
54
         * @var AuditReader
55
         */
56
        $reader = $this->container->get('dh_doctrine_audit.reader');
57
58
        /**
59
         * @var UpdateHelper
60
         */
61
        $updater = new UpdateHelper($manager, $reader);
62
63
        $auditEntityManager = $manager->getConfiguration()->getEntityManager();
64
65
        $sqls = $updater->getUpdateAuditSchemaSql();
66
67
        if (empty($sqls)) {
68
            $io->success('Nothing to update.');
69
70
            $this->release();
71
72
            return 0;
73
        }
74
75
        if ($dumpSql) {
76
            $io->text('The following SQL statements will be executed:');
77
            $io->newLine();
78
79
            foreach ($sqls as $sql) {
80
                $io->text(sprintf('    %s;', $sql));
81
            }
82
        }
83
84
        if ($force) {
85
            if ($dumpSql) {
86
                $io->newLine();
87
            }
88
            $io->text('Updating database schema...');
89
            $io->newLine();
90
91
            foreach ($sqls as $sql) {
92
                try {
93
                    $statement = $auditEntityManager->getConnection()->prepare($sql);
94
                    $statement->execute();
95
                } catch (\Exception $e) {
96
                    // something bad happened here :/
97
                }
98
            }
99
100
            $pluralization = (1 === \count($sqls)) ? 'query was' : 'queries were';
101
102
            $io->text(sprintf('    <info>%s</info> %s executed', \count($sqls), $pluralization));
103
            $io->success('Database schema updated successfully!');
104
        }
105
106
        if ($dumpSql || $force) {
107
            $this->release();
108
109
            return 0;
110
        }
111
112
        $io->caution('This operation should not be executed in a production environment!');
113
114
        $io->text(
115
            [
116
                sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', \count($sqls)),
117
                '',
118
                'Please run the operation by passing one - or both - of the following options:',
119
                '',
120
                sprintf('    <info>%s --force</info> to execute the command', $this->getName()),
121
                sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()),
122
            ]
123
        );
124
125
        $this->release();
126
127
        return 1;
128
    }
129
130
    public function setContainer(ContainerInterface $container = null): void
131
    {
132
        $this->container = $container;
133
    }
134
135
    public function unlock()
136
    {
137
        $this->release();
138
    }
139
}
140