@echo off REM ============================================================================ REM Scoreboard 一键备份(Windows) REM REM 用 sqlite3.exe 的 VACUUM INTO 生成一致性快照,服务运行中也能安全执行, REM 不需要停服务、不需要重启。产物落在 data\backups\,滚动保留最近 20 份。 REM REM 依赖:sqlite3.exe(放到本脚本同目录、项目根目录,或加入 PATH 均可)。 REM 下载地址 https://www.sqlite.org/download.html 的 sqlite-tools-win-x64。 REM REM 用法:deploy\backup.bat 手动备份(原因记 manual) REM deploy\backup.bat publish 发布前备份(原因记 publish) REM ============================================================================ setlocal enabledelayedexpansion chcp 65001 >nul 2>&1 cd /d "%~dp0.." set "ROOT=%CD%" set "DATA=%ROOT%\data" set "OUT=%DATA%\backups" set "KEEP=20" set "REASON=manual" if not "%~1"=="" set "REASON=%~1" set "REASON=%REASON: =_%" set "REASON=%REASON:/=-%" set "REASON=%REASON:\=-%" set "REASON=%REASON:"=%" if not exist "%DATA%" ( echo [错误] 找不到数据目录:%DATA% echo 请在项目根目录执行本脚本。 exit /b 1 ) REM ---- 定位 sqlite3.exe ------------------------------------------------------- set "SQLITE=" if exist "%~dp0sqlite3.exe" set "SQLITE=%~dp0sqlite3.exe" if not defined SQLITE if exist "%ROOT%\sqlite3.exe" set "SQLITE=%ROOT%\sqlite3.exe" if not defined SQLITE for %%I in (sqlite3.exe) do if exist "%%~$PATH:I" set "SQLITE=%%~$PATH:I" if not defined SQLITE ( echo [错误] 找不到 sqlite3.exe。 echo 请把它放到 deploy\ 目录或加入 PATH 后重试。 exit /b 1 ) REM ---- 时间戳:优先 PowerShell,避免受区域设置影响 ----------------------------- set "TS=" for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "Get-Date -Format yyyyMMdd-HHmmss" 2^>nul`) do set "TS=%%I" if not defined TS call :fallback_ts if not defined TS ( echo [错误] 无法生成时间戳。 exit /b 1 ) if not exist "%OUT%" mkdir "%OUT%" echo === Scoreboard 备份 === echo 数据目录:%DATA% echo 备份目录:%OUT% echo 时间戳 :%TS% echo. set /a OK=0 set /a FAIL=0 if exist "%DATA%\system.db" call :backup "system" "%DATA%\system.db" for /d %%D in ("%DATA%\event_projs\*") do ( if exist "%%~fD\event.db" call :backup "%%~nxD" "%%~fD\event.db" ) echo. echo === 滚动清理(保留最近 %KEEP% 份)=== set /a N=0 for /f "delims=" %%F in ('dir /b /o-d /a-d "%OUT%\*.db" 2^>nul') do ( set /a N+=1 if !N! GTR %KEEP% ( echo 删除 %%F del /f /q "%OUT%\%%F" >nul 2>&1 ) ) echo. echo === 备份完成:成功 !OK! 个,失败 !FAIL! 个 === dir /b "%OUT%\*.db" 2>nul if !FAIL! GTR 0 ( endlocal exit /b 1 ) endlocal exit /b 0 REM ---- 备份单个库:%1 文件名前缀,%2 数据库路径 ------------------------------- :backup set "PREFIX=%~1" set "DBFILE=%~2" set "TARGET=%OUT%\%PREFIX%-%REASON%-%TS%.db" if exist "%TARGET%" set "TARGET=%OUT%\%PREFIX%-%REASON%-%TS%-%RANDOM%.db" echo 备份 %DBFILE% echo -^> %TARGET% "%SQLITE%" "%DBFILE%" "VACUUM INTO '%TARGET%'" if errorlevel 1 ( echo [失败] sqlite3 返回错误 set /a FAIL+=1 ) else ( set /a OK+=1 ) exit /b 0 REM ---- %DATE%/%TIME% 兜底:只保证名字不重复 ----------------------------------- :fallback_ts set "D=%DATE%" set "T=%TIME%" set "D=%D:/=%" set "D=%D:-=%" set "D=%D:.=%" set "T=%T::=%" set "T=%T:.=%" set "T=%T: =0%" set "TS=%D%-%T%" exit /b 0