feat(migration): add Migrate-To-V2.ps1 idempotent migration runner

This commit is contained in:
Joseph Doherty
2026-05-26 04:26:01 -04:00
parent 605dbf3dcc
commit c168c1c9c6
4 changed files with 3348 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
<#
.SYNOPSIS
Idempotent migration runner that takes the OtOpcUaConfig database from the v1 schema
(with ConfigGeneration / ClusterNodeGenerationState) to the v2 hosting-aligned schema
(with Deployment / NodeDeploymentState / ConfigEdit / DataProtectionKeys).
.DESCRIPTION
Backs the database up, applies the idempotent EF migration script, then validates that
expected tables exist and legacy tables are gone. Safe to re-run — the EF script itself
is idempotent, and the backup picks a unique filename per invocation.
.PARAMETER ConnectionString
Mandatory. Full ADO.NET connection string with permissions to BACKUP DATABASE and
apply DDL on the target ConfigDb.
.PARAMETER BackupPath
Optional. Full path for the backup file. Defaults to a timestamped path under $env:TEMP.
.EXAMPLE
.\Migrate-To-V2.ps1 -ConnectionString "Server=sql01;Database=OtOpcUaConfig;Trusted_Connection=True;TrustServerCertificate=True"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][string] $ConnectionString,
[string] $BackupPath = "$env:TEMP\OtOpcUa-V1-Backup-$(Get-Date -Format yyyyMMddHHmmss).bak"
)
$ErrorActionPreference = 'Stop'
if (-not (Get-Command Invoke-Sqlcmd -ErrorAction SilentlyContinue)) {
throw "Invoke-Sqlcmd not available. Install module: Install-Module SqlServer -Scope CurrentUser"
}
Write-Host "Step 1/4 — Backup ConfigDb to $BackupPath" -ForegroundColor Cyan
Invoke-Sqlcmd -ConnectionString $ConnectionString `
-Query "BACKUP DATABASE [OtOpcUaConfig] TO DISK = '$BackupPath' WITH FORMAT, COMPRESSION"
Write-Host "Step 2/4 — Row counts (before)" -ForegroundColor Cyan
$beforeCounts = Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\count-rows.sql"
$beforeCounts | Format-Table
Write-Host "Step 3/4 — Apply Migrate-To-V2.sql" -ForegroundColor Cyan
Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\Migrate-To-V2.sql" -QueryTimeout 1800
Write-Host "Step 4/4 — Row counts (after) + validation" -ForegroundColor Cyan
$afterCounts = Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\count-rows.sql"
$afterCounts | Format-Table
$tablesNow = (Invoke-Sqlcmd -ConnectionString $ConnectionString `
-Query "SELECT name FROM sys.tables ORDER BY name").name
foreach ($t in 'Deployment','NodeDeploymentState','ConfigEdit','DataProtectionKeys') {
if ($tablesNow -notcontains $t) { throw "Expected v2 table $t missing." }
}
foreach ($t in 'ConfigGeneration','ClusterNodeGenerationState') {
if ($tablesNow -contains $t) { throw "Legacy v1 table $t still present." }
}
Write-Host "Migration complete. Backup at $BackupPath" -ForegroundColor Green