Passed
Push — next ( e3594a...9991ed )
by Bas
10:46 queued 05:19
created

TableCommand   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Test Coverage

Coverage 94.74%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 79
c 1
b 0
f 0
dl 0
loc 199
ccs 90
cts 95
cp 0.9474
rs 10
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getAttributesForIndex() 0 9 3
A display() 0 3 2
A handle() 0 45 5
A indexes() 0 6 1
A columns() 0 3 1
B displayForCli() 0 57 7
A displayLongStringValue() 0 6 2
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Console;
4
5
use Illuminate\Database\ConnectionResolverInterface;
6
use Illuminate\Database\Console\TableCommand as IlluminateTableCommand;
7
use Illuminate\Database\Schema\Builder;
8
use Illuminate\Support\Number;
9
use LaravelFreelancerNL\Aranguent\Connection;
10
11
use function Laravel\Prompts\select;
12
13
class TableCommand extends IlluminateTableCommand
14
{
15
    /**
16
     * The name and signature of the console command.
17
     *
18
     * @var string
19
     */
20
    protected $signature = 'db:table
21
                            {table? : The name of the table}
22
                            {--database= : The database connection}
23
                            {--system= : Include system tables (ArangoDB)}
24
                            {--json : Output the table information as JSON}';
25
26
    /**
27
     * The console command description.
28
     *
29
     * @var string
30
     */
31
    protected $description = 'Display information about the given database table';
32
33
    /**
34
     * Execute the console command.
35
     *
36
     * @return int
37
     */
38 4
    public function handle(ConnectionResolverInterface $connections)
39
    {
40 4
        $connection = $connections->connection($this->input->getOption('database'));
41
42 4
        if (! $connection instanceof Connection) {
43
            return parent::handle($connections);
44
        }
45
46 4
        $schema = $connection->getSchemaBuilder();
47
48 4
        $tables = collect(
49 4
            ($this->input->getOption('system'))
0 ignored issues
show
Bug introduced by
$this->input->getOption(... : $schema->getTables() of type array|array<mixed,mixed> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

49
            /** @scrutinizer ignore-type */ ($this->input->getOption('system'))
Loading history...
50
                ? $schema->getAllTables()
51 4
                : $schema->getTables(),
52 4
        )
53 4
            ->keyBy(fn($table) => (string) $table->name)
54 4
            ->all();
55
56 4
        $tableName = (string) $this->argument('table') ?: select(
57 4
            'Which table would you like to inspect?',
58 4
            array_keys($tables),
59 4
        );
60
61 4
        $table = $schema->getTable((string) $tableName);
62
63 4
        if (! $table) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $table of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
64
            $this->components->warn("Table [{$tableName}] doesn't exist.");
65
66
            return 1;
67
        }
68
69 4
        $tableName = $this->withoutTablePrefix($connection, $table['name']);
70
71 4
        $columns = $this->columns($schema, $tableName);
72 4
        $indexes = $this->indexes($schema, $tableName);
73
74 4
        $data = [
75 4
            'table' => $table,
76 4
            'columns' => $columns,
77 4
            'indexes' => $indexes,
78 4
        ];
79
80 4
        $this->display($data);
81
82 4
        return 0;
83
    }
84
85
    /**
86
     * Get the information regarding the table's columns.
87
     *
88
     * @param  \Illuminate\Database\Schema\Builder  $schema
89
     * @param  string  $table
90
     * @return \Illuminate\Support\Collection
91
     */
92 4
    protected function columns(Builder $schema, string $table)
93
    {
94 4
        return collect($schema->getColumns($table));
0 ignored issues
show
Bug introduced by
$schema->getColumns($table) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

94
        return collect(/** @scrutinizer ignore-type */ $schema->getColumns($table));
Loading history...
95
    }
96
97
    /**
98
     * Get the information regarding the table's indexes.
99
     *
100
     * @param  \Illuminate\Database\Schema\Builder  $schema
101
     * @param  string  $table
102
     * @return \Illuminate\Support\Collection
103
     */
104 4
    protected function indexes(Builder $schema, string $table)
105
    {
106 4
        return collect($schema->getIndexes($table))->map(fn($index) => [
0 ignored issues
show
Bug introduced by
$schema->getIndexes($table) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

106
        return collect(/** @scrutinizer ignore-type */ $schema->getIndexes($table))->map(fn($index) => [
Loading history...
107 4
            'name' => (string) $index['name'],
108 4
            'columns' => collect((array) $index['fields']),
0 ignored issues
show
Bug introduced by
(array)$index['fields'] of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

108
            'columns' => collect(/** @scrutinizer ignore-type */ (array) $index['fields']),
Loading history...
109 4
            'attributes' => $this->getAttributesForIndex((array) $index),
110 4
        ]);
111
    }
112
113
    /**
114
     * Get the attributes for a table index.
115
     *
116
     * @param  array<mixed>  $index
117
     * @return \Illuminate\Support\Collection
118
     */
119 4
    protected function getAttributesForIndex($index)
120
    {
121 4
        return collect(
122 4
            array_filter([
0 ignored issues
show
Bug introduced by
array_filter(array('spar...pe' => $index['type'])) of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

122
            /** @scrutinizer ignore-type */ array_filter([
Loading history...
123 4
                'sparse' => $index['sparse'] ? 'sparse' : null,
124 4
                'unique' => $index['unique'] ? 'unique' : null,
125 4
                'type' => $index['type'],
126 4
            ]),
127 4
        )->filter();
128
    }
129
130
    /**
131
     * Render the table information.
132
     *
133
     * @param  mixed[]  $data
134
     * @return void
135
     */
136 4
    protected function display(array $data)
137
    {
138 4
        $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data);
139
    }
140
141 1
    protected function displayLongStringValue(string $value): string
142
    {
143 1
        if (strlen($value) < 136) {
144 1
            return $value;
145
        }
146
        return substr($value, 0, 133) . '...';
147
    }
148
149
    /**
150
     * Render the table information formatted for the CLI.
151
     *
152
     * @param  mixed[] $data
153
     * @return void
154
     */
155 4
    protected function displayForCli(array $data)
156
    {
157 4
        [$table, $columns, $indexes ] = [
158 4
            $data['table'], $data['columns'], $data['indexes'],
159 4
        ];
160
161 4
        $this->newLine();
162
163 4
        $this->components->twoColumnDetail('<fg=green;options=bold>Table</>', '<fg=green;options=bold>' . $table['name'] . '</>');
164 4
        $this->components->twoColumnDetail('Type', ($table['type'] == 2) ? 'Vertex' : 'Edge');
165 4
        $this->components->twoColumnDetail('Status', $table['statusString']);
166 4
        $this->components->twoColumnDetail('User Keys Allowed', ($table['keyOptions']->allowUserKeys) ? 'Yes' : 'No');
167 4
        $this->components->twoColumnDetail('Key Type', $table['keyOptions']->type);
168 4
        $this->components->twoColumnDetail('Last Used Key', $table['keyOptions']->lastValue);
169 4
        $this->components->twoColumnDetail('Wait For Sync', ($table['waitForSync']) ? 'Yes' : 'No');
170 4
        $this->components->twoColumnDetail('Columns', $table['count']);
171 4
        $this->components->twoColumnDetail('Size Estimate', Number::fileSize($table['figures']->documentsSize, 2));
172
173 4
        $this->newLine();
174
175 4
        if ($columns->isNotEmpty()) {
176 1
            $this->components->twoColumnDetail('<fg=green;options=bold>Column</>', '<fg=green;options=bold>Type</>');
177
178 1
            $columns->each(function ($column) {
179 1
                $this->components->twoColumnDetail(
180 1
                    $column['name'],
181 1
                    implode(', ', $column['types']),
182 1
                );
183 1
            });
184 1
            $this->components->info('ArangoDB is schemaless by default. Hence, the column & types are a representation of current data within the table.');
185
        }
186
187 4
        $computedValues = collect((array) $table['computedValues']);
0 ignored issues
show
Bug introduced by
(array)$table['computedValues'] of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

187
        $computedValues = collect(/** @scrutinizer ignore-type */ (array) $table['computedValues']);
Loading history...
188 4
        if ($computedValues->isNotEmpty()) {
189 1
            $this->components->twoColumnDetail('<fg=green;options=bold>Computed Value</>', '<fg=green;options=bold>Expression</>');
190
191 1
            $computedValues->each(function ($value) {
192 1
                $this->components->twoColumnDetail(
193 1
                    $value->name,
194 1
                    $this->displayLongStringValue($value->expression),
195 1
                );
196 1
            });
197
198 1
            $this->newLine();
199
        }
200
201 4
        if ($indexes->isNotEmpty()) {
202 4
            $this->components->twoColumnDetail('<fg=green;options=bold>Index</>');
203
204 4
            $indexes->each(function ($index) {
205 4
                $this->components->twoColumnDetail(
206 4
                    $index['name'] . ' <fg=gray>' . $index['columns']->implode(', ') . '</>',
207 4
                    $index['attributes']->implode(', '),
208 4
                );
209 4
            });
210
211 4
            $this->newLine();
212
        }
213
    }
214
}
215