mirror of
https://github.com/alexjustesen/speedtest-tracker.git
synced 2026-06-23 04:20:08 +00:00
[Chore] Removed bad json functions and squashed migrations (#1911)
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use App\Enums\ResultStatus;
|
||||
use App\Models\User;
|
||||
use App\Settings\DataMigrationSettings;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class MigrateBadJsonResults
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public int $jobTimeout = 60 * 5;
|
||||
|
||||
public int $jobTries = 1;
|
||||
|
||||
public function handle(User $user)
|
||||
{
|
||||
$dataSettings = new DataMigrationSettings;
|
||||
|
||||
$tableName = 'results_bad_json';
|
||||
|
||||
if ($dataSettings->bad_json_migrated) {
|
||||
Notification::make()
|
||||
->title('❌ Hmmm it seems someone has already migrated the data!')
|
||||
->body('Check your results table and make sure you\'re not triggering a duplicate data migration.')
|
||||
->danger()
|
||||
->sendToDatabase($user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('results')) {
|
||||
Notification::make()
|
||||
->title('❌ Could not migrate bad json results!')
|
||||
->body('The "results" table is missing.')
|
||||
->danger()
|
||||
->sendToDatabase($user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! Schema::hasTable($tableName)) {
|
||||
Notification::make()
|
||||
->title('❌ Could not migrate bad json results!')
|
||||
->body('The "results_bad_json" table is missing.')
|
||||
->danger()
|
||||
->sendToDatabase($user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy backup data to the new results table and reformat it.
|
||||
*/
|
||||
try {
|
||||
DB::table($tableName)->chunkById(100, function ($results) {
|
||||
foreach ($results as $result) {
|
||||
$record = [
|
||||
'service' => 'ookla',
|
||||
'ping' => $result->ping,
|
||||
'download' => $result->download,
|
||||
'upload' => $result->upload,
|
||||
'comments' => $result->comments,
|
||||
'data' => json_decode($result->data),
|
||||
'status' => match ($result->successful) {
|
||||
1 => ResultStatus::Completed,
|
||||
true => ResultStatus::Completed,
|
||||
default => ResultStatus::Failed,
|
||||
},
|
||||
'scheduled' => $result->scheduled,
|
||||
'created_at' => $result->created_at,
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
DB::table('results')->insert($record);
|
||||
}
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
Log::error($e);
|
||||
|
||||
Notification::make()
|
||||
->title('There was an issue migrating the data!')
|
||||
->body('Check the logs for an output of the issue.')
|
||||
->danger()
|
||||
->sendToDatabase($user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$dataSettings->bad_json_migrated = true;
|
||||
|
||||
$dataSettings->save();
|
||||
|
||||
Notification::make()
|
||||
->title('Data migration completed!')
|
||||
->body('Your history has been successfully migrated.')
|
||||
->success()
|
||||
->sendToDatabase($user);
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,16 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Actions\MigrateBadJsonResults;
|
||||
use App\Enums\ResultStatus;
|
||||
use App\Filament\Exports\ResultExporter;
|
||||
use App\Filament\Resources\ResultResource\Pages;
|
||||
use App\Helpers\Number;
|
||||
use App\Jobs\TruncateResults;
|
||||
use App\Models\Result;
|
||||
use App\Settings\DataMigrationSettings;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Tables;
|
||||
@@ -156,8 +153,6 @@ class ResultResource extends Resource
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
$dataSettings = new DataMigrationSettings;
|
||||
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
@@ -407,21 +402,6 @@ class ResultResource extends Resource
|
||||
Tables\Actions\ExportAction::make()
|
||||
->exporter(ResultExporter::class)
|
||||
->fileName(fn (): string => 'results-'.now()->timestamp),
|
||||
Tables\Actions\Action::make('migrate')
|
||||
->action(function (): void {
|
||||
Notification::make()
|
||||
->title('Starting data migration...')
|
||||
->body('This can take a little bit depending how much data you have.')
|
||||
->warning()
|
||||
->sendToDatabase(Auth::user());
|
||||
|
||||
MigrateBadJsonResults::dispatch(Auth::user());
|
||||
})
|
||||
->hidden($dataSettings->bad_json_migrated)
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Migrate History')
|
||||
->modalDescription(new HtmlString('<p>v0.16.0 archived the old <code>"results"</code> table, to migrate your history click the button below.</p><p>For more information read the <a href="#" target="_blank" rel="nofollow" class="underline">docs</a>.</p>'))
|
||||
->modalSubmitActionLabel('Yes, migrate it'),
|
||||
Tables\Actions\ActionGroup::make([
|
||||
Tables\Actions\Action::make('truncate')
|
||||
->action(fn () => TruncateResults::dispatch(Auth::user()))
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class DataMigrationSettings extends Settings
|
||||
{
|
||||
public bool $bad_json_migrated;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'data_migration';
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
@@ -18,8 +21,17 @@ return new class extends Migration
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->string('role')->default('user');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
User::create([
|
||||
'name' => 'Admin',
|
||||
'email' => 'admin@example.com',
|
||||
'email_verified_at' => now(),
|
||||
'password' => Hash::make('password'),
|
||||
'role' => UserRole::Admin,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,17 +13,15 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('results', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->float('ping', 8, 3);
|
||||
$table->unsignedBigInteger('download'); // will be stored in bytes
|
||||
$table->unsignedBigInteger('upload'); // will be stored in bytes
|
||||
$table->integer('server_id')->nullable();
|
||||
$table->string('server_host')->nullable();
|
||||
$table->string('server_name')->nullable();
|
||||
$table->string('url')->nullable();
|
||||
$table->string('service')->default('ookla');
|
||||
$table->float('ping', 8, 3)->nullable();
|
||||
$table->unsignedBigInteger('download')->nullable();
|
||||
$table->unsignedBigInteger('upload')->nullable();
|
||||
$table->text('comments')->nullable();
|
||||
$table->json('data')->nullable();
|
||||
$table->string('status');
|
||||
$table->boolean('scheduled')->default(false);
|
||||
$table->json('data'); // is a dump of the cli output in case we want more fields later
|
||||
$table->timestamp('created_at')
|
||||
->useCurrent();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
User::create([
|
||||
'name' => 'Admin',
|
||||
'email' => 'admin@example.com',
|
||||
'email_verified_at' => now(),
|
||||
'password' => Hash::make('password'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('results', function (Blueprint $table) {
|
||||
$table->float('ping', 8, 3)->nullable()->change();
|
||||
$table->unsignedBigInteger('download')->nullable()->change();
|
||||
$table->unsignedBigInteger('upload')->nullable()->change();
|
||||
$table->json('data')->nullable()->change();
|
||||
|
||||
$table->boolean('successful')->default(true)->after('scheduled');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('results', function (Blueprint $table) {
|
||||
$table->text('comments')->nullable()->after('url');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('role')
|
||||
->nullable()
|
||||
->after('remember_token');
|
||||
});
|
||||
|
||||
$user = User::first();
|
||||
|
||||
if ($user) {
|
||||
$user->role = 'admin';
|
||||
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('role');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\User;
|
||||
use App\Settings\DataMigrationSettings;
|
||||
use Filament\Notifications\Actions\Action;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('results_bad_json')) {
|
||||
if (Schema::hasTable('results')) {
|
||||
/**
|
||||
* Rename the existing table so that a backup copy exists.
|
||||
*/
|
||||
Schema::rename('results', 'results_bad_json');
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('results') && Schema::hasTable('results_bad_json')) {
|
||||
/**
|
||||
* Create a new results table based on a new DDL schema.
|
||||
*/
|
||||
Schema::create('results', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('service')->default('ookla');
|
||||
$table->float('ping', 8, 3)->nullable();
|
||||
$table->unsignedBigInteger('download')->nullable();
|
||||
$table->unsignedBigInteger('upload')->nullable();
|
||||
$table->text('comments')->nullable();
|
||||
$table->json('data')->nullable();
|
||||
$table->string('status');
|
||||
$table->boolean('scheduled')->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't disable the schedule or send a notification if there are no records.
|
||||
*/
|
||||
if (! DB::table('results_bad_json')->count()) {
|
||||
$dataSettings = new DataMigrationSettings;
|
||||
|
||||
$dataSettings->bad_json_migrated = true;
|
||||
|
||||
$dataSettings->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$admins = User::where('role', '=', UserRole::Admin)->get();
|
||||
|
||||
foreach ($admins as $user) {
|
||||
Notification::make()
|
||||
->title('Breaking change, user action required!')
|
||||
->body('v0.16.0 includes a breaking change to resolve a data quality issue. Read the release notes regarding the data migration.')
|
||||
->danger()
|
||||
->actions([
|
||||
Action::make('Release notes')
|
||||
->button()
|
||||
->url('https://github.com/alexjustesen/speedtest-tracker/releases/tag/v0.16.0')
|
||||
->openUrlInNewTab(),
|
||||
])
|
||||
->sendToDatabase($user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::drop('results');
|
||||
|
||||
if (! Schema::hasTable('results')) {
|
||||
Schema::rename('results_bad_json', 'results');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
return new class extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->add('data_migration.bad_json_migrated', false);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user