feat: complete V1 phases 0-7
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
param([Parameter(Mandatory=$true)][string]$OutputDirectory,[int]$RetentionDays=30)
|
||||
$ErrorActionPreference='Stop'
|
||||
if(-not $env:DATABASE_URL){throw 'DATABASE_URL is required'}
|
||||
$uri=[Uri]$env:DATABASE_URL
|
||||
if($uri.Scheme -ne 'mysql'){throw 'DATABASE_URL must use mysql'}
|
||||
$database=$uri.AbsolutePath.TrimStart('/')
|
||||
if(-not $database){throw 'database name is required'}
|
||||
$resolved=[IO.Path]::GetFullPath($OutputDirectory)
|
||||
New-Item -ItemType Directory -Force -Path $resolved | Out-Null
|
||||
$stamp=(Get-Date).ToUniversalTime().ToString('yyyyMMddTHHmmssZ')
|
||||
$target=Join-Path $resolved "$database-$stamp.sql"
|
||||
$credential=$uri.UserInfo.Split(':',2)
|
||||
$env:MYSQL_PWD=[Uri]::UnescapeDataString($credential[1])
|
||||
& mysqldump --single-transaction --set-gtid-purged=OFF --host $uri.Host --port $uri.Port --user ([Uri]::UnescapeDataString($credential[0])) --result-file $target $database
|
||||
if($LASTEXITCODE -ne 0){throw 'mysqldump failed'}
|
||||
$hash=(Get-FileHash -Algorithm SHA256 -LiteralPath $target).Hash.ToLowerInvariant()
|
||||
Set-Content -LiteralPath "$target.sha256" -Value "$hash $([IO.Path]::GetFileName($target))"
|
||||
Get-ChildItem -LiteralPath $resolved -File | Where-Object {$_.LastWriteTimeUtc -lt (Get-Date).ToUniversalTime().AddDays(-$RetentionDays) -and ($_.Extension -eq '.sql' -or $_.Name.EndsWith('.sql.sha256'))} | Remove-Item -Force
|
||||
Write-Output $target
|
||||
@@ -0,0 +1,15 @@
|
||||
param([Parameter(Mandatory=$true)][string]$BackupFile,[Parameter(Mandatory=$true)][string]$TargetDatabase)
|
||||
$ErrorActionPreference='Stop'
|
||||
if(-not $env:DATABASE_URL){throw 'DATABASE_URL is required'}
|
||||
if($TargetDatabase -notmatch '^[A-Za-z0-9_]+$'){throw 'TargetDatabase contains invalid characters'}
|
||||
$file=(Resolve-Path -LiteralPath $BackupFile).Path
|
||||
$checksum="$file.sha256"
|
||||
if(-not(Test-Path -LiteralPath $checksum)){throw 'checksum file is required'}
|
||||
$expected=(Get-Content -LiteralPath $checksum).Split(' ')[0]
|
||||
if((Get-FileHash -Algorithm SHA256 -LiteralPath $file).Hash.ToLowerInvariant() -ne $expected){throw 'backup checksum mismatch'}
|
||||
$uri=[Uri]$env:DATABASE_URL;$credential=$uri.UserInfo.Split(':',2);$env:MYSQL_PWD=[Uri]::UnescapeDataString($credential[1]);$user=[Uri]::UnescapeDataString($credential[0])
|
||||
& mysql --host $uri.Host --port $uri.Port --user $user --execute "CREATE DATABASE IF NOT EXISTS ``$TargetDatabase`` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
if($LASTEXITCODE -ne 0){throw 'target database creation failed'}
|
||||
Get-Content -LiteralPath $file -Raw | & mysql --host $uri.Host --port $uri.Port --user $user $TargetDatabase
|
||||
if($LASTEXITCODE -ne 0){throw 'restore failed'}
|
||||
Write-Output "Restore completed into $TargetDatabase"
|
||||
Reference in New Issue
Block a user