Passed
Push — master ( a08165...57ee5a )
by Dominik
02:04
created

CreateDatabaseDoctrineCommand::execute()   F

Complexity

Conditions 15
Paths 3280

Size

Total Lines 96

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
dl 0
loc 96
ccs 0
cts 77
cp 0
rs 1.4872
c 0
b 0
f 0
cc 15
nc 3280
nop 2
crap 240

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\DoctrineDbServiceProvider\Command;
6
7
use Doctrine\Common\Persistence\ConnectionRegistry;
8
use Doctrine\DBAL\DriverManager;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
/**
15
 * @link https://github.com/doctrine/DoctrineBundle/blob/master/Command/CreateDatabaseDoctrineCommand.php
16
 */
17
class CreateDatabaseDoctrineCommand extends Command
18
{
19
    /**
20
     * @var ConnectionRegistry
21
     */
22
    private $connectionRegistry;
23
24
    /**
25
     * @param ConnectionRegistry $connectionRegistry
26
     */
27
    public function __construct(ConnectionRegistry $connectionRegistry)
28
    {
29
        parent::__construct();
30
31
        $this->connectionRegistry = $connectionRegistry;
32
    }
33
34
    protected function configure()
35
    {
36
        $this
37
            ->setName('doctrine:database:create')
38
            ->setDescription('Creates the configured database')
39
            ->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command')
40
            ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
41
            ->addOption(
42
                'if-not-exists',
43
                null,
44
                InputOption::VALUE_NONE,
45
                'Don\'t trigger an error, when the database already exists'
46
            )
47
            ->setHelp(<<<EOT
48
The <info>%command.name%</info> command creates the default connections database:
49
50
    <info>php %command.full_name%</info>
51
52
You can also optionally specify the name of a connection to create the database for:
53
54
    <info>php %command.full_name% --connection=default</info>
55
EOT
56
            );
57
    }
58
59
    /**
60
     * @param InputInterface  $input
61
     * @param OutputInterface $output
62
     *
63
     * @return int
64
     */
65
    protected function execute(InputInterface $input, OutputInterface $output): int
66
    {
67
        $connectionName = $input->getOption('connection');
68
        if (empty($connectionName)) {
69
            $connectionName = $this->connectionRegistry->getDefaultConnectionName();
70
        }
71
72
        $connection = $this->connectionRegistry->getConnection($connectionName);
73
74
        $ifNotExists = $input->getOption('if-not-exists');
75
76
        $params = $connection->getParams();
77
        if (isset($params['master'])) {
78
            $params = $params['master'];
79
        }
80
81
        // Cannot inject `shard` option in parent::getDoctrineConnection
82
        // cause it will try to connect to a non-existing database
83
        if (isset($params['shards'])) {
84
            $shards = $params['shards'];
85
            // Default select global
86
            $params = array_merge($params, $params['global']);
87
            unset($params['global']['dbname']);
88
            if ($input->getOption('shard')) {
89
                foreach ($shards as $i => $shard) {
90
                    if ($shard['id'] === (int) $input->getOption('shard')) {
91
                        // Select sharded database
92
                        $params = array_merge($params, $shard);
93
                        unset($params['shards'][$i]['dbname'], $params['id']);
94
                        break;
95
                    }
96
                }
97
            }
98
        }
99
100
        $hasPath = isset($params['path']);
101
102
        $name = $hasPath ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false);
103
        if (!$name) {
104
            throw new \InvalidArgumentException(
105
                'Connection does not contain a \'path\' or \'dbname\' parameter and cannot be dropped.'
106
            );
107
        }
108
109
        // Need to get rid of _every_ occurrence of dbname from connection configuration
110
        // and we have already extracted all relevant info from url
111
        unset($params['dbname'], $params['path'], $params['url']);
112
113
        $tmpConnection = DriverManager::getConnection($params);
114
        $tmpConnection->connect($input->getOption('shard'));
0 ignored issues
show
Unused Code introduced by
The call to Connection::connect() has too many arguments starting with $input->getOption('shard').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
115
        $shouldNotCreateDatabase = $ifNotExists && in_array($name, $tmpConnection->getSchemaManager()->listDatabases());
116
117
        // Only quote if we don't have a path
118
        if (!$hasPath) {
119
            $name = $tmpConnection->getDatabasePlatform()->quoteSingleIdentifier($name);
120
        }
121
122
        $error = false;
123
        try {
124
            if ($shouldNotCreateDatabase) {
125
                $output->writeln(
126
                    sprintf(
127
                        '<info>Database <comment>%s</comment> for connection named <comment>%s</comment>'
128
                            .' already exists. Skipped.</info>',
129
                        $name,
130
                        $connectionName
131
                    )
132
                );
133
            } else {
134
                $tmpConnection->getSchemaManager()->createDatabase($name);
135
                $output->writeln(
136
                    sprintf(
137
                        '<info>Created database <comment>%s</comment>'
138
                            .' for connection named <comment>%s</comment></info>',
139
                        $name,
140
                        $connectionName
141
                    )
142
                );
143
            }
144
        } catch (\Exception $e) {
145
            $output->writeln(
146
                sprintf(
147
                    '<error>Could not create database <comment>%s</comment>'
148
                        .' for connection named <comment>%s</comment></error>',
149
                    $name,
150
                    $connectionName
151
                )
152
            );
153
            $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
154
            $error = true;
155
        }
156
157
        $tmpConnection->close();
158
159
        return $error ? 1 : 0;
160
    }
161
}
162