Passed
Pull Request — master (#27)
by
unknown
10:06
created

SchemaCommand::displaySchema()   F

Complexity

Conditions 20
Paths 1560

Size

Total Lines 101
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 75
c 1
b 0
f 0
nc 1560
nop 3
dl 0
loc 101
ccs 0
cts 87
cp 0
crap 420
rs 0

How to fix   Long Method    Complexity   

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
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Command\Common;
6
7
use Cycle\ORM\Relation;
8
use Cycle\ORM\Schema;
9
use Cycle\ORM\SchemaInterface;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Yiisoft\Yii\Console\ExitCode;
14
use Yiisoft\Yii\Cycle\Command\CycleDependencyPromise;
15
16
final class SchemaCommand extends Command
17
{
18
    protected static $defaultName = 'cycle/schema';
19
20
    private CycleDependencyPromise $promise;
21
    private const STR_RELATION = [
22
        Relation::HAS_ONE => 'has one',
23
        Relation::HAS_MANY => 'has many',
24
        Relation::BELONGS_TO => 'belongs to',
25
        Relation::REFERS_TO => 'refers to',
26
        Relation::MANY_TO_MANY => 'many to many',
27
        Relation::BELONGS_TO_MORPHED => 'belongs to morphed',
28
        Relation::MORPHED_HAS_ONE => 'morphed has one',
29
        Relation::MORPHED_HAS_MANY => 'morphed has many',
30
    ];
31
    private const STR_PREFETCH_MODE = [
32
        Relation::LOAD_PROMISE => 'promise',
33
        Relation::LOAD_EAGER => 'eager',
34
    ];
35
36
    public function __construct(CycleDependencyPromise $promise)
37
    {
38
        $this->promise = $promise;
39
        parent::__construct();
40
    }
41
42
    public function configure(): void
43
    {
44
        $this->setDescription('Shown current schema');
45
        $this->addArgument('entity', null, 'Entity or entities to display (separated by ",").');
46
    }
47
48
    protected function execute(InputInterface $input, OutputInterface $output): int
49
    {
50
        $schema = $this->promise->getSchema();
51
        $entityParameter = $input->getArgument('entity');
52
53
        if ($entityParameter !== null) {
54
            foreach(explode(',', $entityParameter) as $role) {
0 ignored issues
show
Bug introduced by
It seems like $entityParameter can also be of type string[]; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

54
            foreach(explode(',', /** @scrutinizer ignore-type */ $entityParameter) as $role) {
Loading history...
55
                $this->displaySchema($schema, strtolower($role), $output);
56
            }
57
        } else {
58
            foreach ($schema->getRoles() as $role) {
59
                $this->displaySchema($schema, $role, $output);
60
            }
61
        }
62
63
        return ExitCode::OK;
64
    }
65
66
    /**
67
     * Display data schema in console output
68
     *
69
     * @param SchemaInterface $schema Data schema
70
     * @param string $role Role to display
71
     * @param OutputInterface $output Output console
72
     * @return void
73
     */
74
    private function displaySchema(SchemaInterface $schema, string $role, OutputInterface $output) : void
75
    {
76
        $output->write("<fg=magenta>[{$role}</>");
77
        $alias = $schema->resolveAlias($role);
78
        // alias
79
        if ($alias !== null && $alias !== $role) {
80
            $output->write("=><fg=magenta>{$alias}</>");
81
        }
82
        $output->write("<fg=magenta>]</>");
83
84
        // database and table
85
        $database = $schema->define($role, Schema::DATABASE);
86
        $table = $schema->define($role, Schema::TABLE);
87
        if ($database !== null) {
88
            $output->write(" :: <fg=green>{$database}</>.<fg=green>{$table}</>");
89
        }
90
        $output->writeln('');
91
92
        // Entity
93
        $entity = $schema->define($role, Schema::ENTITY);
94
        $output->write('   Entity     : ');
95
        $output->writeln($entity === null ? 'no entity' : "<fg=blue>{$entity}</>");
96
        // Mapper
97
        $mapper = $schema->define($role, Schema::MAPPER);
98
        $output->write('   Mapper     : ');
99
        $output->writeln($mapper === null ? 'no mapper' : "<fg=blue>{$mapper}</>");
100
        // Constrain
101
        $constrain = $schema->define($role, Schema::CONSTRAIN);
102
        $output->write('   Constrain  : ');
103
        $output->writeln($constrain === null ? 'no constrain' : "<fg=blue>{$constrain}</>");
104
        // Repository
105
        $repository = $schema->define($role, Schema::REPOSITORY);
106
        $output->write('   Repository : ');
107
        $output->writeln($repository === null ? 'no repository' : "<fg=blue>{$repository}</>");
108
        // PK
109
        $pk = $schema->define($role, Schema::PRIMARY_KEY);
110
        $output->write('   Primary key: ');
111
        $output->writeln($pk === null ? 'no primary key' : "<fg=green>{$pk}</>");
112
        // Fields
113
        $columns = $schema->define($role, Schema::COLUMNS);
114
        $output->writeln("   Fields     :");
115
        $output->writeln("     (<fg=cyan>property</> -> <fg=green>db.field</> -> <fg=blue>typecast</>)");
116
        $types = $schema->define($role, Schema::TYPECAST);
117
        foreach ($columns as $property => $field) {
118
            $typecast = $types[$property] ?? $types[$field] ?? null;
119
            $output->write("     <fg=cyan>{$property}</> -> <fg=green>{$field}</>");
120
            if ($typecast !== null) {
121
                $output->write(" -> <fg=blue>{$typecast}</>");
122
            }
123
            $output->writeln('');
124
        }
125
126
        // Relations
127
        $relations = $schema->define($role, Schema::RELATIONS);
128
        if (count($relations) > 0) {
129
            $output->writeln('   Relations  :');
130
            foreach ($relations as $field => $relation) {
131
                $type = self::STR_RELATION[$relation[Relation::TYPE] ?? ''] ?? '?';
132
                $target = $relation[Relation::TARGET] ?? '?';
133
                $loading = self::STR_PREFETCH_MODE[$relation[Relation::LOAD] ?? ''] ?? '?';
134
                $relSchema = $relation[Relation::SCHEMA];
135
                $innerKey = $relSchema[Relation::INNER_KEY] ?? '?';
136
                $outerKey = $relSchema[Relation::OUTER_KEY] ?? '?';
137
                $where = $relSchema[Relation::WHERE] ?? [];
138
                $cascade = $relSchema[Relation::CASCADE] ?? null;
139
                $cascadeStr = $cascade ? 'cascaded' : 'not cascaded';
140
                $nullable = $relSchema[Relation::NULLABLE] ?? null;
141
                $nullableStr = $nullable ? 'nullable' : ($nullable === false ? 'not null' : 'n/a');
142
                $morphKey = $relSchema[Relation::MORPH_KEY] ?? null;
143
                // Many-To-Many relation(s) options
144
                $mmInnerKey = $relSchema[Relation::THROUGH_INNER_KEY] ?? '?';
145
                $mmOuterKey = $relSchema[Relation::THROUGH_OUTER_KEY] ?? '?';
146
                $mmEntity = $relSchema[Relation::THROUGH_ENTITY] ?? null;
147
                $mmWhere = $relSchema[Relation::THROUGH_WHERE] ?? [];
148
                // print
149
                $output->write(
150
                    "     <fg=magenta>{$role}</>-><fg=cyan>{$field}</> "
151
                    . "{$type} <fg=magenta>{$target}</> {$loading} load"
152
                );
153
                if ($morphKey !== null) {
154
                    $output->writeln("       Morphed key: <fg=green>{$morphKey}</>");
155
                }
156
                $output->writeln(" <fg=yellow>{$cascadeStr}</>");
157
                $output->write("       {$nullableStr} <fg=green>{$table}</>.<fg=green>{$innerKey}</> <=");
158
                if ($mmEntity !== null) {
159
                    $output->write(" <fg=magenta>{$mmEntity}</>.<fg=green>{$mmInnerKey}</>");
160
                    $output->write("|");
161
                    $output->write("<fg=magenta>{$mmEntity}</>.<fg=green>{$mmOuterKey}</> ");
162
                }
163
                $output->writeln("=> <fg=magenta>{$target}</>.<fg=green>{$outerKey}</> ");
164
                if (count($where)) {
165
                    $output->write("       Where:");
166
                    $output->writeln(str_replace(["\r\n", "\n"], "\n       ", "\n" . print_r($where, 1)));
167
                }
168
                if (count($mmWhere)) {
169
                    $output->write("       Through where:");
170
                    $output->writeln(str_replace(["\r\n", "\n"], "\n       ", "\n" . print_r($mmWhere, 1)));
171
                }
172
            }
173
        } else {
174
            $output->writeln('   No relations');
175
        }
176
    }
177
}
178