Passed
Pull Request — master (#16)
by
unknown
01:41
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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
1
<?php
2
3
namespace Yiisoft\Yii\Cycle\Command;
4
5
use Cycle\ORM\Relation;
6
use Cycle\ORM\Schema;
7
use Cycle\ORM\SchemaInterface;
8
use Spiral\Database\DatabaseManager;
9
use Spiral\Migrations\Config\MigrationConfig;
10
use Spiral\Migrations\Migrator;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Yiisoft\Yii\Console\ExitCode;
14
15
class SchemaCommand extends BaseMigrationCommand
16
{
17
    protected static $defaultName = 'cycle/schema';
18
19
    private SchemaInterface $schema;
20
    private array $strRelations = [
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
    ];
27
    private array $strPreFetchMode = [
28
        Relation::LOAD_PROMISE => 'promise',
29
        Relation::LOAD_EAGER   => 'eager',
30
    ];
31
32
    public function __construct(
33
        DatabaseManager $dbal,
34
        MigrationConfig $conf,
35
        Migrator $migrator,
36
        SchemaInterface $schema
37
    ) {
38
        parent::__construct($dbal, $conf, $migrator);
39
        $this->schema = $schema;
40
    }
41
42
    public function configure(): void
43
    {
44
        $this->setDescription('Shown current schema');
45
    }
46
47
    protected function execute(InputInterface $input, OutputInterface $output): int
48
    {
49
        foreach ($this->schema->getRoles() as $role) {
50
            $output->write("<fg=red>[{$role}</>");
51
            $alias = $this->schema->resolveAlias($role);
52
            // alias
53
            if ($alias !== null && $alias !== $role) {
54
                $output->write("=><fg=red>{$alias}</>");
55
            }
56
            // table
57
            $output->write("<fg=red>]</>");
58
59
            // database
60
            $database = $this->schema->define($role, Schema::DATABASE);
61
            if ($database !== null) {
62
                $table = $this->schema->define($role, Schema::TABLE);
63
                $output->write(" :: <fg=green>{$database}</>.<fg=green>{$table}</>");
64
            }
65
            $output->writeln('');
66
67
            // Entity
68
            $entity = $this->schema->define($role, Schema::ENTITY) ?? null;
69
            $output->write('   Entity     : ');
70
            $output->writeln($entity === null ? '<fg=red>no entity</>' : "<fg=cyan>{$entity}</>");
71
            // Mapper
72
            $mapper = $this->schema->define($role, Schema::MAPPER) ?? null;
73
            $output->write('   Mapper     : ');
74
            $output->writeln($mapper === null ? '<fg=red>no mapper</>' : "<fg=cyan>{$mapper}</>");
75
            // Constrain
76
            $constrain = $this->schema->define($role, Schema::CONSTRAIN) ?? null;
77
            $output->write('   Constrain  : ');
78
            $output->writeln($constrain === null ? '<fg=red>no constrain</>' : "<fg=cyan>{$constrain}</>");
79
            // Repository
80
            $repository = $this->schema->define($role, Schema::REPOSITORY) ?? null;
81
            $output->write('   Repository : ');
82
            $output->writeln($repository === null ? '<fg=red>no repository</>' : "<fg=cyan>{$repository}</>");
83
            // PK
84
            $pk = $this->schema->define($role, Schema::PRIMARY_KEY) ?? null;
85
            $output->write('   Primary key: ');
86
            $output->writeln($pk === null ? '<fg=red>no repository</>' : "<fg=cyan>{$pk}</>");
87
            // Fields
88
            $columns = $this->schema->define($role, Schema::COLUMNS);
89
            $output->writeln('   Fields: (entity.property -> db.field -> typecast)');
90
            $types = $this->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=cyan>{$field}</>");
94
                if ($typecast !== null) {
95
                    $output->write(" -> <fg=green>{$typecast}</>");
96
                }
97
                $output->writeln('');
98
            }
99
100
            // Relations
101
            $relations = $this->schema->define($role, Schema::RELATIONS);
102
            if (count($relations) > 0) {
103
                $output->writeln('   Relations:');
104
                foreach ($relations as $field => $relation) {
105
                    $type = $this->strRelations[$relation[Relation::TYPE] ?? ''] ?? '?';
106
                    $target = $relation[Relation::TARGET] ?? '?';
107
                    $loading = $this->strPreFetchMode[$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
                    // Many-To-Many relation(s) options
117
                    $mmInnerKey = $relSchema[Relation::THROUGH_INNER_KEY] ?? '?';
118
                    $mmOuterKey = $relSchema[Relation::THROUGH_OUTER_KEY] ?? '?';
119
                    $mmEntity = $relSchema[Relation::THROUGH_ENTITY] ?? null;
120
                    $mmWhere = $relSchema[Relation::THROUGH_WHERE] ?? [];
121
                    // print
122
                    $output->write("     <fg=cyan>{$field}</> {$type} <fg=cyan>{$target}</> {$loading} load");
123
                    $output->writeln(" <fg=yellow>{$cascadeStr}</>");
124
                    $output->write("       {$nullableStr} <fg=cyan>{$role}</>.<fg=cyan>{$innerKey}</> <=");
125
                    if ($mmEntity !== null) {
126
                        $output->write(" <fg=yellow>{$mmEntity}</>.<fg=yellow>{$mmInnerKey}</>");
127
                        $output->write("|");
128
                        $output->write("<fg=yellow>{$mmEntity}</>.<fg=yellow>{$mmOuterKey}</> ");
129
                    }
130
                    $output->writeln("=> <fg=cyan>{$target}</>.<fg=cyan>{$outerKey}</> ");
131
                    if (count($where)) {
132
                        $output->writeln("       Where: ");
133
                        $output->writeln('       ' . str_replace(["\r\n", "\n"], "\n       ", print_r($where, 1)));
134
                    }
135
                    if (count($mmWhere)) {
136
                        $output->writeln("       Through where: ");
137
                        $output->writeln('       ' . str_replace(["\r\n", "\n"], "\n       ", print_r($mmWhere, 1)));
138
                    }
139
                }
140
            } else {
141
                $output->writeln('   No relations');
142
            }
143
        }
144
145
        return ExitCode::OK;
146
    }
147
}
148