Passed
Push — master ( d8a269...27cede )
by Alexander
02:46 queued 01:01
created

SchemaCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
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 Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Yiisoft\Yii\Console\ExitCode;
13
use Yiisoft\Yii\Cycle\Command\CycleDependencyPromise;
14
15
final class SchemaCommand extends Command
16
{
17
    protected static $defaultName = 'cycle/schema';
18
19
    private CycleDependencyPromise $promise;
20
    private const STR_RELATION = [
21
        Relation::HAS_ONE => 'has one',
22
        Relation::HAS_MANY => 'has many',
23
        Relation::BELONGS_TO => 'belongs to',
24
        Relation::REFERS_TO => 'refers to',
25
        Relation::MANY_TO_MANY => 'many to many',
26
        Relation::BELONGS_TO_MORPHED => 'belongs to morphed',
27
        Relation::MORPHED_HAS_ONE => 'morphed has one',
28
        Relation::MORPHED_HAS_MANY => 'morphed has many',
29
    ];
30
    private const STR_PREFETCH_MODE = [
31
        Relation::LOAD_PROMISE => 'promise',
32
        Relation::LOAD_EAGER => 'eager',
33
    ];
34
35
    public function __construct(CycleDependencyPromise $promise)
36
    {
37
        $this->promise = $promise;
38
        parent::__construct();
39
    }
40
41
    public function configure(): void
42
    {
43
        $this->setDescription('Shown current schema');
44
    }
45
46
    protected function execute(InputInterface $input, OutputInterface $output): int
47
    {
48
        $schema = $this->promise->getSchema();
49
        foreach ($schema->getRoles() as $role) {
50
            $output->write("<fg=magenta>[{$role}</>");
51
            $alias = $schema->resolveAlias($role);
52
            // alias
53
            if ($alias !== null && $alias !== $role) {
54
                $output->write("=><fg=magenta>{$alias}</>");
55
            }
56
            $output->write("<fg=magenta>]</>");
57
58
            // database and table
59
            $database = $schema->define($role, Schema::DATABASE);
60
            $table = $schema->define($role, Schema::TABLE);
61
            if ($database !== null) {
62
                $output->write(" :: <fg=green>{$database}</>.<fg=green>{$table}</>");
63
            }
64
            $output->writeln('');
65
66
            // Entity
67
            $entity = $schema->define($role, Schema::ENTITY);
68
            $output->write('   Entity     : ');
69
            $output->writeln($entity === null ? 'no entity' : "<fg=blue>{$entity}</>");
70
            // Mapper
71
            $mapper = $schema->define($role, Schema::MAPPER);
72
            $output->write('   Mapper     : ');
73
            $output->writeln($mapper === null ? 'no mapper' : "<fg=blue>{$mapper}</>");
74
            // Constrain
75
            $constrain = $schema->define($role, Schema::CONSTRAIN);
76
            $output->write('   Constrain  : ');
77
            $output->writeln($constrain === null ? 'no constrain' : "<fg=blue>{$constrain}</>");
78
            // Repository
79
            $repository = $schema->define($role, Schema::REPOSITORY);
80
            $output->write('   Repository : ');
81
            $output->writeln($repository === null ? 'no repository' : "<fg=blue>{$repository}</>");
82
            // PK
83
            $pk = $schema->define($role, Schema::PRIMARY_KEY);
84
            $output->write('   Primary key: ');
85
            $output->writeln($pk === null ? 'no primary key' : "<fg=green>{$pk}</>");
86
            // Fields
87
            $columns = $schema->define($role, Schema::COLUMNS);
88
            $output->writeln("   Fields     :");
89
            $output->writeln("     (<fg=cyan>property</> -> <fg=green>db.field</> -> <fg=blue>typecast</>)");
90
            $types = $schema->define($role, Schema::TYPECAST);
91
            foreach ($columns as $property => $field) {
92
                $typecast = $types[$property] ?? $types[$field] ?? null;
93
                $output->write("     <fg=cyan>{$property}</> -> <fg=green>{$field}</>");
94
                if ($typecast !== null) {
95
                    $output->write(" -> <fg=blue>{$typecast}</>");
96
                }
97
                $output->writeln('');
98
            }
99
100
            // Relations
101
            $relations = $schema->define($role, Schema::RELATIONS);
102
            if (count($relations) > 0) {
103
                $output->writeln('   Relations  :');
104
                foreach ($relations as $field => $relation) {
105
                    $type = self::STR_RELATION[$relation[Relation::TYPE] ?? ''] ?? '?';
106
                    $target = $relation[Relation::TARGET] ?? '?';
107
                    $loading = self::STR_PREFETCH_MODE[$relation[Relation::LOAD] ?? ''] ?? '?';
108
                    $relSchema = $relation[Relation::SCHEMA];
109
                    $innerKey = $relSchema[Relation::INNER_KEY] ?? '?';
110
                    $outerKey = $relSchema[Relation::OUTER_KEY] ?? '?';
111
                    $where = $relSchema[Relation::WHERE] ?? [];
112
                    $cascade = $relSchema[Relation::CASCADE] ?? null;
113
                    $cascadeStr = $cascade ? 'cascaded' : 'not cascaded';
114
                    $nullable = $relSchema[Relation::NULLABLE] ?? null;
115
                    $nullableStr = $nullable ? 'nullable' : ($nullable === false ? 'not null' : 'n/a');
116
                    $morphKey = $relSchema[Relation::MORPH_KEY] ?? null;
117
                    // Many-To-Many relation(s) options
118
                    $mmInnerKey = $relSchema[Relation::THROUGH_INNER_KEY] ?? '?';
119
                    $mmOuterKey = $relSchema[Relation::THROUGH_OUTER_KEY] ?? '?';
120
                    $mmEntity = $relSchema[Relation::THROUGH_ENTITY] ?? null;
121
                    $mmWhere = $relSchema[Relation::THROUGH_WHERE] ?? [];
122
                    // print
123
                    $output->write(
124
                        "     <fg=magenta>{$role}</>-><fg=cyan>{$field}</> "
125
                        . "{$type} <fg=magenta>{$target}</> {$loading} load"
126
                    );
127
                    if ($morphKey !== null) {
128
                        $output->writeln("       Morphed key: <fg=green>{$morphKey}</>");
129
                    }
130
                    $output->writeln(" <fg=yellow>{$cascadeStr}</>");
131
                    $output->write("       {$nullableStr} <fg=green>{$table}</>.<fg=green>{$innerKey}</> <=");
132
                    if ($mmEntity !== null) {
133
                        $output->write(" <fg=magenta>{$mmEntity}</>.<fg=green>{$mmInnerKey}</>");
134
                        $output->write("|");
135
                        $output->write("<fg=magenta>{$mmEntity}</>.<fg=green>{$mmOuterKey}</> ");
136
                    }
137
                    $output->writeln("=> <fg=magenta>{$target}</>.<fg=green>{$outerKey}</> ");
138
                    if (count($where)) {
139
                        $output->write("       Where:");
140
                        $output->writeln(str_replace(["\r\n", "\n"], "\n       ", "\n" . print_r($where, 1)));
141
                    }
142
                    if (count($mmWhere)) {
143
                        $output->write("       Through where:");
144
                        $output->writeln(str_replace(["\r\n", "\n"], "\n       ", "\n" . print_r($mmWhere, 1)));
145
                    }
146
                }
147
            } else {
148
                $output->writeln('   No relations');
149
            }
150
        }
151
        return ExitCode::OK;
152
    }
153
}
154