104 lines
3.3 KiB
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}");
|
|
}
|
|
} |