New_Micro_Learning/scripts/configure-local-mysql.ps1

103 خطوط
4.3 KiB
PowerShell

param([switch] $Elevated)
$ErrorActionPreference = 'Stop'
$projectRoot = Split-Path -Parent $PSScriptRoot
$logPath = Join-Path $projectRoot 'mysql-local-setup.log'
if (-not $Elevated) {
$arguments = @(
'-NoProfile',
'-ExecutionPolicy', 'Bypass',
'-File', ('"{0}"' -f $PSCommandPath),
'-Elevated'
)
$process = Start-Process -FilePath 'powershell.exe' -ArgumentList $arguments -Verb RunAs -Wait -PassThru
exit $process.ExitCode
}
$serviceName = 'MySQL80'
$mysqlBase = 'C:\Program Files\MySQL\MySQL Server 8.0'
$mysqldPath = Join-Path $mysqlBase 'bin\mysqld.exe'
$mysqlPath = Join-Path $mysqlBase 'bin\mysql.exe'
$defaultsFile = 'C:\ProgramData\MySQL\MySQL Server 8.0\my.ini'
$originalConfig = [IO.File]::ReadAllText($defaultsFile)
$initFile = 'C:\ProgramData\MySQL\microlearn-init.sql'
$mysqlErrorLog = 'C:\ProgramData\MySQL\MySQL Server 8.0\Data\TOORNAA.err'
$envFile = Join-Path $projectRoot 'backend\.env'
$passwordBytes = New-Object byte[] 24
$randomNumberGenerator = [Security.Cryptography.RandomNumberGenerator]::Create()
$randomNumberGenerator.GetBytes($passwordBytes)
$randomNumberGenerator.Dispose()
$password = ([BitConverter]::ToString($passwordBytes)).Replace('-', '').ToLowerInvariant()
$sql = @"
CREATE DATABASE IF NOT EXISTS microlearn CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS microlearn_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'microlearn'@'localhost' IDENTIFIED BY '$password';
ALTER USER 'microlearn'@'localhost' IDENTIFIED BY '$password';
CREATE USER IF NOT EXISTS 'microlearn'@'127.0.0.1' IDENTIFIED BY '$password';
ALTER USER 'microlearn'@'127.0.0.1' IDENTIFIED BY '$password';
GRANT ALL PRIVILEGES ON microlearn.* TO 'microlearn'@'localhost';
GRANT ALL PRIVILEGES ON microlearn_test.* TO 'microlearn'@'localhost';
GRANT ALL PRIVILEGES ON microlearn.* TO 'microlearn'@'127.0.0.1';
GRANT ALL PRIVILEGES ON microlearn_test.* TO 'microlearn'@'127.0.0.1';
FLUSH PRIVILEGES;
"@
[IO.File]::WriteAllText($initFile, $sql, [Text.UTF8Encoding]::new($false))
$initFileForMySql = $initFile.Replace('\', '/')
try {
Stop-Service -Name $serviceName -Force
[IO.File]::WriteAllText(
$defaultsFile,
($originalConfig.TrimEnd() + "`r`ninit-file=$initFileForMySql`r`n"),
[Text.UTF8Encoding]::new($false)
)
Start-Service -Name $serviceName
$deadline = [DateTime]::UtcNow.AddSeconds(45)
do {
Start-Sleep -Milliseconds 500
$service = Get-Service -Name $serviceName
} until ($service.Status -eq 'Running' -or [DateTime]::UtcNow -ge $deadline)
if ($service.Status -ne 'Running') {
throw 'MySQL service did not start with the one-time initialization file.'
}
$env:MYSQL_PWD = $password
& $mysqlPath --protocol=TCP --host=127.0.0.1 --port=3306 --user=microlearn --skip-column-names --execute='SELECT 1' | Out-Null
if ($LASTEXITCODE -ne 0) {
throw 'The MicroLearn MySQL account could not connect after initialization.'
}
$contents = [IO.File]::ReadAllText($envFile)
$contents = [Regex]::Replace($contents, '(?m)^DB_CONNECTION=.*$', 'DB_CONNECTION=mysql')
$contents = [Regex]::Replace($contents, '(?m)^DB_HOST=.*$', 'DB_HOST=127.0.0.1')
$contents = [Regex]::Replace($contents, '(?m)^DB_PORT=.*$', 'DB_PORT=3306')
$contents = [Regex]::Replace($contents, '(?m)^DB_DATABASE=.*$', 'DB_DATABASE=microlearn')
$contents = [Regex]::Replace($contents, '(?m)^DB_USERNAME=.*$', 'DB_USERNAME=microlearn')
$contents = [Regex]::Replace($contents, '(?m)^DB_PASSWORD=.*$', "DB_PASSWORD=$password")
[IO.File]::WriteAllText($envFile, $contents, [Text.UTF8Encoding]::new($false))
'MySQL databases, application user, and backend environment configured.' | Set-Content -LiteralPath $logPath
}
catch {
$details = $_ | Out-String
if (Test-Path -LiteralPath $mysqlErrorLog) {
$details += "`r`nMySQL error log:`r`n"
$details += (Get-Content -LiteralPath $mysqlErrorLog -Tail 80 | Out-String)
}
$details | Set-Content -LiteralPath $logPath
throw
}
finally {
$env:MYSQL_PWD = $null
Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
[IO.File]::WriteAllText($defaultsFile, $originalConfig, [Text.UTF8Encoding]::new($false))
Start-Service -Name $serviceName
Remove-Item -LiteralPath $initFile -Force -ErrorAction SilentlyContinue
}