Test Failed
Push — master ( 3df9de...c64964 )
by Dominik
03:06
created

DropDatabaseDoctrineCommand::getDbName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 12
loc 12
ccs 0
cts 10
cp 0
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 12
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/DropDatabaseDoctrineCommand.php
17
 */
18
final class DropDatabaseDoctrineCommand extends Command
19
{
20
    const RETURN_CODE_NOT_DROP = 1;
21
22
    const RETURN_CODE_NO_FORCE = 2;
23
24
    /**
25
     * @var ConnectionRegistry
26
     */
27
    private $connectionRegistry;
28
29
    /**
30
     * @param ConnectionRegistry $connectionRegistry
31
     */
32
    public function __construct(ConnectionRegistry $connectionRegistry)
33
    {
34
        parent::__construct();
35
36
        $this->connectionRegistry = $connectionRegistry;
37
    }
38
39
    protected function configure()
40
    {
41
        $this
42
            ->setName('dbal:database:drop')
43
            ->setDescription('Drops the configured database')
44
            ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
45
            ->addOption(
46
                'if-exists',
47
                null,
48
                InputOption::VALUE_NONE,
49
                'Don\'t trigger an error, when the database doesn\'t exist'
50
            )
51
            ->addOption('force', null, InputOption::VALUE_NONE, 'Set this parameter to execute this action')
52
            ->setHelp(<<<EOT
53
The <info>%command.name%</info> command drops the default connections database:
54
55
    <info>php %command.full_name%</info>
56
57
The <info>--force</info> parameter has to be used to actually drop the database.
58
59
You can also optionally specify the name of a connection to drop the database for:
60
61
    <info>php %command.full_name% --connection=default</info>
62
63
<error>Be careful: All data in a given database will be lost when executing this command.</error>
64
EOT
65
            );
66
    }
67
68
    /**
69
     * @param InputInterface  $input
70
     * @param OutputInterface $output
71
     *
72
     * @return int
73
     */
74
    protected function execute(InputInterface $input, OutputInterface $output): int
75
    {
76
        $connectionName = $this->getConnectionName($input);
77
78
        $connection = $this->connectionRegistry->getConnection($connectionName);
79
80
        $params = $this->getParams($connection);
81
82
        $dbName = $this->getDbName($params, $connectionName);
83
84
        if (!$input->getOption('force')) {
85
            $this->writeMissingForceOutput($output, $dbName, $connectionName);
86
87
            return self::RETURN_CODE_NO_FORCE;
88
        }
89
90
        $ifExists = $input->getOption('if-exists');
91
92
        unset($params['dbname'], $params['url']);
93
94
        $connection->close();
95
        $connection = DriverManager::getConnection($params);
96
        $shouldDropDatabase = !$ifExists || in_array($dbName, $connection->getSchemaManager()->listDatabases());
97
98
        // Only quote if we don't have a path
99
        if (!isset($params['path'])) {
100
            $dbName = $connection->getDatabasePlatform()->quoteSingleIdentifier($dbName);
101
        }
102
103
        return $this->dropDatabase($output, $connectionName, $tmpConnection, $dbName, $shouldDropDatabase);
0 ignored issues
show
Bug introduced by
The variable $tmpConnection does not exist. Did you mean $connection?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
104
    }
105
106
    /**
107
     * @param InputInterface $input
108
     *
109
     * @return string
110
     */
111 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...
112
    {
113
        $connectionName = $input->getOption('connection');
114
115
        if (null !== $connectionName) {
116
            return $connectionName;
117
        }
118
119
        return $this->connectionRegistry->getDefaultConnectionName();
120
    }
121
122
    /**
123
     * @param Connection $connection
124
     *
125
     * @return array
126
     */
127 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...
128
    {
129
        $params = $connection->getParams();
130
        if (isset($params['master'])) {
131
            $params = $params['master'];
132
        }
133
134
        return $params;
135
    }
136
137
    /**
138
     * @param array  $params
139
     * @param string $connectionName
140
     *
141
     * @return string
142
     */
143 View Code Duplication
    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...
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...
144
    {
145
        if (isset($params['path'])) {
146
            return $params['path'];
147
        }
148
149
        if (isset($params['dbname'])) {
150
            return $params['dbname'];
151
        }
152
153
        throw new \InvalidArgumentException('Connection does not contain a \'path\' or \'dbname\' parameter.');
154
    }
155
156
    /**
157
     * @param OutputInterface $output
158
     * @param string          $dbName
159
     * @param string          $connectionName
160
     */
161
    private function writeMissingForceOutput(OutputInterface $output, string $dbName, string $connectionName)
162
    {
163
        $output->writeln(
164
            '<error>ATTENTION:</error> This operation should not be executed in a production environment.'
165
        );
166
        $output->writeln('');
167
        $output->writeln(
168
            sprintf(
169
                '<info>Would drop the database <comment>%s</comment> for connection'
170
                    .' named <comment>%s</comment>.</info>',
171
                $dbName,
172
                $connectionName
173
            )
174
        );
175
        $output->writeln('Please run the operation with --force to execute');
176
        $output->writeln('<error>All data will be lost!</error>');
177
    }
178
179
    /**
180
     * @param OutputInterface $output
181
     * @param string          $connectionName
182
     * @param Connection      $connection
183
     * @param string          $dbName
184
     * @param bool            $shouldNotCreateDatabase
0 ignored issues
show
Bug introduced by
There is no parameter named $shouldNotCreateDatabase. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
185
     *
186
     * @return int
187
     */
188 View Code Duplication
    private function dropDatabase(
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...
189
        OutputInterface $output,
190
        string $connectionName,
191
        Connection $connection,
192
        string $dbName,
193
        bool $shouldDropDatabase
194
    ): int {
195
        try {
196
            if ($shouldDropDatabase) {
197
                $connection->getSchemaManager()->dropDatabase($dbName);
198
                $output->writeln(
199
                    sprintf(
200
                        '<info>Dropped database <comment>%s</comment> for connection'
201
                            .' named <comment>%s</comment></info>',
202
                        $dbName,
203
                        $connectionName
204
                    )
205
                );
206
            } else {
207
                $output->writeln(
208
                    sprintf(
209
                        '<info>Database <comment>%s</comment> for connection named <comment>%s</comment>'
210
                            .' doesn\'t exist. Skipped.</info>',
211
                        $dbName,
212
                        $connectionName
213
                    )
214
                );
215
            }
216
        } catch (\Exception $e) {
217
            $output->writeln(
218
                sprintf(
219
                    '<error>Could not drop database <comment>%s</comment> for connection'
220
                        .' named <comment>%s</comment></error>',
221
                    $dbName,
222
                    $connectionName
223
                )
224
            );
225
            $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
226
227
            return self::RETURN_CODE_NOT_DROP;
228
        }
229
230
        return 0;
231
    }
232
}
233