diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php index 616e120ebafe4a49bebb5bce4c6e4f82b804cf72..d432767e92689527de82f382448722aad0ddd32d 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php @@ -42,30 +42,13 @@ class DataCategoryHashMap implements HashMapInterface $this->categoryResource = $categoryResource; } - /** - * {@inheritdoc} - */ - public function getAllData($categoryId) - { - return $this->generateData($categoryId); - } - - /** - * {@inheritdoc} - */ - public function getData($categoryId, $key) - { - $categorySpecificData = $this->generateData($categoryId); - return $categorySpecificData[$key]; - } - /** * Returns an array of categories ids that includes category identified by $categoryId and all its subcategories * * @param int $categoryId * @return array */ - private function generateData($categoryId) + public function getAllData($categoryId) { if (!isset($this->hashMap[$categoryId])) { $category = $this->categoryRepository->get($categoryId); @@ -75,6 +58,18 @@ class DataCategoryHashMap implements HashMapInterface return $this->hashMap[$categoryId]; } + /** + * {@inheritdoc} + */ + public function getData($categoryId, $key) + { + $categorySpecificData = $this->getAllData($categoryId); + if (isset($categorySpecificData[$key])) { + return $categorySpecificData[$key]; + } + return []; + } + /** * Queries the database for sub-categories ids from a category * diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php index 8864226d069d290034c540503e1ee882e5147e90..65200ba1f413d63f06f0d9b319fb6a339d55ae43 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php @@ -33,23 +33,6 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface $this->hashMapPool = $hashMapPool; } - /** - * {@inheritdoc} - */ - public function getAllData($categoryId) - { - return $this->generateData($categoryId); - } - - /** - * {@inheritdoc} - */ - public function getData($categoryId, $key) - { - $categorySpecificData = $this->generateData($categoryId); - return $categorySpecificData[$key]; - } - /** * Returns an array of product ids for all DataProductHashMap list, * that occur in other categories not part of DataCategoryHashMap list @@ -57,7 +40,7 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface * @param int $categoryId * @return array */ - private function generateData($categoryId) + public function getAllData($categoryId) { if (!isset($this->hashMap[$categoryId])) { $productsLinkConnection = $this->connection->getConnection(); @@ -91,6 +74,18 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface return $this->hashMap[$categoryId]; } + /** + * {@inheritdoc} + */ + public function getData($categoryId, $key) + { + $categorySpecificData = $this->getAllData($categoryId); + if (isset($categorySpecificData[$key])) { + return $categorySpecificData[$key]; + } + return []; + } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php index a20b837e4096ad3155aca948e393b8b79597a22a..4b107043459a3c041181961f5cb0a9c02eeb1a41 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php @@ -40,30 +40,13 @@ class DataProductHashMap implements HashMapInterface $this->connection = $connection; } - /** - * {@inheritdoc} - */ - public function getAllData($categoryId) - { - return $this->generateData($categoryId); - } - - /** - * {@inheritdoc} - */ - public function getData($categoryId, $key) - { - $categorySpecificData = $this->generateData($categoryId); - return $categorySpecificData[$key]; - } - /** * Returns an array of ids of all visible products and assigned to a category and all its subcategories * * @param int $categoryId * @return array */ - private function generateData($categoryId) + public function getAllData($categoryId) { if (!isset($this->hashMap[$categoryId])) { $productsCollection = $this->collectionFactory->create(); @@ -89,6 +72,18 @@ class DataProductHashMap implements HashMapInterface return $this->hashMap[$categoryId]; } + /** + * {@inheritdoc} + */ + public function getData($categoryId, $key) + { + $categorySpecificData = $this->getAllData($categoryId); + if (isset($categorySpecificData[$key])) { + return $categorySpecificData[$key]; + } + return []; + } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php index 30732013eace4df7906333bbd43935b2f5761d84..bb94c1972a17c4e4afa1db555fc461cc21625c95 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php @@ -44,17 +44,18 @@ class DatabaseMapPool { $key = $instanceName . '-' . $categoryId; if (!isset($this->dataArray[$key])) { - $this->dataArray[$key] = $this->objectManager->create( + $instance = $this->objectManager->create( $instanceName, [ 'category' => $categoryId ] ); - if (!$this->dataArray[$key] instanceof DatabaseMapInterface) { + if (!$instance instanceof DatabaseMapInterface) { throw new \InvalidArgumentException( $instanceName . ' does not implement interface ' . DatabaseMapInterface::class ); } + $this->dataArray[$key] = $instance; } return $this->dataArray[$key]; } diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php index bc6be808d4d9a96e7cd8a42ed106c7266f209c40..6606812a61995fa24a383170e67c6c99eb1caa90 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php @@ -45,17 +45,18 @@ class HashMapPool { $key = $instanceName . '-' . $categoryId; if (!isset($this->dataArray[$key])) { - $this->dataArray[$key] = $this->objectManager->create( + $instance = $this->objectManager->create( $instanceName, [ 'category' => $categoryId ] ); - if (!$this->dataArray[$key] instanceof HashMapInterface) { + if (!$instance instanceof HashMapInterface) { throw new \InvalidArgumentException( $instanceName . ' does not implement interface ' . HashMapInterface::class ); } + $this->dataArray[$key] = $instance; } return $this->dataArray[$key]; } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php index 78b114f60da858acb0d8bbd2e07edd87dcfb5ad0..eef5e05e4f6429ed90f76d918502b0dff0d20513 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php @@ -9,6 +9,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\CatalogUrlRewrite\Model\Map\HashMapPool; use Magento\CatalogUrlRewrite\Model\Map\DataCategoryHashMap; use Magento\CatalogUrlRewrite\Model\Map\DataProductHashMap; +use Magento\CatalogUrlRewrite\Model\Map\DataCategoryUsedInProductsHashMap; use Magento\Framework\ObjectManagerInterface; /** @@ -41,15 +42,35 @@ class HashMapPoolTest extends \PHPUnit_Framework_TestCase { $dataCategoryMapMock = $this->getMock(DataCategoryHashMap::class, [], [], '', false); $dataProductMapMock = $this->getMock(DataProductHashMap::class, [], [], '', false); - $dataProductMapMockOtherCategory = $this->getMock(DataProductHashMap::class, [], [], '', false); + $dataProductMapMockOtherCategory = $this->getMock(DataCategoryUsedInProductsHashMap::class, [], [], '', false); $this->objectManagerMock->expects($this->any()) ->method('create') - ->willReturnOnConsecutiveCalls($dataCategoryMapMock, $dataProductMapMock, $dataProductMapMockOtherCategory); - $this->assertEquals($dataCategoryMapMock, $this->model->getDataMap(DataCategoryHashMap::class, 1)); + ->willReturnMap( + [ + [ + DataCategoryHashMap::class, + ['category' => 1], + $dataCategoryMapMock + ], + [ + DataProductHashMap::class, + ['category' => 1], + $dataProductMapMock + ], + [ + DataCategoryUsedInProductsHashMap::class, + ['category' => 2], + $dataProductMapMockOtherCategory + ] + ] + ); $this->assertSame($dataCategoryMapMock, $this->model->getDataMap(DataCategoryHashMap::class, 1)); - $this->assertEquals($dataProductMapMock, $this->model->getDataMap(DataProductHashMap::class, 1)); - $this->assertEquals($dataProductMapMockOtherCategory, $this->model->getDataMap(DataCategoryHashMap::class, 2)); + $this->assertSame($dataProductMapMock, $this->model->getDataMap(DataProductHashMap::class, 1)); + $this->assertSame( + $dataProductMapMockOtherCategory, + $this->model->getDataMap(DataCategoryUsedInProductsHashMap::class, 2) + ); } /** diff --git a/app/etc/di.xml b/app/etc/di.xml index 3a5533fd825ce677d5df3f6ff2dded69af010693..a7c38ae1246b602a105c5e1a588fc5e7b9561b2e 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1221,4 +1221,17 @@ </argument> </arguments> </type> + <type name="Magento\Framework\DB\TemporaryTableService"> + <arguments> + <argument name="allowedIndexMethods" xsi:type="array"> + <item name="HASH" xsi:type="string">HASH</item> + <item name="BTREE" xsi:type="string">BTREE</item> + </argument> + <argument name="allowedEngines" xsi:type="array"> + <item name="INNODB" xsi:type="string">INNODB</item> + <item name="MEMORY" xsi:type="string">MEMORY</item> + <item name="MYISAM" xsi:type="string">MYISAM</item> + </argument> + </arguments> + </type> </config> diff --git a/lib/internal/Magento/Framework/DB/TemporaryTableService.php b/lib/internal/Magento/Framework/DB/TemporaryTableService.php index 62d1a0d65cfb5c294e6f9b7771366d10cfcc853f..a2c6f6d46515f4fc0011a65069d5c29af629ac31 100644 --- a/lib/internal/Magento/Framework/DB/TemporaryTableService.php +++ b/lib/internal/Magento/Framework/DB/TemporaryTableService.php @@ -16,8 +16,21 @@ use Magento\Framework\DB\Select; */ class TemporaryTableService { + CONST HASH = 'HASH'; + CONST INNODB = 'INNODB'; + + /** + * @var string[] + */ + private $allowedIndexMethods; + /** - * @var $random + * @var string[] + */ + private $allowedEngines; + + /** + * @var \Magento\Framework\Math\Random */ private $random; @@ -28,10 +41,17 @@ class TemporaryTableService /** * @param \Magento\Framework\Math\Random $random + * @param string[] $allowedIndexMethods + * @param string[] $allowedEngines */ - public function __construct(\Magento\Framework\Math\Random $random) - { + public function __construct( + \Magento\Framework\Math\Random $random, + $allowedIndexMethods = [self::HASH], + $allowedEngines = [self::INNODB] + ) { $this->random = $random; + $this->allowedIndexMethods = $allowedIndexMethods; + $this->allowedEngines = $allowedEngines; } /** @@ -55,16 +75,29 @@ class TemporaryTableService * @param AdapterInterface $adapter * @param array $indexes * @param string $indexMethod - * @param string $engine + * @param string $dbEngine * @return string + * @throws \InvalidArgumentException */ public function createFromSelect( Select $select, AdapterInterface $adapter, array $indexes = [], - $indexMethod = 'HASH', - $engine = 'INNODB' + $indexMethod = self::HASH, + $dbEngine = self::INNODB ) { + if (!in_array($indexMethod, $this->allowedIndexMethods)) { + throw new \InvalidArgumentException( + sprintf('indexMethod must be of type %s', implode(',', $this->allowedIndexMethods)) + ); + } + + if (!in_array($dbEngine, $this->allowedEngines)) { + throw new \InvalidArgumentException( + sprintf('dbEngine must be of type %s', implode(',', $this->allowedEngines)) + ); + } + $name = $this->random->getUniqueHash('tmp_select_'); $indexStatements = []; @@ -90,7 +123,7 @@ class TemporaryTableService 'CREATE TEMPORARY TABLE %s %s ENGINE=%s IGNORE (%s)', $adapter->quoteIdentifier($name), $indexStatements ? '(' . implode(',', $indexStatements) . ')' : '', - $adapter->quoteIdentifier($engine), + $adapter->quoteIdentifier($dbEngine), "{$select}" ); diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php index 4105fefb5785b0ccac7c403afcdce630b041dd1c..68ccad5e3855df6d947cf3b365f837aaf72c595e 100644 --- a/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php +++ b/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php @@ -51,12 +51,39 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase ); } + /** + * Run test createFromSelect method + * + * @return void + */ + public function testCreateFromSelectWithException() + { + $this->setExpectedException(\InvalidArgumentException::class); + $random = 'random_table'; + $indexes = [ + ['PRIMARY' => ['primary_column_name']], + 'CREATE TEMPORARY TABLE random_table (PRIMARY KEY(primary_column_name)) ENGINE=INNODB IGNORE ' + . '(select * from sometable)' + ]; + + $this->assertEquals( + $random, + $this->temporaryTableService->createFromSelect( + $this->selectMock, + $this->adapterMock, + $indexes, + TemporaryTableService::HASH . "Other", + TemporaryTableService::INNODB . "Other" + ) + ); + } + /** * Run test createFromSelect method * * @param array $indexes * @param string $expectedSelect - * @dataProvider getCreateFromSelectTestParameters + * @dataProvider createFromSelectDataProvider * @return void */ public function testCreateFromSelect($indexes, $expectedSelect) @@ -115,7 +142,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase * @param string $tableName * @param bool $assertion * - * @dataProvider getDropTableTestParameters + * @dataProvider dropTableWhenCreatedTablesArrayNotEmptyDataProvider * @return void */ public function testDropTableWhenCreatedTablesArrayNotEmpty($tableName, $assertion) @@ -135,7 +162,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase /** * @return array */ - public function getCreateFromSelectTestParameters() + public function createFromSelectDataProvider() { return [ [ @@ -170,7 +197,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase /** * @return array */ - public function getDropTableTestParameters() + public function dropTableWhenCreatedTablesArrayNotEmptyDataProvider() { return [ ['tmp_select_table_1', false],