AbstractResource.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Indexer\Model\ResourceModel;
  7. use Magento\Framework\DB\Adapter\AdapterInterface;
  8. use Magento\Framework\DB\Select;
  9. /**
  10. * Abstract resource model. Can be used as base for indexer resources
  11. *
  12. * @api
  13. * @since 100.0.2
  14. */
  15. abstract class AbstractResource extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  16. {
  17. /**
  18. * Constructor
  19. *
  20. * @var \Magento\Framework\Indexer\Table\StrategyInterface
  21. */
  22. protected $tableStrategy;
  23. /**
  24. * Class constructor
  25. *
  26. * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
  27. * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy
  28. * @param string $connectionName
  29. */
  30. public function __construct(
  31. \Magento\Framework\Model\ResourceModel\Db\Context $context,
  32. \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
  33. $connectionName = null
  34. ) {
  35. $this->tableStrategy = $tableStrategy;
  36. parent::__construct($context, $connectionName);
  37. }
  38. /**
  39. * Reindex all
  40. *
  41. * @return $this
  42. */
  43. public function reindexAll()
  44. {
  45. $this->tableStrategy->setUseIdxTable(true);
  46. return $this;
  47. }
  48. /**
  49. * Get DB adapter for index data processing
  50. *
  51. * @return AdapterInterface
  52. */
  53. protected function _getIndexAdapter()
  54. {
  55. return $this->getConnection();
  56. }
  57. /**
  58. * Get index table name with additional suffix
  59. *
  60. * @param string $table
  61. * @return string
  62. */
  63. public function getIdxTable($table = null)
  64. {
  65. if ($table) {
  66. return $this->tableStrategy->prepareTableName($table);
  67. }
  68. return $this->tableStrategy->prepareTableName($this->getMainTable());
  69. }
  70. /**
  71. * Synchronize data between index storage and original storage
  72. *
  73. * @return $this
  74. */
  75. public function syncData()
  76. {
  77. $this->beginTransaction();
  78. try {
  79. /**
  80. * Can't use truncate because of transaction
  81. */
  82. $this->getConnection()->delete($this->getMainTable());
  83. $this->insertFromTable($this->getIdxTable(), $this->getMainTable(), false);
  84. $this->commit();
  85. } catch (\Exception $e) {
  86. $this->rollBack();
  87. throw $e;
  88. }
  89. return $this;
  90. }
  91. /**
  92. * Copy data from source table of read adapter to destination table of index adapter
  93. *
  94. * @param string $sourceTable
  95. * @param string $destTable
  96. * @param bool $readToIndex data migration direction (true - read=>index, false - index=>read)
  97. * @return $this
  98. */
  99. public function insertFromTable($sourceTable, $destTable, $readToIndex = true)
  100. {
  101. if ($readToIndex) {
  102. $sourceColumns = array_keys($this->getConnection()->describeTable($sourceTable));
  103. $targetColumns = array_keys($this->getConnection()->describeTable($destTable));
  104. } else {
  105. $sourceColumns = array_keys($this->_getIndexAdapter()->describeTable($sourceTable));
  106. $targetColumns = array_keys($this->getConnection()->describeTable($destTable));
  107. }
  108. $select = $this->_getIndexAdapter()->select()->from($sourceTable, $sourceColumns);
  109. $this->insertFromSelect($select, $destTable, $targetColumns, $readToIndex);
  110. return $this;
  111. }
  112. /**
  113. * Insert data from select statement of read adapter to
  114. * destination table related with index adapter
  115. *
  116. * @param Select $select
  117. * @param string $destTable
  118. * @param array $columns
  119. * @param bool $readToIndex data migration direction (true - read=>index, false - index=>read)
  120. * @return $this
  121. */
  122. public function insertFromSelect($select, $destTable, array $columns, $readToIndex = true)
  123. {
  124. if ($readToIndex) {
  125. $from = $this->getConnection();
  126. $to = $this->_getIndexAdapter();
  127. } else {
  128. $from = $this->_getIndexAdapter();
  129. $to = $this->getConnection();
  130. }
  131. if ($from === $to) {
  132. $query = $select->insertFromSelect($destTable, $columns);
  133. $to->query($query);
  134. } else {
  135. $stmt = $from->query($select);
  136. $data = [];
  137. $counter = 0;
  138. while ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
  139. $data[] = $row;
  140. $counter++;
  141. if ($counter > 2000) {
  142. $to->insertArray($destTable, $columns, $data);
  143. $data = [];
  144. $counter = 0;
  145. }
  146. }
  147. if (!empty($data)) {
  148. $to->insertArray($destTable, $columns, $data);
  149. }
  150. }
  151. return $this;
  152. }
  153. /**
  154. * Clean up temporary index table
  155. *
  156. * @return void
  157. */
  158. public function clearTemporaryIndexTable()
  159. {
  160. $this->getConnection()->delete($this->getIdxTable());
  161. }
  162. }