KTVCentral/app/Jobs/TransferSqliteTableJob.php

104 lines
3.3 KiB
PHP

<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\DB;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class TransferSqliteTableJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected string $sqlitePath;
protected bool $deleteFile;
public function __construct(string $sqlitePath , bool $deleteFile = false){
$this->sqlitePath=$sqlitePath;
$this->deleteFile = $deleteFile;
}
public function handle(): void
{
if (!file_exists($this->sqlitePath)) {
logger()->error("❌ SQLite file not found: {$this->sqlitePath}");
return;
}
// ✅ 動態產生唯一 connection 名稱
$connectionName = 'sqlite_' . md5($this->sqlitePath . microtime());
config(["database.connections.{$connectionName}" => [
'driver' => 'sqlite',
'database' => $this->sqlitePath,
'prefix' => '',
]]);
$mysqlConnection = config('database.default');
$sqliteTables = DB::connection($connectionName)->select("
SELECT name FROM sqlite_master
WHERE type='table' AND name NOT LIKE 'sqlite_%';
");
if (empty($sqliteTables)) {
logger()->error("❌ No tables found in SQLite database.");
DB::purge($connectionName);
return;
}
foreach ($sqliteTables as $tableObj) {
$table = $tableObj->name;
if ($table === 'migrations') {
continue;
}
try {
DB::connection($mysqlConnection)->statement('SET FOREIGN_KEY_CHECKS=0;');
DB::statement("CREATE TABLE IF NOT EXISTS _{$table} LIKE {$table}");
$rows = DB::connection($connectionName)->table($table)->cursor();
$buffer = [];
$count = 0;
foreach ($rows as $row) {
$buffer[] = (array) $row;
$count++;
if ($count % 500 === 0) {
DB::connection($mysqlConnection)->table("_{$table}")->insert($buffer);
$buffer = [];
}
}
if (!empty($buffer)) {
DB::connection($mysqlConnection)->table("_{$table}")->insert($buffer);
}
DB::statement("DROP TABLE IF EXISTS {$table};");
DB::statement("RENAME TABLE _{$table} TO {$table};");
logger()->info("✅ Imported: {$table} ({$count} records)");
} catch (\Exception $e) {
logger()->error("❌ Failed to import {$table}: " . $e->getMessage());
} finally {
DB::connection($mysqlConnection)->statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
// 🔥 結束後刪檔與釋放 connection
DB::purge($connectionName);
if ($this->deleteFile && file_exists($this->sqlitePath)) {
sleep(1);
unlink($this->sqlitePath);
logger()->info("🧹 Deleted SQLite file: {$this->sqlitePath}");
}
logger()->info("🎉 SQLite import completed: {$this->sqlitePath}");
}
}