CreateDatabaseDoctrineCommand::getParams()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
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\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
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 5
    public function __construct(ConnectionRegistry $connectionRegistry)
26
    {
27 5
        parent::__construct();
28
29 5
        $this->connectionRegistry = $connectionRegistry;
30 5
    }
31
32 5
    protected function configure(): void
33
    {
34
        $this
35 5
            ->setName('dbal:database:create')
36 5
            ->setDescription('Creates the configured database')
37 5
            ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
38 5
            ->addOption(
39 5
                'if-not-exists',
40 5
                null,
41 5
                InputOption::VALUE_NONE,
42 5
                'Don\'t trigger an error, when the database already exists'
43
            )
44 5
            ->setHelp(<<<'EOT'
45 5
The <info>%command.name%</info> command creates the default connections database:
46
47
    <info>php %command.full_name%</info>
48
49
You can also optionally specify the name of a connection to create the database for:
50
51
    <info>php %command.full_name% --connection=default</info>
52
EOT
53
            )
54
        ;
55 5
    }
56
57 5
    protected function execute(InputInterface $input, OutputInterface $output): int
58
    {
59 5
        $connectionName = $this->getConnectionName($input);
60
61
        /** @var Connection $connection */
62 5
        $connection = $this->connectionRegistry->getConnection($connectionName);
63
64 5
        $params = $this->getParams($connection);
65
66 5
        $dbName = $this->getDbName($params);
67
68 4
        $isPath = isset($params['path']);
69
70 4
        $ifNotExists = $input->getOption('if-not-exists');
71
72
        // Need to get rid of _every_ occurrence of dbname from connection configuration
73 4
        unset($params['dbname'], $params['path'], $params['url']);
74
75 4
        $tmpConnection = DriverManager::getConnection($params);
76 4
        $shouldNotCreateDatabase = $ifNotExists &&
77 4
            in_array($dbName, $tmpConnection->getSchemaManager()->listDatabases());
78
79
        // Only quote if we don't have a path
80 4
        if (!$isPath) {
81 3
            $dbName = $tmpConnection->getDatabasePlatform()->quoteSingleIdentifier($dbName);
82
        }
83
84 4
        return $this->createDatabase($output, $connectionName, $tmpConnection, $dbName, $shouldNotCreateDatabase);
85
    }
86
87 5
    private function getConnectionName(InputInterface $input): string
88
    {
89
        /** @var string|null $connectionName */
90 5
        $connectionName = $input->getOption('connection');
91
92 5
        if (null !== $connectionName) {
93 3
            return $connectionName;
94
        }
95
96 2
        return $this->connectionRegistry->getDefaultConnectionName();
97
    }
98
99 5
    private function getParams(Connection $connection): array
100
    {
101 5
        $params = $connection->getParams();
102 5
        if (isset($params['master'])) {
103 3
            $params = $params['master'];
104
        }
105
106 5
        return $params;
107
    }
108
109
    /**
110
     * @param array<string, string> $params
111
     */
112
    private function getDbName(array $params): string
113
    {
114 5
        if (isset($params['path'])) {
115
            return $params['path'];
116 5
        }
117 1
118
        if (isset($params['dbname'])) {
119
            return $params['dbname'];
120 4
        }
121 3
122
        throw new \InvalidArgumentException('Connection does not contain a \'path\' or \'dbname\' parameter.');
123
    }
124 1
125
    private function createDatabase(
126
        OutputInterface $output,
127 4
        string $connectionName,
128
        Connection $tmpConnection,
129
        string $dbName,
130
        bool $shouldNotCreateDatabase
131
    ): int {
132
        try {
133
            if ($shouldNotCreateDatabase) {
134
                $output->writeln(
135 4
                    sprintf(
136 1
                        '<info>Database <comment>%s</comment> for connection named <comment>%s</comment>'
137 1
                            .' already exists. Skipped.</info>',
138
                        $dbName,
139 1
                        $connectionName
140 1
                    )
141 1
                );
142
            } else {
143
                $tmpConnection->getSchemaManager()->createDatabase($dbName);
144
                $output->writeln(
145 4
                    sprintf(
146 4
                        '<info>Created database <comment>%s</comment>'
147 4
                             .' for connection named <comment>%s</comment>.</info>',
148
                        $dbName,
149 4
                        $connectionName
150 4
                    )
151 4
                );
152
            }
153
154
            return 0;
155
        } catch (\Exception $exception) {
156 4
            $output->writeln(sprintf('<error>Could not create database <comment>%s</comment>.</error>', $dbName));
157 1
            $output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
158 1
159 1
            return 1;
160
        }
161 1
    }
162
}
163