DatabaseListCommand::execute()   B
last analyzed

Complexity

Conditions 8
Paths 12

Size

Total Lines 64
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 36
nc 12
nop 2
dl 0
loc 64
ccs 0
cts 29
cp 0
crap 72
rs 8.0995
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of Biurad opensource projects.
5
 *
6
 * @copyright 2019 Biurad Group (https://biurad.com/)
7
 * @license   https://opensource.org/licenses/BSD-3-Clause License
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Flange\Commands\CycleORM;
14
15
use Cycle\Database\Config\DatabaseConfig;
16
use Cycle\Database\Database;
17
use Cycle\Database\DatabaseProviderInterface;
18
use Cycle\Database\Driver\Driver;
19
use Symfony\Component\Console\Command\Command;
20
use Symfony\Component\Console\Helper\Table;
21
use Symfony\Component\Console\Helper\TableSeparator;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Output\OutputInterface;
25
26
/**
27
 * List of every configured database, it's tables and count of records.
28
 *
29
 * @author Divine Niiquaye Ibok <[email protected]>
30
 */
31
final class DatabaseListCommand extends Command
32
{
33
    /**
34
     * No information available placeholder.
35
     */
36
    private const SKIP = '<comment>---</comment>';
37
38
    protected static $defaultName = 'cycle:database:list';
39
40
    public function __construct(private DatabaseConfig $config, private DatabaseProviderInterface $provider)
41
    {
42
        parent::__construct();
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    protected function configure(): void
49
    {
50
        $this
51
            ->setDefinition([
52
                new InputArgument('db', InputArgument::OPTIONAL, 'Database name'),
53
            ])
54
            ->setDescription('Get list of available databases, their tables and records count')
55
            ->setHelp(
56
                <<<EOT
57
The <info>%command.name%</info> command list the default connections databases:
58
59
    <info>php %command.full_name%</info>
60
61
You can also optionally specify the name of a database name to view it's connection and tables:
62
63
    <info>php %command.full_name% migrations</info>
64
EOT
65
            )
66
        ;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    protected function execute(InputInterface $input, OutputInterface $output): int
73
    {
74
        $databases = $input->getArgument('db') ?? \array_keys($this->config->getDatabases());
75
76
        if (!\is_array($databases)) {
77
            $databases = [$databases];
78
        }
79
80
        if (empty($databases)) {
81
            $output->writeln('<fg=red>No databases found.</fg=red>');
82
83
            return self::SUCCESS;
84
        }
85
86
        // create symfony command table
87
        $grid = new Table($output);
88
        $grid->setHeaders(
89
            [
90
                'Name (ID):',
91
                'Database:',
92
                'Driver:',
93
                'Prefix:',
94
                'Status:',
95
                'Tables:',
96
                'Count Records:',
97
            ]
98
        );
99
100
        foreach ($databases as $database) {
101
            $database = $this->provider->database($database);
102
103
            /** @var Driver $driver */
104
            $driver = $database->getDriver();
105
106
            $header = [
107
                $database->getName(),
108
                $driver->getSource(),
109
                $driver->getType(),
110
                $database->getPrefix() ?: self::SKIP,
111
            ];
112
113
            try {
114
                $driver->connect();
115
            } catch (\Exception $exception) {
116
                $this->renderException($grid, $header, $exception);
117
118
                if ($database->getName() != \end($databases)) {
119
                    $grid->addRow(new TableSeparator());
120
                }
121
122
                continue;
123
            }
124
125
            $header[] = '<info>connected</info>';
126
            $this->renderTables($grid, $header, $database);
127
128
            if ($database->getName() != \end($databases)) {
129
                $grid->addRow(new TableSeparator());
130
            }
131
        }
132
133
        $grid->render();
134
135
        return self::SUCCESS;
136
    }
137
138
    private function renderException(Table $grid, array $header, \Throwable $exception): void
139
    {
140
        $grid->addRow(
141
            \array_merge(
142
                $header,
143
                [
144
                    "<fg=red>{$exception->getMessage()}</fg=red>",
145
                    self::SKIP,
146
                    self::SKIP,
147
                ]
148
            )
149
        );
150
    }
151
152
    private function renderTables(Table $grid, array $header, Database $database): void
153
    {
154
        foreach ($database->getTables() as $table) {
155
            $grid->addRow(
156
                \array_merge(
157
                    $header,
158
                    [$table->getName(), \number_format($table->count())]
159
                )
160
            );
161
            $header = ['', '', '', '', ''];
162
        }
163
164
        $header[1] && $grid->addRow(\array_merge($header, ['no tables', 'no records']));
165
    }
166
}
167