Skip to content

Commit 2892e93

Browse files
committed
ACP2E-633: Missing trigger in catalogrule_product_price table after a full reindex
1 parent 44f6a52 commit 2892e93

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

app/code/Magento/CatalogRule/Model/Indexer/IndexerTableSwapper.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public function swapIndexTables(array $originalTablesNames)
9191
$toDrop = [];
9292
/** @var string[] $temporaryTablesRenamed */
9393
$temporaryTablesRenamed = [];
94+
$restoreTriggerQueries = [];
9495
//Renaming temporary tables to original tables' names, dropping old
9596
//tables.
9697
foreach ($originalTablesNames as $tableName) {
@@ -99,6 +100,7 @@ public function swapIndexTables(array $originalTablesNames)
99100
$tableName . $this->generateRandomSuffix()
100101
);
101102
$temporaryTableName = $this->getWorkingTableName($tableName);
103+
$restoreTriggerQueries[] = $this->getRestoreTriggerQueries($tableName);
102104
$toRename[] = [
103105
'oldName' => $tableName,
104106
'newName' => $temporaryOriginalName,
@@ -121,6 +123,41 @@ public function swapIndexTables(array $originalTablesNames)
121123
foreach ($toDrop as $tableName) {
122124
$this->resourceConnection->getConnection()->dropTable($tableName);
123125
}
126+
127+
//Restoring triggers
128+
$restoreTriggerQueries = array_merge([], ...$restoreTriggerQueries);
129+
foreach ($restoreTriggerQueries as $restoreTriggerQuery) {
130+
$this->resourceConnection->getConnection()->multiQuery($restoreTriggerQuery);
131+
}
132+
}
133+
134+
/**
135+
* Get queries for table triggers restoring.
136+
*
137+
* @param string $tableName
138+
* @return array
139+
*/
140+
private function getRestoreTriggerQueries(string $tableName): array
141+
{
142+
$triggers = $this->resourceConnection->getConnection()
143+
->query('SHOW TRIGGERS LIKE \''. $tableName . '\'')
144+
->fetchAll();
145+
146+
if (!$triggers) {
147+
return [];
148+
}
149+
150+
$result = [];
151+
foreach ($triggers as $trigger) {
152+
// phpcs:ignore Magento2.SQL.RawQuery.FoundRawSql
153+
$result[] = 'DROP TRIGGER IF EXISTS ' . $trigger['Trigger'];
154+
$triggerData = $this->resourceConnection->getConnection()
155+
->query('SHOW CREATE TRIGGER '. $trigger['Trigger'])
156+
->fetch();
157+
$result[] = preg_replace('/DEFINER=[^\s]*/', '', $triggerData['SQL Original Statement']);
158+
}
159+
160+
return $result;
124161
}
125162

126163
/**

app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexerTableSwapperTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ protected function setUp(): void
4848

4949
$this->adapterInterfaceMock = $this->getMockBuilder(AdapterInterface::class)
5050
->getMockForAbstractClass();
51+
$zendDbStatementInterfaceMock = $this->getMockBuilder(\Zend_Db_Statement_Interface::class)
52+
->getMockForAbstractClass();
53+
$this->adapterInterfaceMock->expects($this->any())
54+
->method('query')
55+
->willReturn($zendDbStatementInterfaceMock);
5156
/** @var \Zend_Db_Statement_Interface $statementInterfaceMock */
5257
$this->statementInterfaceMock = $this->getMockBuilder(\Zend_Db_Statement_Interface::class)
5358
->getMockForAbstractClass();

dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
namespace Magento\CatalogRule\Model\Indexer;
77

88
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Catalog\Model\Indexer\Product\Price\Processor;
10+
use Magento\Framework\App\ResourceConnection;
911
use Magento\Store\Model\StoreManagerInterface;
1012
use Magento\TestFramework\Helper\Bootstrap;
1113

@@ -46,6 +48,16 @@ class IndexerBuilderTest extends \PHPUnit\Framework\TestCase
4648
*/
4749
private $productRepository;
4850

51+
/**
52+
* @var ResourceConnection
53+
*/
54+
private $connection;
55+
56+
/**
57+
* @var Processor
58+
*/
59+
private $indexProductProcessor;
60+
4961
protected function setUp(): void
5062
{
5163
$this->indexerBuilder = Bootstrap::getObjectManager()->get(
@@ -55,6 +67,8 @@ protected function setUp(): void
5567
$this->product = Bootstrap::getObjectManager()->get(\Magento\Catalog\Model\Product::class);
5668
$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
5769
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
70+
$this->connection = Bootstrap::getObjectManager()->get(ResourceConnection::class);
71+
$this->indexProductProcessor = Bootstrap::getObjectManager()->get(Processor::class);
5872
}
5973

6074
protected function tearDown(): void
@@ -171,6 +185,45 @@ public function testReindexFull()
171185
$this->assertFalse($this->resourceRule->getRulePrice(new \DateTime(), 1, 1, $this->productThird->getId()));
172186
}
173187

188+
/**
189+
* Tests restoring triggers on `catalogrule_product_price` table after full reindexing in 'Update by schedule' mode.
190+
*
191+
* @magentoDbIsolation disabled
192+
* @magentoAppIsolation enabled
193+
*/
194+
public function testRestoringTriggersAfterFullReindex()
195+
{
196+
$tableName = $this->connection->getTableName('catalogrule_product_price');
197+
198+
$this->indexProductProcessor->getIndexer()->setScheduled(false);
199+
$this->assertEquals(0, $this->getTriggersCount($tableName));
200+
201+
$this->indexProductProcessor->getIndexer()->setScheduled(true);
202+
$this->assertGreaterThan(0, $this->getTriggersCount($tableName));
203+
204+
$this->indexerBuilder->reindexFull();
205+
$this->assertGreaterThan(0, $this->getTriggersCount($tableName));
206+
207+
$this->indexProductProcessor->getIndexer()->setScheduled(false);
208+
$this->assertEquals(0, $this->getTriggersCount($tableName));
209+
}
210+
211+
/**
212+
* Returns triggers count.
213+
*
214+
* @param string $tableName
215+
* @return int
216+
* @throws \Zend_Db_Statement_Exception
217+
*/
218+
private function getTriggersCount(string $tableName): int
219+
{
220+
return count(
221+
$this->connection->getConnection()
222+
->query('SHOW TRIGGERS LIKE \''. $tableName . '\'')
223+
->fetchAll()
224+
);
225+
}
226+
174227
protected function prepareProducts()
175228
{
176229
$product = $this->product->loadByAttribute('sku', 'simple');

0 commit comments

Comments
 (0)