SchemaDiff::_toSql()   F
last analyzed

Complexity

Conditions 18
Paths 288

Size

Total Lines 64
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 18

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 64
ccs 33
cts 33
cp 1
rs 2.9333
c 0
b 0
f 0
cc 18
nc 288
nop 2
crap 18

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 Doctrine\DBAL\Schema;
6
7
use Doctrine\DBAL\Internal\DependencyOrderCalculator;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use function array_merge;
10
11
/**
12
 * Schema Diff.
13
 */
14
class SchemaDiff
15
{
16
    /** @var Schema|null */
17
    public $fromSchema;
18
19
    /**
20
     * All added namespaces.
21
     *
22
     * @var array<string, string>
23
     */
24
    public $newNamespaces = [];
25
26
    /**
27
     * All removed namespaces.
28
     *
29
     * @var array<string, string>
30
     */
31
    public $removedNamespaces = [];
32
33
    /**
34
     * All added tables.
35
     *
36
     * @var array<string, Table>
37
     */
38
    public $newTables = [];
39
40
    /**
41
     * All changed tables.
42
     *
43
     * @var array<string, TableDiff>
44
     */
45
    public $changedTables = [];
46
47
    /**
48
     * All removed tables.
49
     *
50
     * @var array<string, Table>
51
     */
52
    public $removedTables = [];
53
54
    /** @var array<int, Sequence> */
55
    public $newSequences = [];
56
57
    /** @var array<int, Sequence> */
58
    public $changedSequences = [];
59
60
    /** @var array<int, Sequence> */
61
    public $removedSequences = [];
62
63
    /** @var array<string|int, ForeignKeyConstraint> */
64
    public $orphanedForeignKeys = [];
65
66
    /**
67
     * Constructs an SchemaDiff object.
68
     *
69
     * @param array<string, Table>     $newTables
70
     * @param array<string, TableDiff> $changedTables
71
     * @param array<string, Table>     $removedTables
72
     */
73 691
    public function __construct(array $newTables = [], array $changedTables = [], array $removedTables = [], ?Schema $fromSchema = null)
74
    {
75 691
        $this->newTables     = $newTables;
76 691
        $this->changedTables = $changedTables;
77 691
        $this->removedTables = $removedTables;
78 691
        $this->fromSchema    = $fromSchema;
79 691
    }
80
81
    /**
82
     * The to save sql mode ensures that the following things don't happen:
83
     *
84
     * 1. Tables are deleted
85
     * 2. Sequences are deleted
86
     * 3. Foreign Keys which reference tables that would otherwise be deleted.
87
     *
88
     * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all.
89
     *
90
     * @return array<int, string>
91
     */
92 22
    public function toSaveSql(AbstractPlatform $platform) : array
93
    {
94 22
        return $this->_toSql($platform, true);
95
    }
96
97
    /**
98
     * @return array<int, string>
99
     */
100 97
    public function toSql(AbstractPlatform $platform) : array
101
    {
102 97
        return $this->_toSql($platform, false);
103
    }
104
105
    /**
106
     * @return array<int, string>
107
     */
108 119
    protected function _toSql(AbstractPlatform $platform, bool $saveMode = false) : array
109
    {
110 119
        $sql = [];
111
112 119
        if ($platform->supportsSchemas()) {
113 58
            foreach ($this->newNamespaces as $newNamespace) {
114 51
                $sql[] = $platform->getCreateSchemaSQL($newNamespace);
115
            }
116
        }
117
118 119
        if ($platform->supportsForeignKeyConstraints() && $saveMode === false) {
119 97
            foreach ($this->orphanedForeignKeys as $orphanedForeignKey) {
120 22
                $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable());
121
            }
122
        }
123
124 119
        if ($platform->supportsSequences()) {
125 59
            foreach ($this->changedSequences as $sequence) {
126 44
                $sql[] = $platform->getAlterSequenceSQL($sequence);
127
            }
128
129 59
            if ($saveMode === false) {
130 37
                foreach ($this->removedSequences as $sequence) {
131 22
                    $sql[] = $platform->getDropSequenceSQL($sequence);
132
                }
133
            }
134
135 59
            foreach ($this->newSequences as $sequence) {
136 44
                $sql[] = $platform->getCreateSequenceSQL($sequence);
137
            }
138
        }
139
140 119
        $foreignKeySql = [];
141 119
        $createFlags   = AbstractPlatform::CREATE_INDEXES;
142
143 119
        if (! $platform->supportsCreateDropForeignKeyConstraints()) {
144 23
            $createFlags |= AbstractPlatform::CREATE_FOREIGNKEYS;
145
        }
146
147 119
        foreach ($this->getNewTablesSortedByDependencies() as $table) {
148 88
            $sql = array_merge($sql, $platform->getCreateTableSQL($table, $createFlags));
149
150 88
            if (! $platform->supportsCreateDropForeignKeyConstraints()) {
151 23
                continue;
152
            }
153
154 65
            foreach ($table->getForeignKeys() as $foreignKey) {
155 65
                $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
156
            }
157
        }
158
159 119
        $sql = array_merge($sql, $foreignKeySql);
160
161 119
        if ($saveMode === false) {
162 97
            foreach ($this->removedTables as $table) {
163 22
                $sql[] = $platform->getDropTableSQL($table);
164
            }
165
        }
166
167 119
        foreach ($this->changedTables as $tableDiff) {
168 68
            $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
169
        }
170
171 119
        return $sql;
172
    }
173
174
    /**
175
     * Sorts tables by dependencies so that they are created in the right order.
176
     *
177
     * This is necessary when one table depends on another while creating foreign key
178
     * constraints directly during CREATE TABLE.
179
     *
180
     * @return array<Table>
181
     */
182 119
    private function getNewTablesSortedByDependencies()
183
    {
184 119
        $calculator = new DependencyOrderCalculator();
185 119
        $newTables  = [];
186
187 119
        foreach ($this->newTables as $table) {
188 88
            $newTables[$table->getName()] = true;
189 88
            $calculator->addNode($table->getName(), $table);
190
        }
191
192 119
        foreach ($this->newTables as $table) {
193 88
            foreach ($table->getForeignKeys() as $foreignKey) {
194 66
                $foreignTableName = $foreignKey->getForeignTableName();
195
196 66
                if (! isset($newTables[$foreignTableName])) {
197 44
                    continue;
198
                }
199
200 22
                $calculator->addDependency($foreignTableName, $table->getName());
201
            }
202
        }
203
204 119
        return $calculator->sort();
205
    }
206
}
207