forked from wintercms/storm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProcessesQuery.php
More file actions
74 lines (63 loc) · 2.52 KB
/
Copy pathProcessesQuery.php
File metadata and controls
74 lines (63 loc) · 2.52 KB
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
<?php namespace Winter\Storm\Console\Traits;
use Winter\Storm\Database\Builder;
/**
* Console Command Trait that provides the "processQuery($query, $callback, $chunkSize, $limit)"
* helper method to cleanly handle processing a large number of records in the console.
*
* @package winter\storm
* @author Luke Towers
*/
trait ProcessesQuery
{
/**
* Processes the provided query by rendering a progress bar, chunking the
* query by the provided chunkSize, running the callback on each record and
* limiting number of records processed to the provided limit
*/
public function processQuery(Builder $query, callable $callback, int $chunkSize = 100, ?int $limit = null): void
{
$totalRecords = $query->count();
if (!$totalRecords) {
$this->warn("No records were found to process.");
return;
}
$progress = $this->output->createProgressBar($totalRecords);
$progress->setFormat('%current%/%max% [%bar%] %percent:3s%% (%elapsed:6s%/%estimated:-6s%)');
$recordsProcessed = 0;
$limitReached = false;
$query->chunkById($chunkSize, function ($records) use ($callback, $progress, &$recordsProcessed, $limit, &$limitReached) {
foreach ($records as $record) {
// Handle the limit being reached
if ($limit && $recordsProcessed >= $limit) {
$progress->finish();
$this->info('');
$this->error("Limit reached, " . number_format($recordsProcessed) . " records were processed.");
$limitReached = true;
return false;
}
try {
// Process the record
$callback($record);
} catch (\Throwable $e) {
$recordsProcessed--;
$this->error(sprintf(
"Failed to process ID %s: %s",
$record->getKey(),
$e->getMessage()
));
}
// Attempt to avoid out of memory issues
unset($record);
// Update the UI
$recordsProcessed++;
$progress->advance();
}
});
if (!$limitReached) {
$progress->finish();
$this->info('');
}
$this->info("Processed " . number_format($recordsProcessed) . " of " . number_format($totalRecords) . " records.");
$this->info('');
}
}