Skip to content

Commit e4a2d3c

Browse files
committed
Mview patch update proposal
1 parent 9913305 commit e4a2d3c

File tree

10 files changed

+229
-110
lines changed

10 files changed

+229
-110
lines changed

app/code/Magento/Eav/Model/Mview/BatchIterator.php

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Eav\Model\Mview;
8+
9+
use Magento\Framework\App\ResourceConnection;
10+
use Magento\Framework\DB\Sql\Expression;
11+
use Magento\Framework\Mview\View\ChangeLogBatchWalkerInterface;
12+
use Magento\Framework\Mview\View\ChangelogInterface;
13+
14+
/**
15+
* Class BatchIterator
16+
*/
17+
class ChangeLogBatchWalker implements ChangeLogBatchWalkerInterface
18+
{
19+
private const GROUP_CONCAT_MAX_VARIABLE = 'group_concat_max_len';
20+
/** ID is defined as small int. Default size of it is 5 */
21+
private const DEFAULT_ID_SIZE = 5;
22+
23+
/**
24+
* @var ResourceConnection
25+
*/
26+
private $resourceConnection;
27+
28+
/**
29+
* @var array
30+
*/
31+
private $entityTypeCodes;
32+
33+
/**
34+
* @param ResourceConnection $resourceConnection
35+
* @param array $entityTypeCodes
36+
*/
37+
public function __construct(
38+
ResourceConnection $resourceConnection,
39+
array $entityTypeCodes = []
40+
) {
41+
$this->resourceConnection = $resourceConnection;
42+
$this->entityTypeCodes = $entityTypeCodes;
43+
}
44+
45+
/**
46+
* Calculate EAV attributes size
47+
*
48+
* @param ChangelogInterface $changelog
49+
* @return int
50+
* @throws \Exception
51+
*/
52+
private function calculateEavAttributeSize(ChangelogInterface $changelog): int
53+
{
54+
$connection = $this->resourceConnection->getConnection();
55+
56+
if (!isset($this->entityTypeCodes[$changelog->getViewId()])) {
57+
throw new \Exception('Entity type for view was not defined');
58+
}
59+
60+
$select = $connection->select();
61+
$select->from(
62+
$this->resourceConnection->getTableName('eav_attribute'),
63+
new Expression('COUNT(*)')
64+
)
65+
->joinInner(
66+
['type' => $connection->getTableName('eav_entity_type')],
67+
'type.entity_type_id=eav_attribute.entity_type_id'
68+
)
69+
->where('type.entity_type_code = ?', $this->entityTypeCodes[$changelog->getViewId()]);
70+
71+
return (int) $connection->fetchOne($select);
72+
}
73+
74+
/**
75+
* Prepare group max concat
76+
*
77+
* @param int $numberOfAttributes
78+
* @return void
79+
* @throws \Exception
80+
*/
81+
private function setGroupConcatMax(int $numberOfAttributes): void
82+
{
83+
$connection = $this->resourceConnection->getConnection();
84+
$connection->query(sprintf(
85+
'SET SESSION %s=%s',
86+
self::GROUP_CONCAT_MAX_VARIABLE,
87+
$numberOfAttributes * (self::DEFAULT_ID_SIZE + 1)
88+
));
89+
}
90+
91+
/**
92+
* @inheritdoc
93+
* @throws \Exception
94+
*/
95+
public function walk(ChangelogInterface $changelog, int $fromVersionId, int $toVersion, int $batchSize)
96+
{
97+
$connection = $this->resourceConnection->getConnection();
98+
$numberOfAttributes = $this->calculateEavAttributeSize($changelog);
99+
$this->setGroupConcatMax($numberOfAttributes);
100+
$select = $connection->select()->distinct(true)
101+
->where(
102+
'version_id > ?',
103+
(int) $fromVersionId
104+
)
105+
->where(
106+
'version_id <= ?',
107+
$toVersion
108+
)
109+
->group([$changelog->getColumnName(), 'store_id'])
110+
->limit($batchSize);
111+
112+
$columns = [
113+
$changelog->getColumnName(),
114+
'attribute_ids' => new Expression('GROUP_CONCAT(attribute_id)'),
115+
'store_id'
116+
];
117+
$select->from($changelog->getName(), $columns);
118+
return $connection->fetchAll($select);
119+
}
120+
}

lib/internal/Magento/Framework/Mview/Config/Converter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Magento\Framework\Mview\Config;
77

88
use Magento\Framework\Mview\View\AdditionalColumnsProcessor\DefaultProcessor;
9-
use Magento\Framework\Mview\View\ChangeLogBatchIterator;
9+
use Magento\Framework\Mview\View\ChangeLogBatchWalker;
1010
use Magento\Framework\Mview\View\SubscriptionInterface;
1111

1212
class Converter implements \Magento\Framework\Config\ConverterInterface
@@ -27,7 +27,7 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
2727
*/
2828
public function __construct(
2929
string $defaultProcessor = DefaultProcessor::class,
30-
string $defaultIterator = ChangeLogBatchIterator::class
30+
string $defaultIterator = ChangeLogBatchWalker::class
3131
) {
3232
$this->defaultProcessor = $defaultProcessor;
3333
$this->defaultIterator = $defaultIterator;
@@ -52,7 +52,7 @@ public function convert($source)
5252
$data['view_id'] = $viewId;
5353
$data['action_class'] = $this->getAttributeValue($viewNode, 'class');
5454
$data['group'] = $this->getAttributeValue($viewNode, 'group');
55-
$data['iterator'] = $this->getAttributeValue($viewNode, 'iterator') ?: $this->defaultIterator;
55+
$data['walker'] = $this->getAttributeValue($viewNode, 'walker') ?: $this->defaultIterator;
5656
$data['subscriptions'] = [];
5757

5858
/** @var $childNode \DOMNode */

lib/internal/Magento/Framework/Mview/View.php

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
use InvalidArgumentException;
1212
use Magento\Framework\App\ObjectManager;
1313
use Magento\Framework\DataObject;
14-
use Magento\Framework\Mview\View\ChangeLogBatchIterator;
15-
use Magento\Framework\Mview\View\ChangeLogBatchIteratorInterface;
14+
use Magento\Framework\Mview\View\ChangeLogBatchWalkerFactory;
15+
use Magento\Framework\Mview\View\ChangeLogBatchWalkerInterface;
1616
use Magento\Framework\Mview\View\ChangelogTableNotExistsException;
1717
use Magento\Framework\Mview\View\SubscriptionFactory;
1818
use Exception;
@@ -66,9 +66,9 @@ class View extends DataObject implements ViewInterface
6666
private $changelogBatchSize;
6767

6868
/**
69-
* @var ChangeLogBatchIteratorInterface
69+
* @var ChangeLogBatchWalkerFactory
7070
*/
71-
private $iterator;
71+
private $changeLogBatchWalkerFactory;
7272

7373
/**
7474
* @param ConfigInterface $config
@@ -78,7 +78,7 @@ class View extends DataObject implements ViewInterface
7878
* @param SubscriptionFactory $subscriptionFactory
7979
* @param array $data
8080
* @param array $changelogBatchSize
81-
* @param ChangeLogBatchIteratorInterface|null $changeLogBatchIterator
81+
* @param ChangeLogBatchWalkerFactory $changeLogBatchWalkerFactory
8282
*/
8383
public function __construct(
8484
ConfigInterface $config,
@@ -88,7 +88,7 @@ public function __construct(
8888
SubscriptionFactory $subscriptionFactory,
8989
array $data = [],
9090
array $changelogBatchSize = [],
91-
ChangeLogBatchIteratorInterface $changeLogBatchIterator = null
91+
ChangeLogBatchWalkerFactory $changeLogBatchWalkerFactory = null
9292
) {
9393
$this->config = $config;
9494
$this->actionFactory = $actionFactory;
@@ -97,7 +97,8 @@ public function __construct(
9797
$this->subscriptionFactory = $subscriptionFactory;
9898
$this->changelogBatchSize = $changelogBatchSize;
9999
parent::__construct($data);
100-
$this->iterator = $changeLogBatchIterator;
100+
$this->changeLogBatchWalkerFactory = $changeLogBatchWalkerFactory ?:
101+
ObjectManager::getInstance()->get(ChangeLogBatchWalkerFactory::class);
101102
}
102103

103104
/**
@@ -303,8 +304,8 @@ private function executeAction(ActionInterface $action, int $lastVersionId, int
303304

304305
$vsFrom = $lastVersionId;
305306
while ($vsFrom < $currentVersionId) {
306-
$iterator = $this->getIterator();
307-
$ids = $iterator->walk($this->getChangelog(), $vsFrom, $currentVersionId, $batchSize);
307+
$walker = $this->getWalker();
308+
$ids = $walker->walk($this->getChangelog(), $vsFrom, $currentVersionId, $batchSize);
308309

309310
if (empty($ids)) {
310311
break;
@@ -315,34 +316,16 @@ private function executeAction(ActionInterface $action, int $lastVersionId, int
315316
}
316317

317318
/**
318-
* Create and validate iterator class for changelog
319+
* Create and validate walker class for changelog
319320
*
320-
* @return ChangeLogBatchIteratorInterface|mixed
321+
* @return ChangeLogBatchWalkerInterface|mixed
321322
* @throws Exception
322323
*/
323-
private function getIterator()
324+
private function getWalker(): ChangeLogBatchWalkerInterface
324325
{
325-
if ($this->iterator) {
326-
return $this->iterator;
327-
}
328-
329326
$config = $this->config->getView($this->changelog->getViewId());
330-
$iteratorClass = $config['iterator'];
331-
332-
if (!class_exists($iteratorClass)) {
333-
throw new \Exception('Iterator class does not exist for view: ' . $this->changelog->getViewId());
334-
}
335-
336-
$iterator = ObjectManager::getInstance()->get($iteratorClass);
337-
338-
if (!$iterator instanceof ChangeLogBatchIteratorInterface) {
339-
throw new \Exception(
340-
'Iterator does not implement the right interface for view: ' .
341-
$this->changelog->getViewId()
342-
);
343-
}
344-
345-
return $iterator;
327+
$walkerClass = $config['walker'];
328+
return $this->changeLogBatchWalkerFactory->create($walkerClass);
346329
}
347330

348331
/**
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Framework\Mview\View\AdditionalColumnsProcessor;
8+
9+
use Magento\Framework\Mview\View\AdditionalColumnProcessorInterface;
10+
use Magento\Framework\ObjectManagerInterface;
11+
12+
class ProcessorFactory
13+
{
14+
/**
15+
* @var ObjectManagerInterface
16+
*/
17+
private $objectManager;
18+
19+
/**
20+
* ProcessorFactory constructor.
21+
* @param ObjectManagerInterface $objectManager
22+
*/
23+
public function __construct(ObjectManagerInterface $objectManager)
24+
{
25+
$this->objectManager = $objectManager;
26+
}
27+
28+
/**
29+
* Instantiate additional columns processor
30+
*
31+
* @param string $processorClassName
32+
* @return AdditionalColumnProcessorInterface
33+
*/
34+
public function create(string $processorClassName): AdditionalColumnProcessorInterface
35+
{
36+
return $this->objectManager->create($processorClassName);
37+
}
38+
}

lib/internal/Magento/Framework/Mview/View/ChangeLogBatchIterator.php renamed to lib/internal/Magento/Framework/Mview/View/ChangeLogBatchWalker.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
namespace Magento\Framework\Mview\View;
88

99
use Magento\Framework\App\ResourceConnection;
10-
use Magento\Framework\DB\Sql\Expression;
1110
use Magento\Framework\Phrase;
1211

1312
/**
14-
* Interface \Magento\Framework\Mview\View\ChangeLogBatchIterator
13+
* Interface \Magento\Framework\Mview\View\ChangeLogBatchWalkerInterface
1514
*
1615
*/
17-
class ChangeLogBatchIterator implements ChangeLogBatchIteratorInterface
16+
class ChangeLogBatchWalker implements ChangeLogBatchWalkerInterface
1817
{
1918
/**
2019
* @var ResourceConnection

0 commit comments

Comments
 (0)