-
Notifications
You must be signed in to change notification settings - Fork 518
/
CalculateCompletenessCommand.php
135 lines (114 loc) · 4.19 KB
/
CalculateCompletenessCommand.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php
namespace Akeneo\Pim\Enrichment\Bundle\Command;
use Akeneo\Pim\Enrichment\Bundle\Elasticsearch\Indexer\ProductAndAncestorsIndexer;
use Akeneo\Pim\Enrichment\Bundle\Product\ComputeAndPersistProductCompletenesses;
use Doctrine\DBAL\Connection;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Calculate the completeness of the products
*
* @author Gildas Quemener <[email protected]>
* @copyright 2013 Akeneo SAS (http://www.akeneo.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
class CalculateCompletenessCommand extends Command
{
use LockableTrait;
private const DEFAULT_BATCH_SIZE = 1000;
protected static $defaultName = 'pim:completeness:calculate';
/** @var ProductAndAncestorsIndexer */
private $productAndAncestorsIndexer;
/** @var ComputeAndPersistProductCompletenesses */
private $computeAndPersistProductCompleteness;
/** @var Connection */
private $connection;
public function __construct(
ProductAndAncestorsIndexer $productANdAncestorsIndexer,
ComputeAndPersistProductCompletenesses $computeAndPersistProductCompleteness,
Connection $connection
) {
parent::__construct();
$this->productAndAncestorsIndexer = $productANdAncestorsIndexer;
$this->computeAndPersistProductCompleteness = $computeAndPersistProductCompleteness;
$this->connection = $connection;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setDescription('Launch the product completeness calculation')
->addOption(
'batch-size',
false,
InputArgument::OPTIONAL,
'The number of product completeness calculated in one cycle.',
self::DEFAULT_BATCH_SIZE
)
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->lock()) {
$output->writeln(sprintf('The command "%s" is still running in another process.', self::$defaultName));
return 0;
}
$batchSize = (int) $input->getOption('batch-size') ?: self::DEFAULT_BATCH_SIZE;
$progressBar = new ProgressBar($output, $this->getTotalNumberOfProducts());
$output->writeln('<info>Computing product completenesses...</info>');
$progressBar->start();
foreach ($this->getProductUuids($batchSize) as $productUuids) {
$this->computeAndPersistProductCompleteness->fromProductUuids($productUuids);
$this->productAndAncestorsIndexer->indexFromProductUuids($productUuids);
$progressBar->advance(count($productUuids));
}
$progressBar->finish();
$output->writeln('');
$output->writeln('<info>Completeness successfully computed.</info>');
return 0;
}
private function getTotalNumberOfProducts(): int
{
return $this->connection->executeQuery('SELECT COUNT(0) FROM pim_catalog_product')->fetchOne();
}
private function getProductUuids(int $batchSize): iterable
{
$lastUuidAsBytes = '';
$sql = <<<SQL
SELECT uuid
FROM pim_catalog_product
WHERE uuid > :lastUuid
ORDER BY uuid ASC
LIMIT :limit
SQL;
while (true) {
$rows = $this->connection->fetchFirstColumn(
$sql,
[
'lastUuid' => $lastUuidAsBytes,
'limit' => $batchSize,
],
[
'lastUuid' => \PDO::PARAM_STR,
'limit' => \PDO::PARAM_INT,
]
);
if (empty($rows)) {
return;
}
$lastUuidAsBytes = end($rows);
yield array_map(fn (string $uuidAsBytes): UuidInterface => Uuid::fromBytes($uuidAsBytes), $rows);
}
}
}