Completed
Push — master ( b6018a...af2f64 )
by Andreas
03:13
created

schema   C

Complexity

Total Complexity 28

Size/Duplication

Total Lines 146
Duplicated Lines 10.96 %

Coupling/Cohesion

Components 1
Dependencies 19

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 16
loc 146
rs 6.875
wmc 28
lcom 1
cbo 19

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 7 1
D execute() 0 75 16
A generate_proxyfiles() 14 14 3
C process_updates() 1 44 8

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
6
 */
7
8
namespace midgard\portable\command;
9
10
use midgard\portable\storage\connection;
11
use midgard\portable\classgenerator;
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputArgument;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Helper\ProgressBar;
17
use Symfony\Component\Console\Question\Question;
18
use midgard_storage;
19
use midgard_connection;
20
use Doctrine\ORM\Tools\SchemaTool;
21
use Doctrine\DBAL\Schema\Comparator;
22
use Symfony\Component\Console\Input\InputOption;
23
use Doctrine\Common\Proxy\ProxyGenerator;
24
25
/**
26
 * (Re)generate mapping information from MgdSchema XMLs
27
 */
28
class schema extends Command
29
{
30
    protected function configure()
31
    {
32
        $this->setName('schema')
33
            ->setDescription('(Re)generate mapping information from MgdSchema XMLs')
34
            ->addArgument('config', InputArgument::OPTIONAL, 'Full path to midgard-portable config file')
35
            ->addOption('force', null, InputOption::VALUE_NONE, 'Ignore errors from DB');
36
    }
37
38
    protected function execute(InputInterface $input, OutputInterface $output)
39
    {
40
        $path = $input->getArgument('config');
41
        if (empty($path)) {
42
            if (file_exists(OPENPSA_PROJECT_BASEDIR . 'config/midgard-portable.inc.php')) {
43
                $path = OPENPSA_PROJECT_BASEDIR . 'config/midgard-portable.inc.php';
44
            } else {
45
                $dialog = $this->getHelper('question');
46
                $path = $dialog->ask($input, $output, new Question('<question>Enter path to config file</question>'));
47
            }
48
        }
49
        if (!file_exists($path)) {
50
            throw new \RuntimeException('Config file ' . $path . ' not found');
51
        }
52
        //we have to delay startup so that we can delete the entity class file before it gets included
53
        connection::set_autostart(false);
54
        require $path;
55
56
        $mgd_config = midgard_connection::get_instance()->config;
57
        $mgdschema_file = $mgd_config->vardir . '/mgdschema_classes.php';
58
        if (   file_exists($mgdschema_file)
59
            && !unlink($mgdschema_file)) {
60
            throw new \RuntimeException('Could not unlink ' . $mgdschema_file);
61
        }
62
        if (connection::get_parameter('dev_mode') !== true) {
63
            $driver = connection::get_parameter('driver');
64
            $classgenerator = new classgenerator($driver->get_manager(), $mgdschema_file);
65
            $classgenerator->write($driver->get_namespace());
66
        }
67
        if (!file_exists($mgd_config->blobdir . '/0/0')) {
68
            $mgd_config->create_blobdir();
69
        }
70
        connection::startup();
71
        $em = connection::get_em();
72
        connection::invalidate_cache();
73
        $cms = $em->getMetadataFactory()->getAllMetadata();
74
75
        // create storage
76
        if (    !midgard_storage::create_base_storage()
77
             && midgard_connection::get_instance()->get_error_string() != 'MGD_ERR_OK') {
78
            throw new \Exception("Failed to create base database structures" . midgard_connection::get_instance()->get_error_string());
79
        }
80
        $force = $input->getOption('force');
81
        $to_update = array();
82
        $to_create = array();
83
84
        foreach ($cms as $cm) {
85
            if (!$em->getConnection()->getSchemaManager()->tablesExist(array($cm->getTableName()))) {
86
                $to_create[] = $cm;
87
            } else {
88
                $to_update[] = $cm;
89
            }
90
        }
91
92
        if (!empty($to_create)) {
93
            $output->writeln('Creating <info>' . count($to_create) . '</info> new tables');
94
            $tool = new SchemaTool($em);
95
            try {
96
                $tool->createSchema($to_create);
97
            } catch (\Exception $e) {
98
                if (!$force) {
99
                    throw $e;
100
                } else {
101
                    $output->writeln('<error>' . $e->getMessage() . '</error>');
102
                }
103
            }
104
        }
105
        if (!empty($to_update)) {
106
            $this->process_updates($to_update, $output, $force);
107
        }
108
        $output->writeln('Generating proxies');
109
        $this->generate_proxyfiles($cms);
110
111
        $output->writeln('Done');
112
    }
113
114 View Code Duplication
    private function generate_proxyfiles(array $cms)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
    {
116
        $em = connection::get_em();
117
        $generator = new ProxyGenerator($em->getConfiguration()->getProxyDir(), $em->getConfiguration()->getProxyNamespace());
118
        $generator->setPlaceholder('baseProxyInterface', 'Doctrine\ORM\Proxy\Proxy');
119
120
        foreach ($cms as $cm) {
121
            $filename = $generator->getProxyFileName($cm->getName());
122
            if (file_exists($filename)) {
123
                unlink($filename);
124
            }
125
            $generator->generateProxyClass($cm, $filename);
126
        }
127
    }
128
129
    private function process_updates(array $to_update, OutputInterface $output, $force)
130
    {
131
        $em = connection::get_em();
132
        $conn = $em->getConnection();
133
        $tool = new SchemaTool($em);
134
        $from = $conn->getSchemaManager()->createSchema();
135
        $to = $tool->getSchemaFromMetadata($to_update);
136
137
        $comparator = new Comparator;
138
        $diff = $comparator->compare($from, $to);
139
        foreach ($diff->changedTables as $changed_table) {
140
            if (!empty($changed_table->removedColumns)) {
141
                $changed_table->removedColumns = array();
142
            }
143
        }
144
        $sql = $diff->toSaveSql($conn->getDatabasePlatform());
145
146
        if (count($sql) == 0) {
147
            return;
148
        }
149
150
        $output->writeln('Executing <info>' . count($sql) . '</info> updates');
151
        $progress = new ProgressBar($output);
152
        $progress->start(count($sql));
153
154
        foreach ($sql as $sql_line) {
155
            if ($output->getVerbosity() == OutputInterface::VERBOSITY_VERBOSE) {
156
                $output->writeln(' Executing <info>' . $sql_line . '</info>');
157
            }
158
            try {
159
                $conn->executeQuery($sql_line);
160
            } catch (\Exception $e) {
161
                if (!$force) {
162
                    throw $e;
163
                } else {
164
                    $output->writeln('<error>' . $e->getMessage() . '</error>');
165
                }
166
            }
167
168
            $progress->advance();
169
        }
170
        $progress->finish();
171
        $output->writeln('');
172
    }
173
}
174