KTV/app/Console/Commands/TransferSqliteToMysql.php

91 lines
2.9 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
}
}