SchemaDiff.php 5.6 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;

40
    /**
Benjamin Morel's avatar
Benjamin Morel committed
41
     * All added tables.
42
     *
Benjamin Morel's avatar
Benjamin Morel committed
43
     * @var \Doctrine\DBAL\Schema\Table[]
44
     */
45
    public $newTables = array();
46 47

    /**
Benjamin Morel's avatar
Benjamin Morel committed
48
     * All changed tables.
49
     *
Benjamin Morel's avatar
Benjamin Morel committed
50
     * @var \Doctrine\DBAL\Schema\TableDiff[]
51
     */
52
    public $changedTables = array();
53 54

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

    /**
Benjamin Morel's avatar
Benjamin Morel committed
62
     * @var \Doctrine\DBAL\Schema\Sequence[]
63 64 65 66
     */
    public $newSequences = array();

    /**
Benjamin Morel's avatar
Benjamin Morel committed
67
     * @var \Doctrine\DBAL\Schema\Sequence[]
68 69 70 71
     */
    public $changedSequences = array();

    /**
Benjamin Morel's avatar
Benjamin Morel committed
72
     * @var \Doctrine\DBAL\Schema\Sequence[]
73 74
     */
    public $removedSequences = array();
75

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

81 82 83
    /**
     * Constructs an SchemaDiff object.
     *
Benjamin Morel's avatar
Benjamin Morel committed
84 85 86 87
     * @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
88
     */
89
    public function __construct($newTables = array(), $changedTables = array(), $removedTables = array(), Schema $fromSchema = null)
90
    {
Benjamin Morel's avatar
Benjamin Morel committed
91
        $this->newTables     = $newTables;
92 93
        $this->changedTables = $changedTables;
        $this->removedTables = $removedTables;
Benjamin Morel's avatar
Benjamin Morel committed
94
        $this->fromSchema    = $fromSchema;
95
    }
96 97

    /**
98 99 100 101 102 103 104 105
     * 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
106 107
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     *
108 109 110 111 112 113 114 115
     * @return array
     */
    public function toSaveSql(AbstractPlatform $platform)
    {
        return $this->_toSql($platform, true);
    }

    /**
Benjamin Morel's avatar
Benjamin Morel committed
116 117
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     *
118 119 120
     * @return array
     */
    public function toSql(AbstractPlatform $platform)
121 122 123 124 125
    {
        return $this->_toSql($platform, false);
    }

    /**
Benjamin Morel's avatar
Benjamin Morel committed
126 127 128
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
     * @param boolean                                   $saveMode
     *
129 130 131
     * @return array
     */
    protected function _toSql(AbstractPlatform $platform, $saveMode = false)
132 133 134
    {
        $sql = array();

135
        if ($platform->supportsForeignKeyConstraints() && $saveMode == false) {
136
            foreach ($this->orphanedForeignKeys as $orphanedForeignKey) {
137
                $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTableName());
138 139 140
            }
        }

141
        if ($platform->supportsSequences() == true) {
142
            foreach ($this->changedSequences as $sequence) {
143
                $sql[] = $platform->getAlterSequenceSQL($sequence);
144 145
            }

146
            if ($saveMode === false) {
147
                foreach ($this->removedSequences as $sequence) {
148
                    $sql[] = $platform->getDropSequenceSQL($sequence);
149
                }
150 151
            }

152
            foreach ($this->newSequences as $sequence) {
153
                $sql[] = $platform->getCreateSequenceSQL($sequence);
154 155 156
            }
        }

157
        $foreignKeySql = array();
158
        foreach ($this->newTables as $table) {
159 160
            $sql = array_merge(
                $sql,
161
                $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
162
            );
163 164

            if ($platform->supportsForeignKeyConstraints()) {
165
                foreach ($table->getForeignKeys() as $foreignKey) {
166 167
                    $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
                }
168
            }
169
        }
170
        $sql = array_merge($sql, $foreignKeySql);
171

172
        if ($saveMode === false) {
173
            foreach ($this->removedTables as $table) {
174
                $sql[] = $platform->getDropTableSQL($table);
175
            }
176 177
        }

178
        foreach ($this->changedTables as $tableDiff) {
179
            $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
180 181 182 183
        }

        return $sql;
    }
184
}