123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\DB\Query;
- use Magento\Framework\Exception\LocalizedException;
- /**
- * Query generator
- */
- class Generator
- {
- /**
- * @var \Magento\Framework\DB\Query\BatchIteratorFactory
- */
- private $iteratorFactory;
- /**
- * @var \Magento\Framework\DB\Query\BatchRangeIteratorFactory
- */
- private $rangeIteratorFactory;
- /**
- * Initialize dependencies.
- *
- * @param BatchIteratorFactory $iteratorFactory
- * @param BatchRangeIteratorFactory $rangeIteratorFactory
- */
- public function __construct(
- BatchIteratorFactory $iteratorFactory,
- BatchRangeIteratorFactory $rangeIteratorFactory = null
- ) {
- $this->iteratorFactory = $iteratorFactory;
- $this->rangeIteratorFactory = $rangeIteratorFactory ?: \Magento\Framework\App\ObjectManager::getInstance()
- ->get(\Magento\Framework\DB\Query\BatchRangeIteratorFactory::class);
- }
- /**
- * Generate select query list with predefined items count in each select item
- *
- * Generates select parameters - batchSize, correlationName, rangeField, rangeFieldAlias
- * to obtain instance of iterator. The behavior of the iterator will depend on the parameters passed to it.
- * For example: by default for $batchStrategy parameter used
- * \Magento\Framework\DB\Query\BatchIteratorInterface::UNIQUE_FIELD_ITERATOR. This parameter is determine, what
- * instance of Iterator will be returned.
- *
- * Other params:
- * select - represents the select object, that should be passed into Iterator.
- * batchSize - sets the number of items in select.
- * correlationName - is the base table involved in the select.
- * rangeField - this is the basic field which used to split select.
- * rangeFieldAlias - alias of range field.
- *
- * @see \Magento\Framework\DB\Query\BatchIteratorInterface
- * @param string $rangeField - Field which is used for the range mechanism in select
- * @param \Magento\Framework\DB\Select $select
- * @param int $batchSize - Determines on how many parts will be divided
- * the number of values in the select.
- * @param string $batchStrategy It determines which strategy is chosen
- * @return BatchIteratorInterface
- * @throws LocalizedException Throws if incorrect "FROM" part in \Select exists
- */
- public function generate(
- $rangeField,
- \Magento\Framework\DB\Select $select,
- $batchSize = 100,
- $batchStrategy = \Magento\Framework\DB\Query\BatchIteratorInterface::UNIQUE_FIELD_ITERATOR
- ) {
- if ($batchStrategy == \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR) {
- return $this->generateByRange($rangeField, $select, $batchSize);
- }
- $fromSelect = $select->getPart(\Magento\Framework\DB\Select::FROM);
- if (empty($fromSelect)) {
- throw new LocalizedException(
- new \Magento\Framework\Phrase(
- 'The select object must have the correct "FROM" part. Verify and try again.'
- )
- );
- }
- $fieldCorrelationName = '';
- foreach ($fromSelect as $correlationName => $fromPart) {
- if ($fromPart['joinType'] == \Magento\Framework\DB\Select::FROM) {
- $fieldCorrelationName = $correlationName;
- break;
- }
- }
- $columns = $select->getPart(\Magento\Framework\DB\Select::COLUMNS);
- /**
- * Calculate $rangeField alias
- */
- $rangeFieldAlias = $rangeField;
- foreach ($columns as $column) {
- list($table, $columnName, $alias) = $column;
- if ($table == $fieldCorrelationName && $columnName == $rangeField) {
- $rangeFieldAlias = $alias ?: $rangeField;
- break;
- }
- }
- return $this->iteratorFactory->create(
- [
- 'select' => $select,
- 'batchSize' => $batchSize,
- 'correlationName' => $fieldCorrelationName,
- 'rangeField' => $rangeField,
- 'rangeFieldAlias' => $rangeFieldAlias
- ]
- );
- }
- /**
- * Generate select query list with predefined items count in each select item.
- *
- * Generates select parameters - batchSize, correlationName, rangeField, rangeFieldAlias
- * to obtain instance of BatchRangeIterator.
- *
- * Other params:
- * select - represents the select object, that should be passed into Iterator.
- * batchSize - sets the number of items in select.
- * correlationName - is the base table involved in the select.
- * rangeField - this is the basic field which used to split select.
- * rangeFieldAlias - alias of range field.
- *
- * @see BatchRangeIterator
- * @param string $rangeField - Field which is used for the range mechanism in select
- * @param \Magento\Framework\DB\Select $select
- * @param int $batchSize
- * @return BatchIteratorInterface
- * @throws LocalizedException Throws if incorrect "FROM" part in \Select exists
- * @see \Magento\Framework\DB\Query\Generator
- * @deprecated 100.1.8 This is a temporary solution which is made due to the fact that we
- * can't change method generate() in version 2.1 due to a backwards incompatibility.
- * In 2.2 version need to use original method generate() with additional parameter.
- */
- public function generateByRange(
- $rangeField,
- \Magento\Framework\DB\Select $select,
- $batchSize = 100
- ) {
- $fromSelect = $select->getPart(\Magento\Framework\DB\Select::FROM);
- if (empty($fromSelect)) {
- throw new LocalizedException(
- new \Magento\Framework\Phrase(
- 'The select object must have the correct "FROM" part. Verify and try again.'
- )
- );
- }
- $fieldCorrelationName = '';
- foreach ($fromSelect as $correlationName => $fromPart) {
- if ($fromPart['joinType'] == \Magento\Framework\DB\Select::FROM) {
- $fieldCorrelationName = $correlationName;
- break;
- }
- }
- $columns = $select->getPart(\Magento\Framework\DB\Select::COLUMNS);
- /**
- * Calculate $rangeField alias
- */
- $rangeFieldAlias = $rangeField;
- foreach ($columns as $column) {
- list($table, $columnName, $alias) = $column;
- if ($table == $fieldCorrelationName && $columnName == $rangeField) {
- $rangeFieldAlias = $alias ?: $rangeField;
- break;
- }
- }
- return $this->rangeIteratorFactory->create(
- [
- 'select' => $select,
- 'batchSize' => $batchSize,
- 'correlationName' => $fieldCorrelationName,
- 'rangeField' => $rangeField,
- 'rangeFieldAlias' => $rangeFieldAlias,
- ]
- );
- }
- }
|