# One-time: copy data from old Windows PostgreSQL (port 5432) into data/postgres param( [string]$Root = '', [string]$PgBin, [string]$PgData, [int]$Port = 0 ) . "$PSScriptRoot\db-local.ps1" if (-not $Root) { $Root = Get-ProjectRoot -FromScript $PSScriptRoot } if (-not $Port) { $Port = $LocalDbPort } $ErrorActionPreference = 'Stop' function Parse-DatabaseUrl { param([string]$Url) if ($Url -match '^postgresql://([^:]+):([^@]+)@([^:/]+):(\d+)/(.+)$') { return @{ User = $Matches[1] Password = $Matches[2] Host = $Matches[3] Port = [int]$Matches[4] Database = $Matches[5] } } return $null } function Test-LegacyDatabase { param($Legacy) if (-not $Legacy) { return $false } if ($Legacy.Port -eq $Port) { return $false } if (-not (Test-DbPortOpen -Port $Legacy.Port)) { return $false } $env:PGPASSWORD = $Legacy.Password try { $psql = Join-Path $PgBin 'psql.exe' $count = & $psql -h $Legacy.Host -p $Legacy.Port -U $Legacy.User -d $Legacy.Database -tAc 'SELECT COUNT(*) FROM tasks' 2>$null return ($LASTEXITCODE -eq 0 -and [int]$count -gt 0) } catch { return $false } finally { Remove-Item Env:PGPASSWORD -ErrorAction SilentlyContinue } } $envPath = Join-Path $Root 'backend\.env' $legacy = $null if (Test-Path $envPath) { $line = Get-Content $envPath -Encoding UTF8 | Where-Object { $_ -match '^DATABASE_URL=' } | Select-Object -First 1 if ($line -match '^DATABASE_URL="(.+)"') { $legacy = Parse-DatabaseUrl $Matches[1] } } # Also probe common Windows install (5432 / postgres) when folder is still empty if (-not (Test-LegacyDatabase -Legacy $legacy)) { $legacy = @{ User = 'postgres' Password = $LocalDbPassword Host = 'localhost' Port = 5432 Database = $LocalDbName } if (-not (Test-LegacyDatabase -Legacy $legacy)) { return $false } } Write-Host ' [이전] Windows PostgreSQL 데이터를 data\postgres 로 옮기는 중...' $dumpPath = Join-Path $Root 'data\_legacy_migrate.dump' $initdb = Join-Path $PgBin 'initdb.exe' $pgCtl = Join-Path $PgBin 'pg_ctl.exe' $pgRestore = Join-Path $PgBin 'pg_restore.exe' $pgDump = Join-Path $PgBin 'pg_dump.exe' $env:PGPASSWORD = $legacy.Password & $pgDump -h $legacy.Host -p $legacy.Port -U $legacy.User -d $legacy.Database -F c -f $dumpPath --no-owner --no-acl if ($LASTEXITCODE -ne 0) { Remove-Item Env:PGPASSWORD -ErrorAction SilentlyContinue Remove-Item $dumpPath -ErrorAction SilentlyContinue throw 'legacy pg_dump failed' } Remove-Item Env:PGPASSWORD -ErrorAction SilentlyContinue & $initdb -D $PgData -U $LocalDbUser -E UTF8 --locale=C -A trust if ($LASTEXITCODE -ne 0) { throw 'initdb failed' } Set-PostgresPort -PgData $PgData -Port $Port $logFile = Get-PgCtlLogPath -Root $Root & $pgCtl -D $PgData -l $logFile -o "-p $Port" start -w -t 60 if ($LASTEXITCODE -ne 0) { throw 'pg_ctl start failed (migrate)' } Start-Sleep -Seconds 2 Invoke-Psql -PgBin $PgBin -Port $Port -Sql "ALTER USER $LocalDbUser WITH PASSWORD '$LocalDbPassword';" Invoke-Psql -PgBin $PgBin -Port $Port -Sql "CREATE DATABASE $LocalDbName OWNER $LocalDbUser;" $env:PGPASSWORD = $LocalDbPassword & $pgRestore -h 127.0.0.1 -p $Port -U $LocalDbUser -d $LocalDbName --no-owner --no-acl $dumpPath 2>&1 | Out-Null Remove-Item Env:PGPASSWORD -ErrorAction SilentlyContinue if ($LASTEXITCODE -ge 2) { & $pgCtl -D $PgData stop -m fast throw 'pg_restore failed' } Remove-Item $dumpPath -ErrorAction SilentlyContinue Ensure-BackendEnv -Root $Root Write-Host ' [이전] 완료 — 이제 DB는 data\postgres 에 저장됩니다.' return $true