Skip to content

Commit bca0e5e

Browse files
committed
MAGETWO-95595: Index names are ignored by declarative schema
1 parent 6eefa51 commit bca0e5e

File tree

10 files changed

+569
-275
lines changed

10 files changed

+569
-275
lines changed

app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php

Lines changed: 11 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,9 @@
77

88
namespace Magento\Developer\Console\Command;
99

10-
use Magento\Framework\Component\ComponentRegistrar;
10+
use Magento\Developer\Model\Setup\Declaration\Schema\WhitelistGenerator;
1111
use Magento\Framework\Config\FileResolverByModule;
12-
use Magento\Framework\Module\Dir;
13-
use Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder;
14-
use Magento\Framework\Setup\Declaration\Schema\Diff\Diff;
15-
use Magento\Framework\Setup\Declaration\Schema\Dto\Schema;
16-
use Magento\Framework\Setup\Declaration\Schema\Dto\SchemaFactory;
17-
use Magento\Framework\Setup\JsonPersistor;
18-
use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite;
12+
use Magento\Framework\Exception\ConfigurationMismatchException;
1913
use Symfony\Component\Console\Command\Command;
2014
use Symfony\Component\Console\Input\InputInterface;
2115
use Symfony\Component\Console\Input\InputOption;
@@ -34,57 +28,20 @@ class TablesWhitelistGenerateCommand extends Command
3428
const MODULE_NAME_KEY = 'module-name';
3529

3630
/**
37-
* @var ComponentRegistrar
31+
* @var WhitelistGenerator
3832
*/
39-
private $componentRegistrar;
33+
private $whitelistGenerator;
4034

4135
/**
42-
* @var ReaderComposite
43-
*/
44-
private $readerComposite;
45-
46-
/**
47-
* @var JsonPersistor
48-
*/
49-
private $jsonPersistor;
50-
51-
/**
52-
* @var array
53-
*/
54-
private $primaryDbSchema;
55-
56-
/**
57-
* @var SchemaFactory
58-
*/
59-
private $schemaFactory;
60-
61-
/**
62-
* @var SchemaBuilder
63-
*/
64-
private $schemaBuilder;
65-
66-
/**
67-
* @param ComponentRegistrar $componentRegistrar
68-
* @param ReaderComposite $readerComposite
69-
* @param JsonPersistor $jsonPersistor
70-
* @param SchemaFactory $schemaFactory
71-
* @param SchemaBuilder $schemaBuilder
36+
* @param WhitelistGenerator $whitelistGenerator
7237
* @param string|null $name
7338
*/
7439
public function __construct(
75-
ComponentRegistrar $componentRegistrar,
76-
ReaderComposite $readerComposite,
77-
JsonPersistor $jsonPersistor,
78-
SchemaFactory $schemaFactory,
79-
SchemaBuilder $schemaBuilder,
40+
WhitelistGenerator $whitelistGenerator,
8041
$name = null
8142
) {
43+
$this->whitelistGenerator = $whitelistGenerator;
8244
parent::__construct($name);
83-
$this->componentRegistrar = $componentRegistrar;
84-
$this->readerComposite = $readerComposite;
85-
$this->jsonPersistor = $jsonPersistor;
86-
$this->schemaFactory = $schemaFactory;
87-
$this->schemaBuilder = $schemaBuilder;
8845
}
8946

9047
/**
@@ -112,44 +69,6 @@ protected function configure()
11269
parent::configure();
11370
}
11471

115-
/**
116-
* Update whitelist tables for all modules that are enabled on the moment.
117-
*
118-
* @param string $moduleName
119-
* @return void
120-
* @throws \Magento\Framework\Setup\Exception
121-
*/
122-
private function persistModule($moduleName)
123-
{
124-
$content = [];
125-
$modulePath = $this->componentRegistrar->getPath('module', $moduleName);
126-
$whiteListFileName = $modulePath
127-
. DIRECTORY_SEPARATOR
128-
. Dir::MODULE_ETC_DIR
129-
. DIRECTORY_SEPARATOR
130-
. Diff::GENERATED_WHITELIST_FILE_NAME;
131-
//We need to load whitelist file and update it with new revision of code.
132-
if (file_exists($whiteListFileName)) {
133-
$content = json_decode(file_get_contents($whiteListFileName), true);
134-
}
135-
136-
$schema = $this->schemaFactory->create();
137-
$data = $this->filterPrimaryTables($this->readerComposite->read($moduleName));
138-
if (isset($data['table'])) {
139-
$this->schemaBuilder->addTablesData($data['table']);
140-
$schema = $this->schemaBuilder->build($schema);
141-
142-
//Do merge between what we have before, and what we have now and filter to only certain attributes.
143-
$content = array_replace_recursive(
144-
$content,
145-
$this->getDeclaredContent($schema)
146-
);
147-
if (!empty($content)) {
148-
$this->jsonPersistor->persist($content, $whiteListFileName);
149-
}
150-
}
151-
}
152-
15372
/**
15473
* @inheritdoc
15574
*/
@@ -158,80 +77,14 @@ protected function execute(InputInterface $input, OutputInterface $output) : int
15877
$moduleName = $input->getOption(self::MODULE_NAME_KEY);
15978

16079
try {
161-
if ($moduleName === FileResolverByModule::ALL_MODULES) {
162-
foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) {
163-
$this->persistModule($moduleName);
164-
}
165-
} else {
166-
$this->persistModule($moduleName);
167-
}
80+
$this->whitelistGenerator->generate($moduleName);
81+
} catch (ConfigurationMismatchException $e) {
82+
$output->writeln("<info>". $e . "</info>");
83+
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
16884
} catch (\Exception $e) {
16985
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
17086
}
17187

172-
//If script comes here, that we sucessfully write whitelist configuration
17388
return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
17489
}
175-
176-
/**
177-
* Convert Schema into a whitelist structure.
178-
*
179-
* As for whitelist we do not need any specific attributes like nullable or indexType, we need to choose only names.
180-
*
181-
* @param Schema $schema
182-
* @return array
183-
*/
184-
private function getDeclaredContent(Schema $schema) : array
185-
{
186-
$names = [];
187-
foreach ($schema->getTables() as $tableName => $table) {
188-
$columns = array_keys($table->getColumns());
189-
if ($columns) {
190-
$names[$tableName]['column'] = array_fill_keys($columns, true);
191-
}
192-
193-
$indexes = array_keys($table->getIndexes());
194-
if ($indexes) {
195-
$names[$tableName]['index'] = array_fill_keys($indexes, true);
196-
}
197-
198-
$constraints = array_keys($table->getConstraints());
199-
if ($constraints) {
200-
$names[$tableName]['constraint'] = array_fill_keys($constraints, true);
201-
}
202-
}
203-
204-
return $names;
205-
}
206-
207-
/**
208-
* Load db_schema content from the primary scope app/etc/db_schema.xml.
209-
*
210-
* @return array
211-
*/
212-
private function getPrimaryDbSchema()
213-
{
214-
if (!$this->primaryDbSchema) {
215-
$this->primaryDbSchema = $this->readerComposite->read('primary');
216-
}
217-
return $this->primaryDbSchema;
218-
}
219-
220-
/**
221-
* Filter tables from module db_schema.xml as they should not contain the primary system tables.
222-
*
223-
* @param array $moduleDbSchema
224-
* @return array
225-
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
226-
*/
227-
private function filterPrimaryTables(array $moduleDbSchema)
228-
{
229-
$primaryDbSchema = $this->getPrimaryDbSchema();
230-
if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) {
231-
foreach ($primaryDbSchema['table'] as $tableNameKey => $tableContents) {
232-
unset($moduleDbSchema['table'][$tableNameKey]);
233-
}
234-
}
235-
return $moduleDbSchema;
236-
}
23790
}

0 commit comments

Comments
 (0)