Completed
Push — master ( 7a6bdd...324ce1 )
by Sébastien
09:34
created

DatabaseCommand::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 11
c 1
b 0
f 0
dl 0
loc 18
ccs 12
cts 12
cp 1
rs 9.9
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
namespace Bdf\Prime\Console;
4
5
use Bdf\Prime\Connection\ConnectionInterface;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
6
use Bdf\Prime\Connection\ConnectionRegistry;
7
use Bdf\Prime\Connection\Factory\ChainFactory;
8
use Bdf\Prime\Connection\Factory\ConnectionFactory;
9
use Bdf\Prime\Connection\Factory\ConnectionFactoryInterface;
10
use Bdf\Prime\Connection\Factory\MasterSlaveConnectionFactory;
11
use Bdf\Prime\Connection\Factory\ShardingConnectionFactory;
12
use Bdf\Prime\ConnectionManager;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
13
use Bdf\Prime\ConnectionRegistryInterface;
14
use Bdf\Prime\ServiceLocator;
15
use Bdf\Util\Console\BdfStyle;
16
use Doctrine\DBAL\Connection as DoctrineConnection;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Output\OutputInterface;
21
22
/**
23
 * @todo manage Shard and Master/slave connection
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
Coding Style Documentation introduced by
@todo tag is not allowed in class comment
Loading history...
24
 * @todo remonve doctrine dependency
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
Coding Style Documentation introduced by
@todo tag is not allowed in class comment
Loading history...
25
 */
26
abstract class DatabaseCommand extends Command
27
{
28
    /**
29
     * @var ConnectionRegistryInterface
30
     */
31
    private $registry;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
32
33
    /**
34
     * @var ConnectionFactoryInterface
35
     */
36
    private $connectionFactory;
37
38
    /**
39
     * @var BdfStyle
40
     */
41
    protected $io;
42
43
    /**
44
     * DatabaseCommand constructor.
45
     *
46
     * @param ConnectionRegistryInterface $registry
47
     * @param ConnectionFactoryInterface $connectionFactory
48
     */
49 2
    public function __construct(/* ConnectionRegistryInterface */ $registry, ConnectionFactoryInterface $connectionFactory = null)
0 ignored issues
show
introduced by
Type hint "ConnectionRegistryInterface" missing for $registry
Loading history...
Coding Style introduced by
Single line block comment not allowed; use inline ("// text") comment instead
Loading history...
50
    {
51 2
        $this->registry = $registry;
52 2
        $this->connectionFactory = $connectionFactory;
53
54 2
        if ($registry instanceof ServiceLocator) {
55 1
            @trigger_error(__METHOD__.' signature has changed since 1.1. Inject instances '.ConnectionRegistryInterface::class.' '.ConnectionFactoryInterface::class);
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged; found: @trigger_error(__METHOD__...
Loading history...
56
57 1
            $factory = new ConnectionFactory();
58 1
            $this->connectionFactory = new ChainFactory([
59 1
                new MasterSlaveConnectionFactory($factory),
60 1
                new ShardingConnectionFactory($factory),
61 1
                $factory,
62
            ]);
63 1
            $this->registry = new ConnectionRegistry([], $this->connectionFactory, $registry->config());
0 ignored issues
show
Deprecated Code introduced by
The function Bdf\Prime\ServiceLocator::config() has been deprecated: Since 1.1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

63
            $this->registry = new ConnectionRegistry([], $this->connectionFactory, /** @scrutinizer ignore-deprecated */ $registry->config());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
64
        }
65
66 2
        parent::__construct(static::$defaultName);
67 2
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 2
    protected function configure()
73
    {
74 2
        $this->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'Interacts only on the database from this connection');
75 2
        $this->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Set the user name.', 'root');
76 2
        $this->addOption('password', 'p', InputOption::VALUE_REQUIRED, 'Set the user password.', '');
77 2
    }
78
79
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $input should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $output should have a doc-comment as per coding-style.
Loading history...
80
     * {@inheritdoc}
81
     */
82 2
    protected function execute(InputInterface $input, OutputInterface $output): int
83
    {
84 2
        $this->io = new BdfStyle($input, $output);
85
86 2
        $name = $this->io->option('connection');
87
88 2
        $connections = $name ? [$name] : $this->registry->getConnectionNames();
0 ignored issues
show
Coding Style introduced by
The value of a comparison must not be assigned to a variable
Loading history...
Coding Style introduced by
Inline IF statements are not allowed
Loading history...
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
89
90 2
        foreach ($connections as $connectionName) {
91 2
            $connection = $this->registry->getConnection($connectionName);
92
93 2
            if (!$connection instanceof DoctrineConnection) {
94
                $this->io->line('Connection <comment>%s</comment> is ignored: only doctrine connection can be managed', $connectionName);
95
                continue;
96
            }
97
98 2
            $parameters = $connection->getParams();
99
100
            // Skip connections marked as "ignore" on configuration
101
            // Permit to declare SQLite connections, which do not supports database management
102 2
            if (!empty($parameters['ignore'])) {
103 2
                $this->io->line('Connection <comment>%s</comment> is ignored.', $connectionName);
104 2
                continue;
105
            }
106
107
            $dbName = $this->prepareConnectionConfig($parameters);
108
            $connectionTmp = $this->connectionFactory->create($connectionName, $parameters, $connection->getConfiguration());
109
            $schema = $connectionTmp->schema();
110
111
            if ($schema->hasDatabase($dbName)) {
112
                $this->interactWithDatabase($connectionTmp, $dbName);
113
                continue;
114
            }
115
116
            $this->interactWithNoDatabase($connectionTmp, $dbName);
117
118
            $connectionTmp->close();
0 ignored issues
show
Bug introduced by
The method close() does not exist on Bdf\Prime\Connection\ConnectionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Bdf\Prime\Connection\ConnectionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            $connectionTmp->/** @scrutinizer ignore-call */ 
119
                            close();
Loading history...
119
        }
0 ignored issues
show
Coding Style introduced by
End comment for long condition not found; expected "//end foreach"
Loading history...
120
121 2
        return 0;
122
    }
123
124
    /**
125
     * Prepare the configuration of the connection
126
     * Change the user and remove db name.
0 ignored issues
show
introduced by
Doc comment short description must be on a single line, further text should be a separate paragraph
Loading history...
127
     *
128
     * @param array $parameters
129
     *
130
     * @return string The db name to interact
131
     */
132
    protected function prepareConnectionConfig(&$parameters): string
0 ignored issues
show
introduced by
Type hint "array" missing for $parameters
Loading history...
133
    {
134
        $user = $this->io->option('user');
135
136
        if (!isset($parameters['user']) || $parameters['user'] !== $user) {
137
            $parameters['user'] = $user;
138
            $parameters['password'] = $this->io->option('password');
139
        }
140
141
        // Force the connection with no database to allow doctrine to connect.
142
        $dbName = $parameters['dbname'] ?? $parameters['path'];
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
143
        $parameters['dbname'] = $parameters['path'] = $parameters['url'] = null;
0 ignored issues
show
Coding Style introduced by
Assignments must be the first block of code on a line
Loading history...
144
145
        return $dbName;
146
    }
147
148
    /**
149
     * Interact if the database exists
150
     *
151
     * @param ConnectionInterface $connection
152
     * @param string $dbName
153
     */
154
    abstract protected function interactWithDatabase($connection, $dbName);
0 ignored issues
show
introduced by
Type hint "ConnectionInterface" missing for $connection
Loading history...
155
156
    /**
157
     * Interact if the database does not exist
158
     *
159
     * @param ConnectionInterface $connection
160
     * @param string $dbName
161
     */
162
    abstract protected function interactWithNoDatabase($connection, $dbName);
0 ignored issues
show
introduced by
Type hint "ConnectionInterface" missing for $connection
Loading history...
163
}
164