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

CreateDatabaseDoctrineCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 0
cts 21
cp 0
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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