Passed
Push — main ( 7a6063...0cf387 )
by Lorenzo
10:35
created

PruneCacheInvalidationDataCommand   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 71
rs 10
wmc 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
A pruneTable() 0 25 2
A handle() 0 18 2
1
<?php
2
3
namespace Padosoft\SuperCacheInvalidate\Console;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Facades\DB;
7
8
class PruneCacheInvalidationDataCommand extends Command
9
{
10
    /**
11
     * The name and signature of the console command.
12
     *
13
     * @var string
14
     */
15
    protected $signature = 'supercache:prune-invalidation-data
16
                            {--months=1 : The number of months to retain data}';
17
18
    /**
19
     * The console command description.
20
     *
21
     * @var string
22
     */
23
    protected $description = 'Prune old cache invalidation data by dropping partitions';
24
25
    /**
26
     * Prune partitions in a table older than the retention partition key.
27
     *
28
     * @param string $tableName             The name of the table
29
     * @param int    $retentionPartitionKey The partition key cutoff
30
     */
31
    protected function pruneTable(string $tableName, int $retentionPartitionKey): void
32
    {
33
        // Fetch partition names
34
        $partitions = DB::select('
35
            SELECT PARTITION_NAME, PARTITION_DESCRIPTION
36
            FROM INFORMATION_SCHEMA.PARTITIONS
37
            WHERE TABLE_SCHEMA = DATABASE()
38
            AND TABLE_NAME = ?
39
            AND PARTITION_NAME IS NOT NULL
40
            AND PARTITION_DESCRIPTION < ?
41
        ', [$tableName, $retentionPartitionKey]);
42
43
        if (empty($partitions)) {
44
            $this->info("No partitions to prune for table {$tableName}.");
45
46
            return;
47
        }
48
49
        // Build DROP PARTITION statement
50
        $partitionNames = implode(', ', array_map(function ($partition) {
51
            return $partition->PARTITION_NAME;
52
        }, $partitions));
53
54
        DB::statement("ALTER TABLE `{$tableName}` DROP PARTITION {$partitionNames}");
55
        $this->info("Pruned partitions: {$partitionNames} from table {$tableName}.");
56
    }
57
58
    /**
59
     * Execute the console command.
60
     */
61
    public function handle(): void
62
    {
63
        $months = (int) $this->option('months');
64
        $retentionDate = now()->subMonths($months);
65
        $retentionPartitionKey = $retentionDate->year * 100 + $retentionDate->week();
66
67
        // Prune tables
68
        $tables = [
69
            'cache_invalidation_events',
70
            'cache_invalidation_timestamps',
71
            'cache_invalidation_event_associations',
72
        ];
73
74
        foreach ($tables as $tableName) {
75
            $this->pruneTable($tableName, $retentionPartitionKey);
76
        }
77
78
        $this->info('Old cache invalidation data has been pruned.');
79
    }
80
}
81