91 lines
2.9 KiB
PHP
91 lines
2.9 KiB
PHP
<?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;
|
||
}
|
||
} |