SchemaDiff.php 6.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
Benjamin Eberlei's avatar
Benjamin Eberlei committed
16
 * and is licensed under the MIT license. For more information, see
17 18 19 20 21
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\DBAL\Schema;

22 23
use \Doctrine\DBAL\Platforms\AbstractPlatform;

24
/**
Benjamin Morel's avatar
Benjamin Morel committed
25
 * Schema Diff.
26
 *
Benjamin Morel's avatar
Benjamin Morel committed
27
 * @link      www.doctrine-project.org
28
 * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
Benjamin Morel's avatar
Benjamin Morel committed
29 30 31
 * @license   http://ez.no/licenses/new_bsd New BSD License
 * @since     2.0
 * @author    Benjamin Eberlei <kontakt@beberlei.de>
32 33 34
 */
class SchemaDiff
{
35
    /**
Benjamin Morel's avatar
Benjamin Morel committed
36
     * @var \Doctrine\DBAL\Schema\Schema
37 38 39
     */
    public $fromSchema;

Marco Pivetta's avatar
Marco Pivetta committed
40 41 42 43 44 45 46
    /**
     * All added namespaces.
     *
     * @var string[]
     */
    public $newNamespaces = array();

47 48 49 50 51 52 53
    /**
     * All removed namespaces.
     *
     * @var string[]
     */
    public $removedNamespaces = array();

54
    /**
Benjamin Morel's avatar
Benjamin Morel committed
55
     * All added tables.
56
     *
Benjamin Morel's avatar
Benjamin Morel committed
57
     * @var \Doctrine\DBAL\Schema\Table[]
58
     */
59
    public $newTables = array();
60 61

    /**
Benjamin Morel's avatar
Benjamin Morel committed
62
     * All changed tables.
63
     *
Benjamin Morel's avatar
Benjamin Morel committed
64
     * @var \Doctrine\DBAL\Schema\TableDiff[]
65
     */
66
    public $changedTables = array();
67 68

    /**
Benjamin Morel's avatar
Benjamin Morel committed
69
     * All removed tables.
70
     *
Benjamin Morel's avatar
Benjamin Morel committed
71
     * @var \Doctrine\DBAL\Schema\Table[]
72
     */
73 74 75
    public $removedTables = array();

    /**
Benjamin Morel's avatar
Benjamin Morel committed
76
     * @var \Doctrine\DBAL\Schema\Sequence[]
77 78 79 80
     */
    public $newSequences = array();

    /**
Benjamin Morel's avatar
Benjamin Morel committed
81
     * @var \Doctrine\DBAL\Schema\Sequence[]
82 83 84 85
     */
    public $changedSequences = array();

    /**
Benjamin Morel's avatar
Benjamin Morel committed
86
     * @var \Doctrine\DBAL\Schema\Sequence[]
87 88
     */
    public $removedSequences = array();
89

90
    /**
Benjamin Morel's avatar
Benjamin Morel committed
91
     * @var \Doctrine\DBAL\Schema\ForeignKeyConstraint[]
92 93 94
     */
    public $orphanedForeignKeys = array();

95 96 97
    /**
     * Constructs an SchemaDiff object.
     *
Benjamin Morel's avatar
Benjamin Morel committed
98 99 100 101
     * @param \Doctrine\DBAL\Schema\Table[]     $newTables
     * @param \Doctrine\DBAL\Schema\TableDiff[] $changedTables
     * @param \Doctrine\DBAL\Schema\Table[]     $removedTables
     * @param \Doctrine\DBAL\Schema\Schema|null $fromSchema
102
     */
103
    public function __construct($newTables = array(), $changedTables = array(), $removedTables = array(), Schema $fromSchema = null)
104
    {
Benjamin Morel's avatar
Benjamin Morel committed
105
        $this->newTables     = $newTables;
106 107
        $this->changedTables = $changedTables;
        $this->removedTables = $removedTables;
Benjamin Morel's avatar
Benjamin Morel committed
108
        $this->fromSchema    = $fromSchema;
109
    }
110 111

    /**
112 113 114 115 116 117 118 119
     * 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.
     *
Benjamin Morel's avatar
Benjamin Morel committed
120 121
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     *
122 123 124 125 126 127 128 129
     * @return array
     */
    public function toSaveSql(AbstractPlatform $platform)
    {
        return $this->_toSql($platform, true);
    }

    /**
Benjamin Morel's avatar
Benjamin Morel committed
130 131
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     *
132 133 134
     * @return array
     */
    public function toSql(AbstractPlatform $platform)
135 136 137 138 139
    {
        return $this->_toSql($platform, false);
    }

    /**
Benjamin Morel's avatar
Benjamin Morel committed
140 141 142
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     * @param boolean                                   $saveMode
     *
143 144 145
     * @return array
     */
    protected function _toSql(AbstractPlatform $platform, $saveMode = false)
146 147 148
    {
        $sql = array();

Marco Pivetta's avatar
Marco Pivetta committed
149 150 151 152 153 154
        if ($platform->supportsSchemas()) {
            foreach ($this->newNamespaces as $newNamespace) {
                $sql[] = $platform->getCreateSchemaSQL($newNamespace);
            }
        }

155
        if ($platform->supportsForeignKeyConstraints() && $saveMode == false) {
156
            foreach ($this->orphanedForeignKeys as $orphanedForeignKey) {
157
                $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable());
158 159 160
            }
        }

161
        if ($platform->supportsSequences() == true) {
162
            foreach ($this->changedSequences as $sequence) {
163
                $sql[] = $platform->getAlterSequenceSQL($sequence);
164 165
            }

166
            if ($saveMode === false) {
167
                foreach ($this->removedSequences as $sequence) {
168
                    $sql[] = $platform->getDropSequenceSQL($sequence);
169
                }
170 171
            }

172
            foreach ($this->newSequences as $sequence) {
173
                $sql[] = $platform->getCreateSequenceSQL($sequence);
174 175 176
            }
        }

177
        $foreignKeySql = array();
178
        foreach ($this->newTables as $table) {
179 180
            $sql = array_merge(
                $sql,
181
                $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
182
            );
183 184

            if ($platform->supportsForeignKeyConstraints()) {
185
                foreach ($table->getForeignKeys() as $foreignKey) {
186 187
                    $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
                }
188
            }
189
        }
190
        $sql = array_merge($sql, $foreignKeySql);
191

192
        if ($saveMode === false) {
193
            foreach ($this->removedTables as $table) {
194
                $sql[] = $platform->getDropTableSQL($table);
195
            }
196 197
        }

198
        foreach ($this->changedTables as $tableDiff) {
199
            $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
200 201 202 203
        }

        return $sql;
    }
204
}