SchemaDiff.php 4.2 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\DBAL\Schema;

5
use Doctrine\DBAL\Platforms\AbstractPlatform;
6
use function array_merge;
7

8
/**
Benjamin Morel's avatar
Benjamin Morel committed
9
 * Schema Diff.
10 11 12
 */
class SchemaDiff
{
13
    /** @var Schema */
14 15
    public $fromSchema;

Marco Pivetta's avatar
Marco Pivetta committed
16 17 18 19 20
    /**
     * All added namespaces.
     *
     * @var string[]
     */
21
    public $newNamespaces = [];
Marco Pivetta's avatar
Marco Pivetta committed
22

23 24 25 26 27
    /**
     * All removed namespaces.
     *
     * @var string[]
     */
28
    public $removedNamespaces = [];
29

30
    /**
Benjamin Morel's avatar
Benjamin Morel committed
31
     * All added tables.
32
     *
33
     * @var Table[]
34
     */
35
    public $newTables = [];
36 37

    /**
Benjamin Morel's avatar
Benjamin Morel committed
38
     * All changed tables.
39
     *
40
     * @var TableDiff[]
41
     */
42
    public $changedTables = [];
43 44

    /**
Benjamin Morel's avatar
Benjamin Morel committed
45
     * All removed tables.
46
     *
47
     * @var Table[]
48
     */
49
    public $removedTables = [];
50

51
    /** @var Sequence[] */
52
    public $newSequences = [];
53

54
    /** @var Sequence[] */
55
    public $changedSequences = [];
56

57
    /** @var Sequence[] */
58
    public $removedSequences = [];
59

60
    /** @var ForeignKeyConstraint[] */
61
    public $orphanedForeignKeys = [];
62

63 64 65
    /**
     * Constructs an SchemaDiff object.
     *
66 67 68
     * @param Table[]     $newTables
     * @param TableDiff[] $changedTables
     * @param Table[]     $removedTables
69
     */
70
    public function __construct($newTables = [], $changedTables = [], $removedTables = [], ?Schema $fromSchema = null)
71
    {
Benjamin Morel's avatar
Benjamin Morel committed
72
        $this->newTables     = $newTables;
73 74
        $this->changedTables = $changedTables;
        $this->removedTables = $removedTables;
Benjamin Morel's avatar
Benjamin Morel committed
75
        $this->fromSchema    = $fromSchema;
76
    }
77 78

    /**
79 80 81 82 83 84 85 86
     * The to save sql mode ensures that the following things don't happen:
     *
     * 1. Tables are deleted
     * 2. Sequences are deleted
     * 3. Foreign Keys which reference tables that would otherwise be deleted.
     *
     * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all.
     *
87
     * @return string[]
88 89 90 91 92 93 94
     */
    public function toSaveSql(AbstractPlatform $platform)
    {
        return $this->_toSql($platform, true);
    }

    /**
95
     * @return string[]
96 97
     */
    public function toSql(AbstractPlatform $platform)
98 99 100 101 102
    {
        return $this->_toSql($platform, false);
    }

    /**
103
     * @param bool $saveMode
Benjamin Morel's avatar
Benjamin Morel committed
104
     *
105
     * @return string[]
106 107
     */
    protected function _toSql(AbstractPlatform $platform, $saveMode = false)
108
    {
109
        $sql = [];
110

Marco Pivetta's avatar
Marco Pivetta committed
111 112 113 114 115 116
        if ($platform->supportsSchemas()) {
            foreach ($this->newNamespaces as $newNamespace) {
                $sql[] = $platform->getCreateSchemaSQL($newNamespace);
            }
        }

117
        if ($platform->supportsForeignKeyConstraints() && $saveMode === false) {
118
            foreach ($this->orphanedForeignKeys as $orphanedForeignKey) {
119
                $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable());
120 121 122
            }
        }

123
        if ($platform->supportsSequences() === true) {
124
            foreach ($this->changedSequences as $sequence) {
125
                $sql[] = $platform->getAlterSequenceSQL($sequence);
126 127
            }

128
            if ($saveMode === false) {
129
                foreach ($this->removedSequences as $sequence) {
130
                    $sql[] = $platform->getDropSequenceSQL($sequence);
131
                }
132 133
            }

134
            foreach ($this->newSequences as $sequence) {
135
                $sql[] = $platform->getCreateSequenceSQL($sequence);
136 137 138
            }
        }

139
        $foreignKeySql = [];
140
        foreach ($this->newTables as $table) {
141 142
            $sql = array_merge(
                $sql,
143
                $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
144
            );
145

146 147 148 149 150 151
            if (! $platform->supportsForeignKeyConstraints()) {
                continue;
            }

            foreach ($table->getForeignKeys() as $foreignKey) {
                $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
152
            }
153
        }
154
        $sql = array_merge($sql, $foreignKeySql);
155

156
        if ($saveMode === false) {
157
            foreach ($this->removedTables as $table) {
158
                $sql[] = $platform->getDropTableSQL($table);
159
            }
160 161
        }

162
        foreach ($this->changedTables as $tableDiff) {
163
            $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
164 165 166 167
        }

        return $sql;
    }
168
}