Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
SchemaBuilder.php
Go to the documentation of this file.
1 <?php
8 
16 
29 {
33  private $elementFactory;
34 
38  private $dbSchemaReader;
39 
43  private $sharding;
44 
48  private $tables;
49 
57  public function __construct(
58  ElementFactory $elementFactory,
59  DbSchemaReaderInterface $dbSchemaReader,
60  Sharding $sharding
61  ) {
62  $this->elementFactory = $elementFactory;
63  $this->dbSchemaReader = $dbSchemaReader;
64  $this->sharding = $sharding;
65  }
66 
70  public function build(Schema $schema)
71  {
72  foreach ($this->sharding->getResources() as $resource) {
73  foreach ($this->dbSchemaReader->readTables($resource) as $tableName) {
74  $columns = [];
75  $indexes = [];
76  $constraints = [];
77 
78  $tableOptions = $this->dbSchemaReader->getTableOptions($tableName, $resource);
79  $columnsData = $this->dbSchemaReader->readColumns($tableName, $resource);
80  $indexesData = $this->dbSchemaReader->readIndexes($tableName, $resource);
81  $constrainsData = $this->dbSchemaReader->readConstraints($tableName, $resource);
82 
86  $table = $this->elementFactory->create(
87  'table',
88  [
89  'name' => $tableName,
90  'resource' => $resource,
91  'engine' => strtolower($tableOptions['engine']),
92  'comment' => $tableOptions['comment'] === '' ? null : $tableOptions['comment'],
93  'charset' => $tableOptions['charset'],
94  'collation' => $tableOptions['collation']
95  ]
96  );
97 
98  // Process columns
99  foreach ($columnsData as $columnData) {
100  $columnData['table'] = $table;
101  $column = $this->elementFactory->create($columnData['type'], $columnData);
102  $columns[$column->getName()] = $column;
103  }
104 
105  $table->addColumns($columns);
106  //Process indexes
107  foreach ($indexesData as $indexData) {
108  $indexData['table'] = $table;
109  $indexData['columns'] = $this->resolveInternalRelations($columns, $indexData);
110  $index = $this->elementFactory->create('index', $indexData);
111  $indexes[$index->getName()] = $index;
112  }
113  //Process internal constraints
114  foreach ($constrainsData as $constraintData) {
115  $constraintData['table'] = $table;
116  $constraintData['columns'] = $this->resolveInternalRelations($columns, $constraintData);
117  $constraint = $this->elementFactory->create($constraintData['type'], $constraintData);
118  $constraints[$constraint->getName()] = $constraint;
119  }
120 
121  $table->addIndexes($indexes);
122  $table->addConstraints($constraints);
123  $this->tables[$table->getName()] = $table;
124  }
125  }
126 
127  $this->processReferenceKeys($this->tables, $schema);
128  return $schema;
129  }
130 
137  private function processReferenceKeys(array $tables, Schema $schema)
138  {
139  foreach ($tables as $table) {
140  $tableName = $table->getName();
141  if ($schema->getTableByName($tableName) instanceof Table) {
142  continue;
143  }
144  $referencesData = $this->dbSchemaReader->readReferences($tableName, $table->getResource());
145  $references = [];
146 
147  foreach ($referencesData as $referenceData) {
148  //Prepare reference data
149  $referenceData['table'] = $table;
150  $referenceTableName = $referenceData['referenceTable'];
151  $referenceData['column'] = $table->getColumnByName($referenceData['column']);
152  $referenceData['referenceTable'] = $this->tables[$referenceTableName];
153  $referenceData['referenceColumn'] = $referenceData['referenceTable']->getColumnByName(
154  $referenceData['referenceColumn']
155  );
156 
157  $references[$referenceData['name']] = $this->elementFactory->create('foreign', $referenceData);
158  //We need to instantiate tables in order of references tree
159  if (isset($tables[$referenceTableName]) && $referenceTableName !== $tableName) {
160  $this->processReferenceKeys([$referenceTableName => $tables[$referenceTableName]], $schema);
161  unset($tables[$referenceTableName]);
162  }
163  }
164 
165  $table->addConstraints($references);
166  $schema->addTable($table);
167  }
168  }
169 
178  private function resolveInternalRelations(array $columns, array $data)
179  {
180  if (!is_array($data['column'])) {
181  throw new Exception(
182  new Phrase("Cannot find columns for internal index")
183  );
184  }
185 
186  $referenceColumns = [];
187  foreach ($data['column'] as $columnName) {
188  if (!isset($columns[$columnName])) {
189  $tableName = isset($data['table']) ? $data['table']->getName() : '';
190  trigger_error(
191  new Phrase(
192  'Column %1 does not exist for index/constraint %2 in table %3.',
193  [
194  $columnName,
195  $data['name'],
196  $tableName
197  ]
198  ),
199  E_USER_WARNING
200  );
201  } else {
202  $referenceColumns[] = $columns[$columnName];
203  }
204  }
205 
206  return $referenceColumns;
207  }
208 }
$tableName
Definition: trigger.php:13
$resource
Definition: bulk.php:12
$columns
Definition: default.phtml:15
__construct(ElementFactory $elementFactory, DbSchemaReaderInterface $dbSchemaReader, Sharding $sharding)
$table
Definition: trigger.php:14
$index
Definition: list.phtml:44