KTV/app/Console/Commands/TransferSqliteToMysql.php

91 lines
2.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Config;
class TransferSqliteToMysql extends Command
{
protected $signature = 'transfer:sqlite {path : SQLite 相對路徑sqlite/song.sqlite} ';
protected $description = 'Transfer all data from SQLite to MySQL, optionally truncating tables first.';
public function handle(): int
{
$path = ltrim($this->argument('path'), '/');
$this->info("[Transfer] 開始轉移 SQLite 資料:{$path}");
if (!file_exists($path)) {
$this->error("[Transfer] 找不到 SQLite 檔案:{$path}");
return 1;
}
// ✅ 動態產生唯一 connection 名稱
$connectionName = 'sqlite_' . md5($path . microtime());
config(["database.connections.{$connectionName}" => [
'driver' => 'sqlite',
'database' => $path,
'prefix' => '',
]]);
$this->info("🚀 Starting transfer from SQLite to MySQL...");
// 讀取 SQLite 資料庫的所有資料表
$sqliteTables = DB::connection($connectionName)->select("
SELECT name FROM sqlite_master
WHERE type='table' AND name NOT LIKE 'sqlite_%';
");
if (empty($sqliteTables)) {
$this->error("❌ No tables found in SQLite database.");
return 1;
}
// 取得 .env 中指定的 MySQL 連線名稱
$mysqlConnection = config('database.default'); // 默認會是 'mysql',如果 .env 修改會自動更新
foreach ($sqliteTables as $tableObj) {
$table = $tableObj->name;
// 忽略 Laravel 內部 migration 表
if ($table === 'migrations') {
continue;
}
$this->info("📦 Transferring table: {$table}");
try {
// 用 cursor 來避免一次性佔用過多記憶體
$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 = []; // 清空 buffer
}
}
// 插入剩下的資料
if (!empty($buffer)) {
DB::connection($mysqlConnection)->table($table)->insert($buffer);
}
$this->info("✅ Done: {$table} ({$count} records)");
} catch (\Exception $e) {
$this->error("❌ Failed to transfer {$table}: " . $e->getMessage());
}
}
$this->info("🎉 Transfer complete!");
return 0;
}
}