# Executes a .sql file against a database whose structure Flyway does not maintain.
|
#
|
# Why this exists: the shared dev database (talent_card) runs with spring.flyway.enabled=false, and
|
# its structure is not maintained by the migrations. Only the merchant-onboarding tables are patched
|
# by a startup initializer, so a new column on another table has to be applied by hand or the first
|
# request that touches it fails with "Unknown column ...". See docs/agents/testing.md.
|
#
|
# Usage:
|
# .\scripts\apply-sql-file.ps1 -File scripts\dev-schema-v152-payment-attempt.sql -Yes
|
# .\scripts\apply-sql-file.ps1 -File src\main\resources\db\migration\V152__payment_attempt_convergence.sql -Yes
|
# .\scripts\apply-sql-file.ps1 -File <file> # prints the statements without executing
|
#
|
# The target defaults to the shared dev database. It is a shared database, so the script executes
|
# nothing unless -Yes is given, and it prints the exact target and statements first.
|
#
|
# Do NOT point this at the test database: that schema is rebuilt from db/migration by the test run,
|
# and hand-applied DDL there makes the migrations and the history table disagree.
|
param(
|
[Parameter(Mandatory = $true)][string] $File,
|
[switch] $Yes,
|
[string] $Database = 'talent_card',
|
[string] $DatabaseHost = '192.168.110.13',
|
[int] $Port = 3306,
|
[string] $User = 'root',
|
[string] $Password = '123456'
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
function Find-MySqlDriver {
|
$roots = @()
|
if ($env:MAVEN_REPO_LOCAL) { $roots += $env:MAVEN_REPO_LOCAL }
|
$roots += (Join-Path $env:USERPROFILE '.m2\repository')
|
foreach ($root in $roots) {
|
if (-not $root -or -not (Test-Path $root)) { continue }
|
# 本地仓库里是旧 artifactId(mysql-connector-java-8.0.23.jar),上游后来改名为
|
# mysql-connector-j,两个都要能匹配到。
|
$jar = Get-ChildItem -Path $root -Recurse -Filter 'mysql-connector-*.jar' -ErrorAction SilentlyContinue |
|
Where-Object { $_.Name -notmatch 'sources|javadoc' } |
|
Sort-Object FullName -Descending |
|
Select-Object -First 1
|
if ($jar) { return $jar.FullName }
|
}
|
return $null
|
}
|
|
function Get-JavaExecutable {
|
$candidates = @()
|
if ($env:JAVA_HOME) { $candidates += (Join-Path $env:JAVA_HOME 'bin\java.exe') }
|
$candidates += 'java'
|
foreach ($candidate in $candidates) {
|
$command = Get-Command $candidate -ErrorAction SilentlyContinue
|
if ($command) { return $command.Source }
|
}
|
throw 'No java executable found. Set JAVA_HOME or add java to PATH.'
|
}
|
|
$script = Join-Path $PSScriptRoot $File
|
if (-not (Test-Path $script)) { $script = (Resolve-Path $File -ErrorAction SilentlyContinue) }
|
if (-not $script -or -not (Test-Path $script)) { throw "SQL file not found: $File" }
|
|
$driver = Find-MySqlDriver
|
if (-not $driver) {
|
throw 'mysql-connector-j was not found in the Maven local repository. Run ".\mvnw.cmd -o test-compile" once so Maven downloads the project dependencies.'
|
}
|
$java = Get-JavaExecutable
|
$url = "jdbc:mysql://${DatabaseHost}:${Port}/${Database}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false"
|
$program = Join-Path $PSScriptRoot 'ApplySqlFile.java'
|
|
Write-Host "Target: ${Database} on ${DatabaseHost}:${Port} (host/port/database are all overridable)" -ForegroundColor Cyan
|
Write-Host "File: $script" -ForegroundColor Cyan
|
|
if (-not $Yes) {
|
Write-Host 'Dry run: the statements are printed but not executed. Add -Yes to execute.' -ForegroundColor Yellow
|
& $java --class-path $driver $program $url $User $Password $script '--dry-run'
|
exit $LASTEXITCODE
|
}
|
|
& $java --class-path $driver $program $url $User $Password $script
|
if ($LASTEXITCODE -ne 0) { throw "Apply failed (exit $LASTEXITCODE). Driver: $driver" }
|