1<?php 2 3namespace Doctrine\DBAL\Schema; 4 5use Doctrine\DBAL\Platforms\AbstractPlatform; 6use function array_merge; 7 8/** 9 * Schema Diff. 10 */ 11class SchemaDiff 12{ 13 /** @var Schema|null */ 14 public $fromSchema; 15 16 /** 17 * All added namespaces. 18 * 19 * @var string[] 20 */ 21 public $newNamespaces = []; 22 23 /** 24 * All removed namespaces. 25 * 26 * @var string[] 27 */ 28 public $removedNamespaces = []; 29 30 /** 31 * All added tables. 32 * 33 * @var Table[] 34 */ 35 public $newTables = []; 36 37 /** 38 * All changed tables. 39 * 40 * @var TableDiff[] 41 */ 42 public $changedTables = []; 43 44 /** 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 * Constructs an SchemaDiff object. 65 * 66 * @param Table[] $newTables 67 * @param TableDiff[] $changedTables 68 * @param Table[] $removedTables 69 */ 70 public function __construct($newTables = [], $changedTables = [], $removedTables = [], ?Schema $fromSchema = null) 71 { 72 $this->newTables = $newTables; 73 $this->changedTables = $changedTables; 74 $this->removedTables = $removedTables; 75 $this->fromSchema = $fromSchema; 76 } 77 78 /** 79 * The to save sql mode ensures that the following things don't happen: 80 * 81 * 1. Tables are deleted 82 * 2. Sequences are deleted 83 * 3. Foreign Keys which reference tables that would otherwise be deleted. 84 * 85 * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all. 86 * 87 * @return string[] 88 */ 89 public function toSaveSql(AbstractPlatform $platform) 90 { 91 return $this->_toSql($platform, true); 92 } 93 94 /** 95 * @return string[] 96 */ 97 public function toSql(AbstractPlatform $platform) 98 { 99 return $this->_toSql($platform, false); 100 } 101 102 /** 103 * @param bool $saveMode 104 * 105 * @return string[] 106 */ 107 protected function _toSql(AbstractPlatform $platform, $saveMode = false) 108 { 109 $sql = []; 110 111 if ($platform->supportsSchemas()) { 112 foreach ($this->newNamespaces as $newNamespace) { 113 $sql[] = $platform->getCreateSchemaSQL($newNamespace); 114 } 115 } 116 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 $sql = array_merge( 142 $sql, 143 $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES) 144 ); 145 146 if (! $platform->supportsForeignKeyConstraints()) { 147 continue; 148 } 149 150 foreach ($table->getForeignKeys() as $foreignKey) { 151 $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 return $sql; 167 } 168} 169