![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/framework/Setup/Declaration/Schema/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\Setup\Declaration\Schema; use Magento\Framework\App\ResourceConnection; use Magento\Framework\Setup\Declaration\Schema\DataSavior\DataSaviorInterface; use Magento\Framework\Setup\Declaration\Schema\Db\DbSchemaWriterInterface; use Magento\Framework\Setup\Declaration\Schema\Db\StatementAggregatorFactory; use Magento\Framework\Setup\Declaration\Schema\Db\StatementFactory; use Magento\Framework\Setup\Declaration\Schema\Diff\DiffInterface; use Magento\Framework\Setup\Declaration\Schema\Dto\ElementInterface; use Magento\Framework\Setup\Declaration\Schema\Operations\AddColumn; use Magento\Framework\Setup\Declaration\Schema\Operations\CreateTable; use Magento\Framework\Setup\Declaration\Schema\Operations\ReCreateTable; /** * Schema operations executor. * * Go through all available SQL operations and execute each one with data from change registry. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class OperationsExecutor { /** * Request keys. */ const KEY_SAFE_MODE = 'safe-mode'; const KEY_DATA_RESTORE = 'data-restore'; /** * @var OperationInterface[] */ private $operations; /** * @var Sharding */ private $sharding; /** * @var ResourceConnection */ private $resourceConnection; /** * @var StatementFactory */ private $statementFactory; /** * @var DbSchemaWriterInterface */ private $dbSchemaWriter; /** * @var StatementAggregatorFactory */ private $statementAggregatorFactory; /** * @var DataSaviorInterface[] */ private $dataSaviorsCollection; /** * @var DryRunLogger */ private $dryRunLogger; /** * Constructor. * * @param array $operations * @param array $dataSaviorsCollection * @param Sharding $sharding * @param ResourceConnection $resourceConnection * @param StatementFactory $statementFactory * @param DbSchemaWriterInterface $dbSchemaWriter * @param StatementAggregatorFactory $statementAggregatorFactory * @param DryRunLogger $dryRunLogger */ public function __construct( array $operations, array $dataSaviorsCollection, Sharding $sharding, ResourceConnection $resourceConnection, StatementFactory $statementFactory, DbSchemaWriterInterface $dbSchemaWriter, StatementAggregatorFactory $statementAggregatorFactory, DryRunLogger $dryRunLogger ) { $this->operations = $operations; $this->sharding = $sharding; $this->resourceConnection = $resourceConnection; $this->statementFactory = $statementFactory; $this->dbSchemaWriter = $dbSchemaWriter; $this->statementAggregatorFactory = $statementAggregatorFactory; $this->dataSaviorsCollection = $dataSaviorsCollection; $this->dryRunLogger = $dryRunLogger; } /** * Retrieve only destructive operation names. * * For example, drop_table, recreate_table, etc. * * @return array */ public function getDestructiveOperations() { $operations = []; foreach ($this->operations as $operation) { if ($operation->isOperationDestructive()) { $operations[$operation->getOperationName()] = $operation->getOperationName(); } } return $operations; } /** * In order to successfully run all operations we need to start setup for all * connections first. * * @return void */ private function startSetupForAllConnections() { foreach ($this->sharding->getResources() as $resource) { $connection = $this->resourceConnection->getConnection($resource); $connection->startSetup(); $connection->query('SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0'); } } /** * In order to revert previous state we need to end setup for all connections * connections first. * * @return void */ private function endSetupForAllConnections() { foreach ($this->sharding->getResources() as $resource) { $connection = $this->resourceConnection->getConnection($resource); $connection->query('SET UNIQUE_CHECKS=IF(@OLD_UNIQUE_CHECKS=0, 0, 1)'); $connection->endSetup(); } } /** * Check if during this operation we need to restore data * * @param OperationInterface $operation * @return bool */ private function operationIsOppositeToDestructive(OperationInterface $operation) { return $operation instanceof AddColumn || $operation instanceof CreateTable || $operation instanceof ReCreateTable; } /** * Loop through all operations that are configured in di.xml * and execute them with elements from Diff. * * @see OperationInterface * @param DiffInterface $diff * @param array $requestData * @return void * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute(DiffInterface $diff, array $requestData) { $this->startSetupForAllConnections(); $tableHistories = $diff->getAll(); $dryRun = isset($requestData[DryRunLogger::INPUT_KEY_DRY_RUN_MODE]) && $requestData[DryRunLogger::INPUT_KEY_DRY_RUN_MODE]; if ($dryRun) { $this->dryRunLogger->prepareToDryRun(); } if (is_array($tableHistories)) { foreach ($tableHistories as $tableHistory) { $destructiveElements = []; $oppositeToDestructiveElements = []; $statementAggregator = $this->statementAggregatorFactory->create(); foreach ($this->operations as $operation) { if (isset($tableHistory[$operation->getOperationName()])) { /** @var ElementHistory $elementHistory */ foreach ($tableHistory[$operation->getOperationName()] as $elementHistory) { $statementAggregator->addStatements($operation->doOperation($elementHistory)); if ($operation->isOperationDestructive()) { $destructiveElements[] = $elementHistory->getOld(); } elseif ($this->operationIsOppositeToDestructive($operation)) { $oppositeToDestructiveElements[] = $elementHistory->getNew(); } } } } $this->doDump($destructiveElements, $requestData); $this->dbSchemaWriter->compile($statementAggregator, $dryRun); $this->doRestore($oppositeToDestructiveElements, $requestData); } } $this->endSetupForAllConnections(); } /** * Do restore of destructive operations * * @param array $elements * @param array $requestData */ private function doRestore(array $elements, array $requestData) { $restoreMode = isset($requestData[self::KEY_DATA_RESTORE]) && $requestData[self::KEY_DATA_RESTORE]; if ($restoreMode) { /** * @var ElementInterface $element */ foreach ($elements as $element) { foreach ($this->dataSaviorsCollection as $dataSavior) { if ($dataSavior->isAcceptable($element)) { $dataSavior->restore($element); break; } } } } } /** * Do dump of destructive operations * * @param array $elements * @param array $requestData */ private function doDump(array $elements, array $requestData) { $safeMode = isset($requestData[self::KEY_SAFE_MODE]) && $requestData[self::KEY_SAFE_MODE]; if ($safeMode) { /** * @var ElementInterface $element */ foreach ($elements as $element) { foreach ($this->dataSaviorsCollection as $dataSavior) { if ($dataSavior->isAcceptable($element)) { $dataSavior->dump($element); break; } } } } } }