22 class Full extends \Magento\Catalog\Model\Indexer\Product\Price\AbstractAction
27 private $metadataPool;
32 private $batchSizeCalculator;
37 private $batchProvider;
42 private $activeTableSwitcher;
47 private $productMetaDataCached;
52 private $dimensionCollectionFactory;
57 private $dimensionTableMaintainer;
62 private $processManager;
85 \
Magento\Directory\Model\CurrencyFactory $currencyFactory,
86 \
Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
91 \
Magento\Framework\EntityManager\MetadataPool $metadataPool =
null,
93 \
Magento\Framework\
Indexer\BatchProviderInterface $batchProvider =
null,
106 $indexerPriceFactory,
107 $defaultIndexerResource
110 \
Magento\Framework\EntityManager\MetadataPool::class
140 public function execute($ids =
null)
144 $this->prepareTables();
150 $this->reindexProductTypeWithDimensions($priceIndexer, $typeId);
154 $priceIndexer->getTableStrategy()->setUseIdxTable(
false);
157 $this->reindexProductType($priceIndexer, $typeId);
161 $this->switchTables();
162 }
catch (\Exception $e) {
173 private function prepareTables()
175 $this->_defaultIndexerResource->getTableStrategy()->setUseIdxTable(
false);
177 $this->_prepareWebsiteDateTable();
179 $this->truncateReplicaTables();
188 private function truncateReplicaTables()
190 foreach ($this->dimensionCollectionFactory->create() as $dimension) {
191 $dimensionTable = $this->dimensionTableMaintainer->getMainReplicaTable($dimension);
192 $this->_defaultIndexerResource->getConnection()->truncateTable($dimensionTable);
205 private function reindexProductTypeWithDimensions(DimensionalIndexerInterface $priceIndexer,
string $typeId)
208 foreach ($this->dimensionCollectionFactory->create() as $dimensions) {
209 $userFunctions[] =
function () use ($priceIndexer, $dimensions, $typeId) {
210 return $this->reindexByBatches($priceIndexer, $dimensions, $typeId);
213 $this->processManager->execute($userFunctions);
226 private function reindexByBatches(DimensionalIndexerInterface $priceIndexer, array $dimensions,
string $typeId)
228 foreach ($this->getBatchesForIndexer($typeId) as $batch) {
229 $this->reindexByBatchWithDimensions($priceIndexer, $batch, $dimensions, $typeId);
241 private function getBatchesForIndexer(
string $typeId)
243 $connection = $this->_defaultIndexerResource->getConnection();
244 return $this->batchProvider->getBatches(
246 $this->getProductMetaData()->getEntityTable(),
247 $this->getProductMetaData()->getIdentifierField(),
248 $this->batchSizeCalculator->estimateBatchSize(
266 private function reindexByBatchWithDimensions(
267 DimensionalIndexerInterface $priceIndexer,
272 $entityIds = $this->getEntityIdsFromBatch($typeId, $batch);
274 if (!empty($entityIds)) {
275 $this->dimensionTableMaintainer->createMainTmpTable($dimensions);
276 $temporaryTable = $this->dimensionTableMaintainer->getMainTmpTable($dimensions);
279 $priceIndexer->executeByDimensions($dimensions, \SplFixedArray::fromArray($entityIds,
false));
284 $this->dimensionTableMaintainer->getMainReplicaTable($dimensions)
298 private function reindexProductType(PriceInterface $priceIndexer,
string $typeId)
300 foreach ($this->getBatchesForIndexer($typeId) as $batch) {
301 $this->reindexBatch($priceIndexer, $batch, $typeId);
315 private function reindexBatch(PriceInterface $priceIndexer, array $batch,
string $typeId)
317 $entityIds = $this->getEntityIdsFromBatch($typeId, $batch);
319 if (!empty($entityIds)) {
321 $idxTableName = $this->_defaultIndexerResource->getIdxTable();
324 if ($priceIndexer->getIsComposite()) {
329 $priceIndexer->reindexEntity($entityIds);
335 $this->_defaultIndexerResource->getConnection()->dropTable($idxTableName);
348 private function getEntityIdsFromBatch(
string $typeId, array $batch)
350 $connection = $this->_defaultIndexerResource->getConnection();
357 [
'e' => $this->getProductMetaData()->getEntityTable()],
358 $this->getProductMetaData()->getIdentifierField()
360 ->where(
'type_id = ?', $typeId);
371 private function getProductMetaData()
373 if ($this->productMetaDataCached ===
null) {
374 $this->productMetaDataCached = $this->metadataPool->getMetadata(ProductInterface::class);
377 return $this->productMetaDataCached;
386 private function getReplicaTable()
388 return $this->activeTableSwitcher->getAdditionalTableName(
389 $this->_defaultIndexerResource->getMainTable()
398 private function switchTables()
401 $mainTablesByDimension = [];
403 foreach ($this->dimensionCollectionFactory->create() as $dimensions) {
404 $mainTablesByDimension[] = $this->dimensionTableMaintainer->getMainTable($dimensions);
407 $this->moveDataFromReplicaTableToReplicaTables($dimensions);
410 if (count($mainTablesByDimension) > 0) {
411 $this->activeTableSwitcher->switchTable(
412 $this->_defaultIndexerResource->getConnection(),
413 $mainTablesByDimension
426 private function moveDataFromReplicaTableToReplicaTables(array $dimensions)
431 $select = $this->dimensionTableMaintainer->getConnection()->select()->from(
432 $this->dimensionTableMaintainer->getMainReplicaTable([])
436 $check->reset(
'columns')->columns(
'count(*)');
438 if (!$this->dimensionTableMaintainer->getConnection()->query($check)->fetchColumn()) {
442 $replicaTablesByDimension = $this->dimensionTableMaintainer->getMainReplicaTable($dimensions);
444 foreach ($dimensions as $dimension) {
445 if ($dimension->getName() === WebsiteDimensionProvider::DIMENSION_NAME) {
446 $select->where(
'website_id = ?', $dimension->getValue());
448 if ($dimension->getName() === CustomerGroupDimensionProvider::DIMENSION_NAME) {
449 $select->where(
'customer_group_id = ?', $dimension->getValue());
453 $this->dimensionTableMaintainer->getConnection()->query(
454 $this->dimensionTableMaintainer->getConnection()->insertFromSelect(
456 $replicaTablesByDimension,
458 \
Magento\Framework\DB\Adapter\AdapterInterface::INSERT_ON_DUPLICATE
470 return $this->activeTableSwitcher->getAdditionalTableName($this->_defaultIndexerResource->getMainTable());
_insertFromTable($sourceTable, $destTable, $where=null)
_copyRelationIndexData($parentIds, $excludeIds=null)
getTypeIndexers($fullReindexAction=false)
__construct(\Magento\Framework\App\Config\ScopeConfigInterface $config, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Catalog\Model\Product\Type $catalogProductType, \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Factory $indexerPriceFactory, \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice $defaultIndexerResource, \Magento\Framework\EntityManager\MetadataPool $metadataPool=null, \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BatchSizeCalculator $batchSizeCalculator=null, \Magento\Framework\Indexer\BatchProviderInterface $batchProvider=null, \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher $activeTableSwitcher=null, \Magento\Catalog\Model\Indexer\Product\Price\DimensionCollectionFactory $dimensionCollectionFactory=null, \Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer $dimensionTableMaintainer=null, \Magento\Indexer\Model\ProcessManager $processManager=null)