Initial V2 commit
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Add missing indexes + api_key/api_secret columns for HMAC auth
|
||||
*
|
||||
* SAFE: Only adds columns/indexes — does NOT modify existing data
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// ══════════════════════════════════════════════
|
||||
// PRIMARY DATABASE — Add API columns
|
||||
// ══════════════════════════════════════════════
|
||||
|
||||
// Add api_key and api_secret to driver table
|
||||
if (!Schema::connection('primary')->hasColumn('driver', 'api_key')) {
|
||||
Schema::connection('primary')->table('driver', function (Blueprint $table) {
|
||||
$table->string('api_key', 64)->nullable()->after('expirationDate');
|
||||
$table->string('api_secret', 128)->nullable()->after('api_key');
|
||||
$table->index('api_key', 'idx_driver_api_key');
|
||||
});
|
||||
}
|
||||
|
||||
// Add api_key and api_secret to passengers table
|
||||
if (!Schema::connection('primary')->hasColumn('passengers', 'api_key')) {
|
||||
Schema::connection('primary')->table('passengers', function (Blueprint $table) {
|
||||
$table->string('api_key', 64)->nullable()->after('maritalStatus');
|
||||
$table->string('api_secret', 128)->nullable()->after('api_key');
|
||||
$table->index('api_key', 'idx_passenger_api_key');
|
||||
});
|
||||
}
|
||||
|
||||
// Add api_key to adminUser
|
||||
if (!Schema::connection('primary')->hasColumn('adminUser', 'api_key')) {
|
||||
Schema::connection('primary')->table('adminUser', function (Blueprint $table) {
|
||||
$table->string('api_key', 64)->nullable()->after('name');
|
||||
$table->string('api_secret', 128)->nullable()->after('api_key');
|
||||
$table->string('password_hash', 255)->nullable()->after('api_secret');
|
||||
});
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════
|
||||
// MISSING INDEXES — Performance optimization
|
||||
// ══════════════════════════════════════════════
|
||||
|
||||
// driver_orders: missing index on order_id (used in every ride lifecycle query)
|
||||
$this->addIndexIfMissing('primary', 'driver_orders', 'idx_do_order', 'order_id');
|
||||
$this->addCompoundIndexIfMissing('primary', 'driver_orders', 'idx_do_driver_status', ['driver_id', 'status']);
|
||||
|
||||
// ride: compound index for status queries (most common query pattern)
|
||||
$this->addCompoundIndexIfMissing('primary', 'ride', 'idx_ride_pass_status', ['passenger_id', 'status']);
|
||||
$this->addCompoundIndexIfMissing('primary', 'ride', 'idx_ride_status_id', ['status', 'id']);
|
||||
|
||||
// tokens: index on fingerPrint for device verification queries
|
||||
$this->addCompoundIndexIfMissing('primary', 'tokens', 'idx_tokens_fp', ['passengerID', 'fingerPrint']);
|
||||
|
||||
// ══════════════════════════════════════════════
|
||||
// RIDE DATABASE — Same indexes
|
||||
// ══════════════════════════════════════════════
|
||||
$this->addIndexIfMissing('ride', 'driver_orders', 'idx_do_order', 'order_id');
|
||||
$this->addCompoundIndexIfMissing('ride', 'driver_orders', 'idx_do_driver_status', ['driver_id', 'status']);
|
||||
|
||||
// ══════════════════════════════════════════════
|
||||
// TRACKING DATABASE — car_tracks index (missing)
|
||||
// ══════════════════════════════════════════════
|
||||
// Note: tracking DB already has idx_driver_time on car_tracks
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Reversible: drop added columns and indexes
|
||||
Schema::connection('primary')->table('driver', function (Blueprint $table) {
|
||||
$table->dropIndex('idx_driver_api_key');
|
||||
$table->dropColumn(['api_key', 'api_secret']);
|
||||
});
|
||||
Schema::connection('primary')->table('passengers', function (Blueprint $table) {
|
||||
$table->dropIndex('idx_passenger_api_key');
|
||||
$table->dropColumn(['api_key', 'api_secret']);
|
||||
});
|
||||
}
|
||||
|
||||
// ── Helper Methods ──
|
||||
|
||||
private function addIndexIfMissing(string $connection, string $table, string $indexName, string $column): void
|
||||
{
|
||||
$exists = DB::connection($connection)
|
||||
->select("SHOW INDEX FROM `{$table}` WHERE Key_name = ?", [$indexName]);
|
||||
|
||||
if (empty($exists)) {
|
||||
DB::connection($connection)->statement("CREATE INDEX `{$indexName}` ON `{$table}` (`{$column}`)");
|
||||
}
|
||||
}
|
||||
|
||||
private function addCompoundIndexIfMissing(string $connection, string $table, string $indexName, array $columns): void
|
||||
{
|
||||
$exists = DB::connection($connection)
|
||||
->select("SHOW INDEX FROM `{$table}` WHERE Key_name = ?", [$indexName]);
|
||||
|
||||
if (empty($exists)) {
|
||||
$cols = implode('`, `', $columns);
|
||||
DB::connection($connection)->statement("CREATE INDEX `{$indexName}` ON `{$table}` (`{$cols}`)");
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user