Beta_cartrigesg_bd Beta v0.1

This commit is contained in:
2026-07-25 16:41:27 +03:00
parent d8cee567d7
commit 86e8e60ed2
13 changed files with 1122 additions and 29 deletions

View File

@@ -0,0 +1,179 @@
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$PsqlPath,
[Parameter(Mandatory = $true)]
[string]$AdminUser,
[Parameter(Mandatory = $true)]
[string]$AdminPassword,
[Parameter(Mandatory = $true)]
[ValidateRange(1, 65535)]
[int]$PostgreSqlPort,
[Parameter(Mandatory = $true)]
[string]$DatabaseName,
[Parameter(Mandatory = $true)]
[string]$DatabaseUser,
[Parameter(Mandatory = $true)]
[string]$DatabasePassword,
[Parameter(Mandatory = $true)]
[ValidateRange(1, 65535)]
[int]$ApplicationPort,
[Parameter(Mandatory = $true)]
[string]$ConfigPath
)
$ErrorActionPreference = 'Stop'
trap {
$logDirectory = Split-Path -Parent $ConfigPath
New-Item -ItemType Directory -Path $logDirectory -Force -ErrorAction SilentlyContinue | Out-Null
$_ | Out-String | Set-Content -LiteralPath (Join-Path $logDirectory 'install-error.log') -Encoding UTF8
$env:PGPASSWORD = $null
exit 1
}
function Assert-SafeIdentifier {
param([string]$Value, [string]$Label)
if ($Value -notmatch '^[A-Za-z_][A-Za-z0-9_]*$') {
throw "$Label содержит недопустимые символы."
}
}
function Quote-Identifier {
param([string]$Value)
return '"' + $Value.Replace('"', '""') + '"'
}
function Quote-Literal {
param([string]$Value)
return "'" + $Value.Replace("'", "''") + "'"
}
function Invoke-Psql {
param(
[string]$Database,
[string]$Sql,
[switch]$Capture
)
$arguments = @(
'--host', '127.0.0.1',
'--port', [string]$PostgreSqlPort,
'--username', $AdminUser,
'--dbname', $Database,
'--no-password',
'--set', 'ON_ERROR_STOP=1',
'--tuples-only',
'--no-align',
'--command', $Sql
)
if ($Capture) {
$output = & $PsqlPath @arguments 2>&1
if ($LASTEXITCODE -ne 0) {
throw ($output -join [Environment]::NewLine)
}
return ($output -join [Environment]::NewLine).Trim()
}
& $PsqlPath @arguments
if ($LASTEXITCODE -ne 0) {
throw "psql завершился с кодом $LASTEXITCODE."
}
}
if (-not (Test-Path -LiteralPath $PsqlPath -PathType Leaf)) {
throw "Не найден psql.exe: $PsqlPath"
}
Assert-SafeIdentifier -Value $AdminUser -Label 'Логин администратора PostgreSQL'
Assert-SafeIdentifier -Value $DatabaseName -Label 'Имя базы данных'
Assert-SafeIdentifier -Value $DatabaseUser -Label 'Логин пользователя базы данных'
$env:PGPASSWORD = $AdminPassword
$connected = $false
$lastConnectionError = $null
for ($attempt = 1; $attempt -le 45; $attempt++) {
try {
Invoke-Psql -Database 'postgres' -Sql 'SELECT 1;' | Out-Null
$connected = $true
break
}
catch {
$lastConnectionError = $_
Start-Sleep -Seconds 2
}
}
if (-not $connected) {
throw "Не удалось подключиться к PostgreSQL на порту $PostgreSqlPort. $lastConnectionError"
}
$databaseIdentifier = Quote-Identifier $DatabaseName
$databaseLiteral = Quote-Literal $DatabaseName
$userIdentifier = Quote-Identifier $DatabaseUser
$userLiteral = Quote-Literal $DatabaseUser
$passwordLiteral = Quote-Literal $DatabasePassword
$roleExists = Invoke-Psql -Database 'postgres' -Sql "SELECT 1 FROM pg_roles WHERE rolname = $userLiteral;" -Capture
if ($roleExists -eq '1') {
Invoke-Psql -Database 'postgres' -Sql "ALTER ROLE $userIdentifier WITH LOGIN PASSWORD $passwordLiteral;"
}
else {
Invoke-Psql -Database 'postgres' -Sql "CREATE ROLE $userIdentifier WITH LOGIN PASSWORD $passwordLiteral;"
}
$databaseExists = Invoke-Psql -Database 'postgres' -Sql "SELECT 1 FROM pg_database WHERE datname = $databaseLiteral;" -Capture
if ($databaseExists -ne '1') {
Invoke-Psql -Database 'postgres' -Sql "CREATE DATABASE $databaseIdentifier OWNER $userIdentifier ENCODING 'UTF8';"
}
else {
Invoke-Psql -Database 'postgres' -Sql "ALTER DATABASE $databaseIdentifier OWNER TO $userIdentifier;"
}
Invoke-Psql -Database 'postgres' -Sql "GRANT ALL PRIVILEGES ON DATABASE $databaseIdentifier TO $userIdentifier;"
$env:PGPASSWORD = $DatabasePassword
$testArguments = @(
'--host', '127.0.0.1',
'--port', [string]$PostgreSqlPort,
'--username', $DatabaseUser,
'--dbname', $DatabaseName,
'--no-password',
'--set', 'ON_ERROR_STOP=1',
'--command', 'SELECT 1;'
)
& $PsqlPath @testArguments | Out-Null
if ($LASTEXITCODE -ne 0) {
throw 'Не удалось проверить подключение с учётными данными приложения.'
}
$configDirectory = Split-Path -Parent $ConfigPath
New-Item -ItemType Directory -Path $configDirectory -Force | Out-Null
$config = [ordered]@{
database = [ordered]@{
host = '127.0.0.1'
port = $PostgreSqlPort
name = $DatabaseName
user = $DatabaseUser
password = $DatabasePassword
}
application = [ordered]@{
host = '0.0.0.0'
port = $ApplicationPort
}
}
$config | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $ConfigPath -Encoding UTF8
$env:PGPASSWORD = $null
Write-Host "База данных $DatabaseName и конфигурация Inventera подготовлены."