SchemaNormalizer::normalizeColumn()   F
last analyzed

Complexity

Conditions 14
Paths 6144

Size

Total Lines 46
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 29
c 1
b 0
f 0
nc 6144
nop 2
dl 0
loc 46
rs 2.1

How to fix   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
namespace TheCodingMachine\TDBM\SchemaVersionControl;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
7
use Doctrine\DBAL\Schema\Index;
8
use Doctrine\DBAL\Schema\Schema;
9
use Doctrine\DBAL\Schema\SchemaConfig;
10
use Doctrine\DBAL\Schema\Table;
11
12
/**
13
 * Database schema normalizer.
14
 *
15
 * Given an instance of Schema, it will construct a deep associative array to describe it. Such an array will then be
16
 * easy to serialize.
17
 */
18
class SchemaNormalizer
19
{
20
    protected Schema $schema;
21
    protected SchemaConfig $schemaConfig;
22
23
    /**
24
     * Normalize a Schema object into an array descriptor
25
     * @return array
26
     */
27
    public function normalize(Schema $schema, SchemaConfig $schemaConfig): array
28
    {
29
        $this->schema = $schema;
30
        $this->schemaConfig = $schemaConfig;
31
        $schemaDesc = [];
32
        if (!empty($this->schemaConfig->getDefaultTableOptions())) {
33
            $schemaDesc['default_table_options'] = $this->schemaConfig->getDefaultTableOptions();
34
        }
35
        $schemaDesc['tables'] = [];
36
        foreach ($schema->getTables() as $table) {
37
            $schemaDesc['tables'][$table->getName()] = $this->normalizeTable($table);
38
        }
39
        ksort($schemaDesc['tables']);
40
41
        return $schemaDesc;
42
    }
43
44
    protected function normalizeTable(Table $table)
45
    {
46
        $tableDesc = [];
47
48
        $primaryKey = $table->getPrimaryKey();
49
        if ($primaryKey) {
50
            $pk_columns = $primaryKey->getUnquotedColumns();
51
        } else {
52
            $pk_columns = [];
53
        }
54
55
        if ($table->hasOption('comment') && $table->getOption('comment')) {
56
            $tableDesc['comment'] = $table->getOption('comment');
57
        }
58
59
        // list columns
60
        foreach ($table->getColumns() as $columnName => $column) {
61
            $tableDesc['columns'][$column->getName()] = $this->normalizeColumn($column, in_array($column->getName(), $pk_columns));
62
        }
63
64
        // list indexes
65
        foreach ($table->getIndexes() as $index) {
66
            if (!$index->isPrimary()) {
67
                $tableDesc['indexes'][$index->getName()] = $this->normalizeIndex($index);
68
            }
69
        }
70
71
        // list foreign keys
72
        foreach ($table->getForeignKeys() as $foreignKey) {
73
            $tableDesc['foreign_keys'][$foreignKey->getName()] = $this->normalizeForeignKeyConstraint($foreignKey);
74
        }
75
76
        return $tableDesc;
77
    }
78
79
    protected function normalizeColumn(Column $column, bool $isPrimaryKey)
80
    {
81
        $columnDesc = [];
82
        if ($isPrimaryKey) {
83
            $columnDesc['primary_key'] = $isPrimaryKey;
84
        }
85
        $columnDesc['type'] = $column->getType()->getName();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Types\Type::getName() has been deprecated: this method will be removed in Doctrine DBAL 4.0, use {@see TypeRegistry::lookupName()} instead. ( Ignorable by Annotation )

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

85
        $columnDesc['type'] = /** @scrutinizer ignore-deprecated */ $column->getType()->getName();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
86
        if ($column->getUnsigned()) {
87
            $columnDesc['unsigned'] = $column->getUnsigned();
88
        }
89
        if ($column->getFixed()) {
90
            $columnDesc['fixed'] = $column->getFixed();
91
        }
92
        if ($column->getLength() !== null) {
93
            $columnDesc['length'] = $column->getLength();
94
        }
95
        if ($column->getPrecision() !== 10) {
96
            $columnDesc['precision'] = $column->getPrecision();
97
        }
98
        if ($column->getScale() !== 0) {
99
            $columnDesc['scale'] = $column->getScale();
100
        }
101
        if ($column->getNotnull()) {
102
            $columnDesc['not_null'] = $column->getNotnull();
103
        }
104
        if ($column->getDefault() !== null) {
105
            $columnDesc['default'] = $column->getDefault();
106
        }
107
        if ($column->getAutoincrement()) {
108
            $columnDesc['auto_increment'] = $column->getAutoincrement();
109
        }
110
        if ($column->getComment() !== null) {
111
            $columnDesc['comment'] = $column->getComment();
112
        }
113
        if (!empty($column->getPlatformOptions())) {
114
            $custom = array_diff_assoc($column->getPlatformOptions(), $this->schemaConfig->getDefaultTableOptions());
115
            if (!empty($custom)) {
116
                $columnDesc['custom'] = $custom;
117
            }
118
        }
119
120
        if (count($columnDesc) > 1) {
121
            return $columnDesc;
122
        }
123
124
        return $columnDesc['type'];
125
    }
126
127
    protected function normalizeForeignKeyConstraint(ForeignKeyConstraint $foreignKeyConstraint)
128
    {
129
        $constraintDesc = [];
130
        if (count($foreignKeyConstraint->getLocalColumns()) > 1) {
131
            $constraintDesc['columns'] = $foreignKeyConstraint->getLocalColumns();
132
        } else {
133
            $constraintDesc['column'] = $foreignKeyConstraint->getLocalColumns()[0];
134
        }
135
136
        $constraintDesc['references'] = $this->normalizeForeignReference($foreignKeyConstraint);
137
        if (!empty($foreignKeyConstraint->getOptions())) {
138
            $constraintDesc = array_merge($constraintDesc, $foreignKeyConstraint->getOptions());
139
        }
140
        return $constraintDesc;
141
    }
142
143
    protected function normalizeForeignReference(ForeignKeyConstraint $foreignKeyConstraint)
144
    {
145
        $referenceDesc = [];
146
        $foreignTableName = $foreignKeyConstraint->getForeignTableName();
147
        $foreignTable = $this->schema->getTable($foreignTableName);
148
        $foreignPrimaryKey = $foreignTable->getPrimaryKey();
149
        if ($foreignPrimaryKey && $foreignPrimaryKey->getColumns() == $foreignKeyConstraint->getForeignColumns()) {
150
            $referenceDesc = $foreignKeyConstraint->getForeignTableName();
151
        } else {
152
            $referenceDesc['table'] = $foreignKeyConstraint->getForeignTableName();
153
            $fkColumns = $foreignKeyConstraint->getForeignColumns();
154
            if (count($fkColumns) > 1) {
155
                $referenceDesc['columns'] = $fkColumns;
156
            } else {
157
                $referenceDesc['column'] = $fkColumns[0];
158
            }
159
        }
160
        return $referenceDesc;
161
    }
162
163
    protected function normalizeIndex(Index $index)
164
    {
165
        $indexDesc = [];
166
        $columns = $index->getColumns();
167
        if (count($columns) > 1) {
168
            $indexDesc['columns'] = $index->getColumns();
169
        } else {
170
            $indexDesc['column'] = $index->getColumns()[0];
171
        }
172
        if ($index->isUnique()) {
173
            $indexDesc['unique'] = $index->isUnique();
174
        }
175
        if ($index->isPrimary()) {
176
            $indexDesc['primary'] = $index->isPrimary();
177
        }
178
        if (!empty($index->getOptions())) {
179
            $indexDesc = array_merge($indexDesc, $index->getOptions());
180
        }
181
        return $indexDesc;
182
    }
183
}
184