SchemaDiff.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Setup\Declaration\Schema\Diff;
  7. use Magento\Framework\Setup\Declaration\Schema\Dto\Schema;
  8. use Magento\Framework\Setup\Declaration\Schema\OperationsExecutor;
  9. /**
  10. * Aggregation root of all diffs.
  11. * Loop through all tables and find difference between them.
  12. *
  13. * If table exists only in XML -> then we need to create table.
  14. * If table exists in both version -> then we need to go deeper and inspect each element.
  15. * If table exists only in db -> then we need to remove this table.
  16. */
  17. class SchemaDiff
  18. {
  19. /**
  20. * @var TableDiff
  21. */
  22. private $tableDiff;
  23. /**
  24. * @var DiffManager
  25. */
  26. private $diffManager;
  27. /**
  28. * @var DiffFactory
  29. */
  30. private $diffFactory;
  31. /**
  32. * @var OperationsExecutor
  33. */
  34. private $operationsExecutor;
  35. /**
  36. * Constructor.
  37. *
  38. * @param DiffManager $diffManager
  39. * @param TableDiff $tableDiff
  40. * @param DiffFactory $diffFactory
  41. * @param OperationsExecutor $operationsExecutor
  42. */
  43. public function __construct(
  44. DiffManager $diffManager,
  45. TableDiff $tableDiff,
  46. DiffFactory $diffFactory,
  47. OperationsExecutor $operationsExecutor
  48. ) {
  49. $this->tableDiff = $tableDiff;
  50. $this->diffManager = $diffManager;
  51. $this->diffFactory = $diffFactory;
  52. $this->operationsExecutor = $operationsExecutor;
  53. }
  54. /**
  55. * Create consistent table index from all tables
  56. *
  57. * All declared table names should have order, all tables exists only in db should goes after them
  58. *
  59. * @param array $tableNames
  60. * @param array $generatedTableNames
  61. * @return array
  62. */
  63. private function createTableIndex(array $tableNames, array $generatedTableNames)
  64. {
  65. foreach ($generatedTableNames as $tableName) {
  66. //If table exists only in db
  67. if (!in_array($tableName, $tableNames)) {
  68. $tableNames[] = $tableName;
  69. }
  70. }
  71. return array_flip($tableNames);
  72. }
  73. /**
  74. * Create diff.
  75. *
  76. * @param Schema $schema
  77. * @param Schema $generatedSchema
  78. * @return Diff
  79. */
  80. public function diff(
  81. Schema $schema,
  82. Schema $generatedSchema
  83. ) {
  84. $generatedTables = $generatedSchema->getTables();
  85. $tableNames = array_keys($schema->getTables());
  86. $generatedTableNames = array_keys($generatedSchema->getTables());
  87. $diff = $this->diffFactory->create(
  88. [
  89. 'tableIndexes' => $this->createTableIndex($tableNames, $generatedTableNames),
  90. 'destructiveOperations' => $this->operationsExecutor->getDestructiveOperations()
  91. ]
  92. );
  93. foreach ($schema->getTables() as $name => $table) {
  94. if ($this->diffManager->shouldBeCreated($generatedTables, $table)) {
  95. $diff = $this->diffManager->registerCreation($diff, $table);
  96. } else {
  97. $diff = $this->tableDiff->diff($table, $generatedTables[$name], $diff);
  98. }
  99. unset($generatedTables[$name]);
  100. }
  101. //Removal process
  102. if ($this->diffManager->shouldBeRemoved($generatedTables)) {
  103. $diff = $this->diffManager->registerRemoval($diff, $generatedTables);
  104. }
  105. return $diff;
  106. }
  107. }