98 lines
3.1 KiB
PHP
98 lines
3.1 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace App\Console\Commands;
|
||
|
|
|
||
|
|
use App\Models\Event;
|
||
|
|
use App\Models\Issue;
|
||
|
|
use Illuminate\Console\Attributes\Description;
|
||
|
|
use Illuminate\Console\Attributes\Signature;
|
||
|
|
use Illuminate\Console\Command;
|
||
|
|
use Illuminate\Support\Carbon;
|
||
|
|
|
||
|
|
#[Signature('events:cleanup {--days=90 : Delete events older than this many days}')]
|
||
|
|
#[Description('Delete old events to free up database space while keeping issue summaries')]
|
||
|
|
class CleanupOldEvents extends Command
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Execute the console command.
|
||
|
|
*/
|
||
|
|
public function handle(): int
|
||
|
|
{
|
||
|
|
$days = (int) $this->option('days');
|
||
|
|
|
||
|
|
if ($days < 1) {
|
||
|
|
$this->error('Days must be at least 1');
|
||
|
|
return self::FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$cutoffDate = Carbon::now()->subDays($days);
|
||
|
|
|
||
|
|
$this->info("Deleting events older than {$days} days (before {$cutoffDate->toDateTimeString()})...");
|
||
|
|
|
||
|
|
// Get count of events to be deleted
|
||
|
|
$eventsToDelete = Event::where('created_at', '<', $cutoffDate)->count();
|
||
|
|
|
||
|
|
if ($eventsToDelete === 0) {
|
||
|
|
$this->info('No events to delete.');
|
||
|
|
return self::SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->confirm("This will delete {$eventsToDelete} events. Continue?", true)) {
|
||
|
|
$this->info('Cleanup cancelled.');
|
||
|
|
return self::SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Delete events in chunks to avoid memory issues
|
||
|
|
$deleted = 0;
|
||
|
|
$bar = $this->output->createProgressBar($eventsToDelete);
|
||
|
|
$bar->start();
|
||
|
|
|
||
|
|
Event::where('created_at', '<', $cutoffDate)
|
||
|
|
->chunkById(1000, function ($events) use (&$deleted, $bar) {
|
||
|
|
foreach ($events as $event) {
|
||
|
|
$event->delete();
|
||
|
|
$deleted++;
|
||
|
|
$bar->advance();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
$bar->finish();
|
||
|
|
$this->newLine(2);
|
||
|
|
|
||
|
|
$this->info("Deleted {$deleted} events.");
|
||
|
|
|
||
|
|
// Update issue counters based on remaining events
|
||
|
|
$this->info('Updating issue counters...');
|
||
|
|
|
||
|
|
$issues = Issue::all();
|
||
|
|
$issuesUpdated = 0;
|
||
|
|
|
||
|
|
foreach ($issues as $issue) {
|
||
|
|
$eventsCount = $issue->events()->count();
|
||
|
|
|
||
|
|
if ($eventsCount === 0) {
|
||
|
|
// If no events remain, optionally delete the issue or mark it
|
||
|
|
// For now, we'll keep the issue but mark times_seen as 0
|
||
|
|
$issue->update(['times_seen' => 0]);
|
||
|
|
$issuesUpdated++;
|
||
|
|
} else {
|
||
|
|
// Update counters based on remaining events
|
||
|
|
$firstEvent = $issue->events()->oldest('timestamp')->first();
|
||
|
|
$lastEvent = $issue->events()->latest('timestamp')->first();
|
||
|
|
|
||
|
|
$issue->update([
|
||
|
|
'times_seen' => $eventsCount,
|
||
|
|
'first_seen_at' => $firstEvent?->timestamp ?? $issue->first_seen_at,
|
||
|
|
'last_seen_at' => $lastEvent?->timestamp ?? $issue->last_seen_at,
|
||
|
|
]);
|
||
|
|
$issuesUpdated++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->info("Updated {$issuesUpdated} issues.");
|
||
|
|
$this->info('Cleanup completed successfully!');
|
||
|
|
|
||
|
|
return self::SUCCESS;
|
||
|
|
}
|
||
|
|
}
|