Fix daily_summary dan hourly_summary aggregation, tambah fallback logic untuk dashboard, update validator untuk camera dan location type
This commit is contained in:
150
bin/run_migrations.php
Normal file
150
bin/run_migrations.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Script untuk menjalankan migration yang belum dijalankan
|
||||
* Usage: php bin/run_migrations.php
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use App\Config\AppConfig;
|
||||
use App\Support\Database;
|
||||
|
||||
// Load environment variables
|
||||
AppConfig::loadEnv(__DIR__ . '/..');
|
||||
|
||||
echo "=== Menjalankan Database Migrations ===\n\n";
|
||||
|
||||
// Get database connection
|
||||
$dbHost = AppConfig::get('DB_HOST', 'localhost');
|
||||
$dbName = AppConfig::get('DB_NAME', '');
|
||||
$dbUser = AppConfig::get('DB_USER', '');
|
||||
$dbPass = AppConfig::get('DB_PASS', '');
|
||||
|
||||
if (empty($dbName) || empty($dbUser)) {
|
||||
echo "❌ Error: Database credentials tidak lengkap di .env\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
$db = Database::getConnection($dbHost, $dbName, $dbUser, $dbPass);
|
||||
|
||||
$migrationsDir = __DIR__ . '/../migrations';
|
||||
$migrationFiles = [
|
||||
'001_create_audit_logs.sql',
|
||||
'002_create_hourly_summary.sql',
|
||||
'003_create_realtime_events.sql',
|
||||
'004_add_camera_to_gates.sql'
|
||||
];
|
||||
|
||||
foreach ($migrationFiles as $migrationFile) {
|
||||
$migrationPath = $migrationsDir . '/' . $migrationFile;
|
||||
|
||||
if (!file_exists($migrationPath)) {
|
||||
echo "⚠️ File migration tidak ditemukan: {$migrationFile}\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "Menjalankan: {$migrationFile}...\n";
|
||||
|
||||
$sql = file_get_contents($migrationPath);
|
||||
|
||||
// Remove comments and clean up SQL
|
||||
$sql = preg_replace('/--.*$/m', '', $sql);
|
||||
$sql = preg_replace('/\/\*.*?\*\//s', '', $sql);
|
||||
|
||||
// Split by semicolon, but keep multi-line statements intact
|
||||
$statements = [];
|
||||
$currentStatement = '';
|
||||
$lines = explode("\n", $sql);
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (empty($line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$currentStatement .= $line . "\n";
|
||||
|
||||
// If line ends with semicolon, it's a complete statement
|
||||
if (substr(rtrim($line), -1) === ';') {
|
||||
$stmt = trim($currentStatement);
|
||||
if (!empty($stmt) && strlen($stmt) > 5) {
|
||||
$statements[] = $stmt;
|
||||
}
|
||||
$currentStatement = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Add any remaining statement
|
||||
if (!empty(trim($currentStatement))) {
|
||||
$statements[] = trim($currentStatement);
|
||||
}
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
if (empty(trim($statement))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$db->exec($statement);
|
||||
} catch (\PDOException $e) {
|
||||
// Skip jika error karena table/column sudah ada
|
||||
$errorMsg = $e->getMessage();
|
||||
if (strpos($errorMsg, 'already exists') !== false ||
|
||||
strpos($errorMsg, 'Duplicate column') !== false ||
|
||||
strpos($errorMsg, 'Duplicate key name') !== false) {
|
||||
echo " ⚠️ Sudah ada: " . substr($errorMsg, 0, 100) . "\n";
|
||||
} else {
|
||||
echo " ❌ Error: " . $errorMsg . "\n";
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo " ✅ Selesai: {$migrationFile}\n\n";
|
||||
}
|
||||
|
||||
echo "=== Migration Selesai ===\n";
|
||||
|
||||
// Verifikasi tabel
|
||||
echo "\n=== Verifikasi Tabel ===\n";
|
||||
$requiredTables = ['audit_logs', 'hourly_summary', 'realtime_events'];
|
||||
|
||||
foreach ($requiredTables as $table) {
|
||||
try {
|
||||
$stmt = $db->query("SHOW TABLES LIKE '{$table}'");
|
||||
$exists = $stmt->fetch() !== false;
|
||||
|
||||
if ($exists) {
|
||||
echo " ✅ Tabel '{$table}' ada\n";
|
||||
} else {
|
||||
echo " ❌ Tabel '{$table}' tidak ada\n";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo " ❌ Error cek tabel '{$table}': " . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Cek field camera di gates
|
||||
echo "\n=== Verifikasi Field Camera di Gates ===\n";
|
||||
try {
|
||||
$stmt = $db->query("SHOW COLUMNS FROM gates LIKE 'camera'");
|
||||
$exists = $stmt->fetch() !== false;
|
||||
|
||||
if ($exists) {
|
||||
echo " ✅ Field 'camera' ada di tabel gates\n";
|
||||
} else {
|
||||
echo " ❌ Field 'camera' tidak ada di tabel gates\n";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo " ❌ Error cek field camera: " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "❌ Error: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user