mirror of
https://github.com/alexjustesen/speedtest-tracker.git
synced 2026-06-23 07:20:09 +00:00
feat: add SQLite vacuum maintenance action and schedule (#2760)
Co-authored-by: Alex Justesen <1144087+alexjustesen@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class VacuumDatabase
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
/**
|
||||
* Reclaim unused pages and refresh query planner stats on SQLite databases.
|
||||
* No-op for other drivers, which handle this internally.
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$connection = DB::connection();
|
||||
|
||||
if ($connection->getDriverName() !== 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// VACUUM cannot run inside a transaction. Bail out rather than fail hard
|
||||
// if one is somehow active (e.g. tests wrapped in RefreshDatabase).
|
||||
if ($connection->transactionLevel() > 0) {
|
||||
Log::warning('Skipping SQLite maintenance: active transaction detected.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$connection->statement('PRAGMA optimize;');
|
||||
$connection->statement('VACUUM;');
|
||||
|
||||
Log::info('SQLite maintenance completed', [
|
||||
'duration_ms' => round((microtime(true) - $start) * 1000, 2),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\CheckForScheduledSpeedtests;
|
||||
use App\Actions\VacuumDatabase;
|
||||
use Illuminate\Support\Facades\Schedule;
|
||||
|
||||
/**
|
||||
@@ -28,3 +29,13 @@ Schedule::everyMinute()
|
||||
->group(function () {
|
||||
Schedule::call(fn () => CheckForScheduledSpeedtests::run());
|
||||
});
|
||||
|
||||
/**
|
||||
* Weekly SQLite maintenance (no-op on other drivers).
|
||||
*/
|
||||
Schedule::call(fn () => VacuumDatabase::run())
|
||||
->weekly()
|
||||
->sundays()
|
||||
->at('03:15')
|
||||
->name('sqlite-vacuum')
|
||||
->onOneServer();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\VacuumDatabase;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
describe('VacuumDatabase', function () {
|
||||
it('skips silently when the default connection is not sqlite', function () {
|
||||
Log::spy();
|
||||
|
||||
VacuumDatabase::run();
|
||||
|
||||
Log::shouldNotHaveReceived('info');
|
||||
Log::shouldNotHaveReceived('warning');
|
||||
});
|
||||
|
||||
it('runs PRAGMA optimize and VACUUM on a sqlite connection', function () {
|
||||
Config::set('database.connections.sqlite_vacuum_test', [
|
||||
'driver' => 'sqlite',
|
||||
'database' => ':memory:',
|
||||
'prefix' => '',
|
||||
'foreign_key_constraints' => true,
|
||||
]);
|
||||
Config::set('database.default', 'sqlite_vacuum_test');
|
||||
DB::purge();
|
||||
|
||||
$statements = [];
|
||||
DB::listen(function ($query) use (&$statements) {
|
||||
$statements[] = $query->sql;
|
||||
});
|
||||
|
||||
Log::spy();
|
||||
|
||||
VacuumDatabase::run();
|
||||
|
||||
expect($statements)->toContain('PRAGMA optimize;');
|
||||
expect($statements)->toContain('VACUUM;');
|
||||
Log::shouldHaveReceived('info')
|
||||
->with('SQLite maintenance completed', Mockery::type('array'))
|
||||
->once();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user