Failed Conditions
Pull Request — 2.10 (#3762)
by Benjamin
09:16
created

SchemaDiff   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 26
eloc 60
dl 0
loc 192
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

5 Methods

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