PageRenderTime 28ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/magento/framework/DB/FieldDataConverter.php

https://bitbucket.org/sergiu-tot-fb/vendors
PHP | 144 lines | 84 code | 10 blank | 50 comment | 5 complexity | d404c49b46795ab3c60419a50bbbd3e5 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MIT, Apache-2.0
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\DB;
  7. use Magento\Framework\DB\Adapter\AdapterInterface;
  8. use Magento\Framework\DB\DataConverter\DataConversionException;
  9. use Magento\Framework\DB\DataConverter\DataConverterInterface;
  10. use Magento\Framework\DB\Query\Generator;
  11. use Magento\Framework\DB\Select\QueryModifierInterface;
  12. /**
  13. * Convert field data from one representation to another
  14. */
  15. class FieldDataConverter
  16. {
  17. /**
  18. * Batch size env variable name
  19. */
  20. const BATCH_SIZE_VARIABLE_NAME = 'DATA_CONVERTER_BATCH_SIZE';
  21. /**
  22. * Default batch size
  23. */
  24. const DEFAULT_BATCH_SIZE = 50000;
  25. /**
  26. * @var Generator
  27. */
  28. private $queryGenerator;
  29. /**
  30. * @var DataConverterInterface
  31. */
  32. private $dataConverter;
  33. /**
  34. * @var SelectFactory
  35. */
  36. private $selectFactory;
  37. /**
  38. * @var string|null
  39. */
  40. private $envBatchSize;
  41. /**
  42. * Constructor
  43. *
  44. * @param Generator $queryGenerator
  45. * @param DataConverterInterface $dataConverter
  46. * @param SelectFactory $selectFactory
  47. * @param string|null $envBatchSize
  48. */
  49. public function __construct(
  50. Generator $queryGenerator,
  51. DataConverterInterface $dataConverter,
  52. SelectFactory $selectFactory,
  53. $envBatchSize = null
  54. ) {
  55. $this->queryGenerator = $queryGenerator;
  56. $this->dataConverter = $dataConverter;
  57. $this->selectFactory = $selectFactory;
  58. $this->envBatchSize = $envBatchSize;
  59. }
  60. /**
  61. * Convert table field data from one representation to another
  62. *
  63. * @param AdapterInterface $connection
  64. * @param string $table
  65. * @param string $identifier
  66. * @param string $field
  67. * @param QueryModifierInterface|null $queryModifier
  68. * @throws FieldDataConversionException
  69. * @return void
  70. */
  71. public function convert(
  72. AdapterInterface $connection,
  73. $table,
  74. $identifier,
  75. $field,
  76. QueryModifierInterface $queryModifier = null
  77. ) {
  78. $select = $this->selectFactory->create($connection)
  79. ->from($table, [$identifier, $field])
  80. ->where($field . ' IS NOT NULL');
  81. if ($queryModifier) {
  82. $queryModifier->modify($select);
  83. }
  84. $iterator = $this->queryGenerator->generate($identifier, $select, $this->getBatchSize());
  85. foreach ($iterator as $selectByRange) {
  86. $rows = $connection->fetchPairs($selectByRange);
  87. $uniqueFieldDataArray = array_unique($rows);
  88. foreach ($uniqueFieldDataArray as $uniqueFieldData) {
  89. $ids = array_keys($rows, $uniqueFieldData);
  90. try {
  91. $convertedValue = $this->dataConverter->convert($uniqueFieldData);
  92. if ($uniqueFieldData === $convertedValue) {
  93. // Skip for data rows that have been already converted
  94. continue;
  95. }
  96. $bind = [$field => $convertedValue];
  97. $where = [$identifier . ' IN (?)' => $ids];
  98. $connection->update($table, $bind, $where);
  99. } catch (DataConversionException $e) {
  100. throw new \Magento\Framework\DB\FieldDataConversionException(
  101. sprintf(
  102. \Magento\Framework\DB\FieldDataConversionException::MESSAGE_PATTERN,
  103. $field,
  104. $table,
  105. $identifier,
  106. implode(', ', $ids),
  107. get_class($this->dataConverter),
  108. $e->getMessage()
  109. )
  110. );
  111. }
  112. }
  113. }
  114. }
  115. /**
  116. * Get batch size from environment variable or default
  117. *
  118. * @return int
  119. */
  120. private function getBatchSize()
  121. {
  122. if (null !== $this->envBatchSize) {
  123. $batchSize = (int) $this->envBatchSize;
  124. if (bccomp($this->envBatchSize, PHP_INT_MAX, 0) === 1 || $batchSize < 1) {
  125. throw new \InvalidArgumentException(
  126. 'Invalid value for environment variable ' . self::BATCH_SIZE_VARIABLE_NAME . '. '
  127. . 'Should be integer, >= 1 and < value of PHP_INT_MAX'
  128. );
  129. }
  130. return $batchSize;
  131. }
  132. return self::DEFAULT_BATCH_SIZE;
  133. }
  134. }