Completed
Branch master (3df9de)
by Dominik
04:56 queued 02:08
created

CreateDatabaseDoctrineCommand::getConnectionName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 10
loc 10
ccs 5
cts 5
cp 1
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
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\Connection;
9
use Doctrine\DBAL\DriverManager;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
15
/**
16
 * @see https://github.com/doctrine/DoctrineBundle/blob/master/Command/CreateDatabaseDoctrineCommand.php
17
 */
18
final class CreateDatabaseDoctrineCommand extends Command
19
{
20
    /**
21
     * @var ConnectionRegistry
22
     */
23
    private $connectionRegistry;
24
25
    /**
26
     * @param ConnectionRegistry $connectionRegistry
27
     */
28 5
    public function __construct(ConnectionRegistry $connectionRegistry)
29
    {
30 5
        parent::__construct();
31
32 5
        $this->connectionRegistry = $connectionRegistry;
33 5
    }
34
35 5
    protected function configure()
36
    {
37
        $this
38 5
            ->setName('dbal:database:create')
39 5
            ->setDescription('Creates the configured database')
40 5
            ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
41 5
            ->addOption(
42 5
                'if-not-exists',
43 5
                null,
44 5
                InputOption::VALUE_NONE,
45 5
                'Don\'t trigger an error, when the database already exists'
46
            )
47 5
            ->setHelp(<<<EOT
48 5
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 5
    }
58
59
    /**
60
     * @param InputInterface  $input
61
     * @param OutputInterface $output
62
     *
63
     * @return int
64
     */
65 5
    protected function execute(InputInterface $input, OutputInterface $output): int
66
    {
67 5
        $connectionName = $this->getConnectionName($input);
68
69 5
        $connection = $this->connectionRegistry->getConnection($connectionName);
70
71 5
        $params = $this->getParams($connection);
72
73 5
        $dbName = $this->getDbName($params, $connectionName);
74
75 4
        $isPath = isset($params['path']);
76
77
        // Need to get rid of _every_ occurrence of dbname from connection configuration
78 4
        unset($params['dbname'], $params['path'], $params['url']);
79
80 4
        $ifNotExists = $input->getOption('if-not-exists');
81
82 4
        $tmpConnection = DriverManager::getConnection($params);
83 4
        $shouldNotCreateDatabase = $ifNotExists && in_array($dbName, $tmpConnection->getSchemaManager()->listDatabases());
84
85
        // Only quote if we don't have a path
86 4
        if (!$isPath) {
87 3
            $dbName = $tmpConnection->getDatabasePlatform()->quoteSingleIdentifier($dbName);
88
        }
89
90 4
        return $this->createDatabase($output, $connectionName, $tmpConnection, $dbName, $shouldNotCreateDatabase);
91
    }
92
93
    /**
94
     * @param InputInterface $input
95
     *
96
     * @return string
97
     */
98 5 View Code Duplication
    private function getConnectionName(InputInterface $input): string
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...
99
    {
100 5
        $connectionName = $input->getOption('connection');
101
102 5
        if (null !== $connectionName) {
103 3
            return $connectionName;
104
        }
105
106 2
        return $this->connectionRegistry->getDefaultConnectionName();
107
    }
108
109
    /**
110
     * @param Connection $connection
111
     *
112
     * @return array
113
     */
114 5 View Code Duplication
    private function getParams(Connection $connection): array
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 5
        $params = $connection->getParams();
117 5
        if (isset($params['master'])) {
118 3
            $params = $params['master'];
119
        }
120
121 5
        return $params;
122
    }
123
124
    /**
125
     * @param array  $params
126
     * @param string $connectionName
127
     *
128
     * @return string
129
     */
130 5
    private function getDbName(array $params, string $connectionName): string
0 ignored issues
show
Unused Code introduced by
The parameter $connectionName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
131
    {
132 5
        if (isset($params['path'])) {
133 1
            return $params['path'];
134
        }
135
136 4
        if (isset($params['dbname'])) {
137 3
            return $params['dbname'];
138
        }
139
140 1
        throw new \InvalidArgumentException('Connection does not contain a \'path\' or \'dbname\' parameter.');
141
    }
142
143
    /**
144
     * @param OutputInterface $output
145
     * @param string          $connectionName
146
     * @param Connection      $tmpConnection
147
     * @param string          $dbName
148
     * @param bool            $shouldNotCreateDatabase
149
     *
150
     * @return int
151
     */
152 4
    private function createDatabase(
153
        OutputInterface $output,
154
        string $connectionName,
155
        Connection $tmpConnection,
156
        string $dbName,
157
        bool $shouldNotCreateDatabase
158
    ): int {
159
        try {
160 4
            if ($shouldNotCreateDatabase) {
161 1
                $output->writeln(
162 1
                    sprintf(
163
                        '<info>Database <comment>%s</comment> for connection named <comment>%s</comment>'
164 1
                            .' already exists. Skipped.</info>',
165 1
                        $dbName,
166 1
                        $connectionName
167
                    )
168
                );
169
            } else {
170 4
                $tmpConnection->getSchemaManager()->createDatabase($dbName);
171 4
                $output->writeln(
172 4
                    sprintf(
173
                        '<info>Created database <comment>%s</comment>'
174 4
                             .' for connection named <comment>%s</comment>.</info>',
175 4
                        $dbName,
176 4
                        $connectionName
177
                    )
178
                );
179
            }
180
181 4
            return 0;
182 1
        } catch (\Exception $e) {
183 1
            $output->writeln(sprintf('<error>Could not create database <comment>%s</comment>.</error>', $dbName));
184 1
            $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
185
186 1
            return 1;
187
        }
188
    }
189
}
190