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