SchemaDiff.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace Doctrine\DBAL\Schema;
  3. use Doctrine\DBAL\Platforms\AbstractPlatform;
  4. use function array_merge;
  5. /**
  6. * Schema Diff.
  7. */
  8. class SchemaDiff
  9. {
  10. /** @var Schema|null */
  11. public $fromSchema;
  12. /**
  13. * All added namespaces.
  14. *
  15. * @var string[]
  16. */
  17. public $newNamespaces = [];
  18. /**
  19. * All removed namespaces.
  20. *
  21. * @var string[]
  22. */
  23. public $removedNamespaces = [];
  24. /**
  25. * All added tables.
  26. *
  27. * @var Table[]
  28. */
  29. public $newTables = [];
  30. /**
  31. * All changed tables.
  32. *
  33. * @var TableDiff[]
  34. */
  35. public $changedTables = [];
  36. /**
  37. * All removed tables.
  38. *
  39. * @var Table[]
  40. */
  41. public $removedTables = [];
  42. /** @var Sequence[] */
  43. public $newSequences = [];
  44. /** @var Sequence[] */
  45. public $changedSequences = [];
  46. /** @var Sequence[] */
  47. public $removedSequences = [];
  48. /** @var ForeignKeyConstraint[] */
  49. public $orphanedForeignKeys = [];
  50. /**
  51. * Constructs an SchemaDiff object.
  52. *
  53. * @param Table[] $newTables
  54. * @param TableDiff[] $changedTables
  55. * @param Table[] $removedTables
  56. */
  57. public function __construct($newTables = [], $changedTables = [], $removedTables = [], ?Schema $fromSchema = null)
  58. {
  59. $this->newTables = $newTables;
  60. $this->changedTables = $changedTables;
  61. $this->removedTables = $removedTables;
  62. $this->fromSchema = $fromSchema;
  63. }
  64. /**
  65. * The to save sql mode ensures that the following things don't happen:
  66. *
  67. * 1. Tables are deleted
  68. * 2. Sequences are deleted
  69. * 3. Foreign Keys which reference tables that would otherwise be deleted.
  70. *
  71. * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all.
  72. *
  73. * @return string[]
  74. */
  75. public function toSaveSql(AbstractPlatform $platform)
  76. {
  77. return $this->_toSql($platform, true);
  78. }
  79. /**
  80. * @return string[]
  81. */
  82. public function toSql(AbstractPlatform $platform)
  83. {
  84. return $this->_toSql($platform, false);
  85. }
  86. /**
  87. * @param bool $saveMode
  88. *
  89. * @return string[]
  90. */
  91. protected function _toSql(AbstractPlatform $platform, $saveMode = false)
  92. {
  93. $sql = [];
  94. if ($platform->supportsSchemas()) {
  95. foreach ($this->newNamespaces as $newNamespace) {
  96. $sql[] = $platform->getCreateSchemaSQL($newNamespace);
  97. }
  98. }
  99. if ($platform->supportsForeignKeyConstraints() && $saveMode === false) {
  100. foreach ($this->orphanedForeignKeys as $orphanedForeignKey) {
  101. $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable());
  102. }
  103. }
  104. if ($platform->supportsSequences() === true) {
  105. foreach ($this->changedSequences as $sequence) {
  106. $sql[] = $platform->getAlterSequenceSQL($sequence);
  107. }
  108. if ($saveMode === false) {
  109. foreach ($this->removedSequences as $sequence) {
  110. $sql[] = $platform->getDropSequenceSQL($sequence);
  111. }
  112. }
  113. foreach ($this->newSequences as $sequence) {
  114. $sql[] = $platform->getCreateSequenceSQL($sequence);
  115. }
  116. }
  117. $foreignKeySql = [];
  118. foreach ($this->newTables as $table) {
  119. $sql = array_merge(
  120. $sql,
  121. $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES)
  122. );
  123. if (! $platform->supportsForeignKeyConstraints()) {
  124. continue;
  125. }
  126. foreach ($table->getForeignKeys() as $foreignKey) {
  127. $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table);
  128. }
  129. }
  130. $sql = array_merge($sql, $foreignKeySql);
  131. if ($saveMode === false) {
  132. foreach ($this->removedTables as $table) {
  133. $sql[] = $platform->getDropTableSQL($table);
  134. }
  135. }
  136. foreach ($this->changedTables as $tableDiff) {
  137. $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff));
  138. }
  139. return $sql;
  140. }
  141. }