mirror of
https://devops.lemonos.cn/lawson/FendxPHP.git
synced 2026-06-15 23:12:49 +08:00
467 lines
13 KiB
PowerShell
467 lines
13 KiB
PowerShell
|
|
# FendxPHP 数据库检查 PowerShell 脚本
|
|||
|
|
# 用法: .\scripts\check-database.ps1 [选项]
|
|||
|
|
|
|||
|
|
param(
|
|||
|
|
[Parameter(Mandatory=$false)]
|
|||
|
|
[ValidateSet("check", "fix", "migrate", "seed", "help")]
|
|||
|
|
[string]$Action = "check"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 颜色输出函数
|
|||
|
|
function Write-ColorOutput {
|
|||
|
|
param(
|
|||
|
|
[string]$Message,
|
|||
|
|
[ConsoleColor]$Color = "White"
|
|||
|
|
)
|
|||
|
|
Write-Host $Message -ForegroundColor $Color
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Info {
|
|||
|
|
param([string]$Message)
|
|||
|
|
Write-ColorOutput "[INFO] $Message" -Color Cyan
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Success {
|
|||
|
|
param([string]$Message)
|
|||
|
|
Write-ColorOutput "[SUCCESS] $Message" -Color Green
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Warning {
|
|||
|
|
param([string]$Message)
|
|||
|
|
Write-ColorOutput "[WARNING] $Message" -Color Yellow
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Write-Error {
|
|||
|
|
param([string]$Message)
|
|||
|
|
Write-ColorOutput "[ERROR] $Message" -Color Red
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 加载环境配置
|
|||
|
|
function Load-Environment {
|
|||
|
|
$envFile = Join-Path $PSScriptRoot "..\.env"
|
|||
|
|
|
|||
|
|
if (Test-Path $envFile) {
|
|||
|
|
Write-Info "加载环境配置: $envFile"
|
|||
|
|
Get-Content $envFile | ForEach-Object {
|
|||
|
|
if ($_ -match '^([^=]+)=(.*)$' -and -not $_.StartsWith('#')) {
|
|||
|
|
$name = $matches[1].Trim()
|
|||
|
|
$value = $matches[2].Trim()
|
|||
|
|
[Environment]::SetEnvironmentVariable($name, $value, "Process")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
Write-Warning "环境配置文件不存在: $envFile"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 测试MySQL客户端
|
|||
|
|
function Test-MySQLClient {
|
|||
|
|
try {
|
|||
|
|
$result = & mysql --version 2>$null
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "MySQL客户端可用"
|
|||
|
|
return $true
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
# 忽略错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Warning "MySQL客户端不可用,尝试使用Docker"
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 测试数据库连接
|
|||
|
|
function Test-DatabaseConnection {
|
|||
|
|
$dbHost = if ($env:DB_HOST) { $env:DB_HOST } else { "localhost" }
|
|||
|
|
$dbPort = if ($env:DB_PORT) { $env:DB_PORT } else { "3306" }
|
|||
|
|
$dbDatabase = if ($env:DB_DATABASE) { $env:DB_DATABASE } else { "fendx_php" }
|
|||
|
|
$dbUsername = if ($env:DB_USERNAME) { $env:DB_USERNAME } else { "root" }
|
|||
|
|
$dbPassword = if ($env:DB_PASSWORD) { $env:DB_PASSWORD } else { "" }
|
|||
|
|
|
|||
|
|
$config = @{
|
|||
|
|
Host = $dbHost
|
|||
|
|
Port = $dbPort
|
|||
|
|
Database = $dbDatabase
|
|||
|
|
Username = $dbUsername
|
|||
|
|
Password = $dbPassword
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Info "检查数据库连接..."
|
|||
|
|
Write-Info " 主机: $($config.Host):$($config.Port)"
|
|||
|
|
Write-Info " 数据库: $($config.Database)"
|
|||
|
|
Write-Info " 用户名: $($config.Username)"
|
|||
|
|
|
|||
|
|
# 尝试使用MySQL客户端
|
|||
|
|
if (Test-MySQLClient) {
|
|||
|
|
try {
|
|||
|
|
& mysql -h $config.Host -P $config.Port -u $config.Username -p$config.Password -e "SELECT 1" 2>$null
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "数据库连接成功"
|
|||
|
|
return @{ Success = $true; Config = $config }
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
# 忽略错误
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 尝试使用Docker
|
|||
|
|
if (Get-Command docker -ErrorAction SilentlyContinue) {
|
|||
|
|
return Test-DockerDatabaseConnection $config
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Error "数据库连接失败"
|
|||
|
|
return @{ Success = $false }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 测试Docker数据库连接
|
|||
|
|
function Test-DockerDatabaseConnection {
|
|||
|
|
param($config)
|
|||
|
|
|
|||
|
|
Write-Info "尝试使用Docker连接数据库..."
|
|||
|
|
|
|||
|
|
# 检查Docker是否运行
|
|||
|
|
try {
|
|||
|
|
& docker info >$null 2>&1
|
|||
|
|
if ($LASTEXITCODE -ne 0) {
|
|||
|
|
Write-Error "Docker未运行"
|
|||
|
|
return @{ Success = $false }
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
Write-Error "Docker未运行"
|
|||
|
|
return @{ Success = $false }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 检查MySQL容器
|
|||
|
|
$containerName = "fendx-mysql-test"
|
|||
|
|
$container = & docker ps --filter "name=$containerName" --format "table {{.Names}}\t{{.Status}}" | Select-Object -Skip 1
|
|||
|
|
|
|||
|
|
if (-not $container -or $container -notlike "*Up*") {
|
|||
|
|
Write-Warning "MySQL容器未运行,尝试启动..."
|
|||
|
|
& docker-compose -f docker-compose.test.yml up -d mysql-test
|
|||
|
|
|
|||
|
|
# 等待启动
|
|||
|
|
Write-Info "等待MySQL启动..."
|
|||
|
|
$maxAttempts = 30
|
|||
|
|
$attempt = 0
|
|||
|
|
|
|||
|
|
while ($attempt -lt $maxAttempts) {
|
|||
|
|
try {
|
|||
|
|
& docker exec $containerName mysqladmin ping -h localhost --silent >$null 2>&1
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "MySQL启动成功"
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
# 忽略错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$attempt++
|
|||
|
|
Write-Host "." -NoNewline
|
|||
|
|
Start-Sleep -Seconds 2
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($attempt -eq $maxAttempts) {
|
|||
|
|
Write-Error "MySQL启动超时"
|
|||
|
|
& docker-compose -f docker-compose.test.yml logs mysql-test
|
|||
|
|
return @{ Success = $false }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 测试连接
|
|||
|
|
try {
|
|||
|
|
& docker exec $containerName mysql -u test -ptest -e "SELECT 1" >$null 2>&1
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "Docker数据库连接成功"
|
|||
|
|
return @{ Success = $true; Config = $config; Docker = $true }
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
# 忽略错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Error "Docker数据库连接失败"
|
|||
|
|
return @{ Success = $false }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 检查数据库是否存在
|
|||
|
|
function Test-DatabaseExists {
|
|||
|
|
param($Config, [switch]$UseDocker)
|
|||
|
|
|
|||
|
|
$database = $Config.Database
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
Write-Info "检查数据库是否存在 (Docker)..."
|
|||
|
|
$result = & docker exec fendx-mysql-test mysql -u test -ptest -e "SHOW DATABASES LIKE '$database'" 2>$null
|
|||
|
|
if ($result -match $database) {
|
|||
|
|
Write-Success "数据库 '$database' 存在"
|
|||
|
|
return $true
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
Write-Info "检查数据库是否存在..."
|
|||
|
|
$result = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password -e "SHOW DATABASES LIKE '$database'" 2>$null
|
|||
|
|
if ($result -match $database) {
|
|||
|
|
Write-Success "数据库 '$database' 存在"
|
|||
|
|
return $true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Warning "数据库 '$database' 不存在"
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 创建数据库
|
|||
|
|
function New-Database {
|
|||
|
|
param($Config, [switch]$UseDocker)
|
|||
|
|
|
|||
|
|
$database = $Config.Database
|
|||
|
|
|
|||
|
|
Write-Info "创建数据库 '$database'..."
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
$sql = "CREATE DATABASE IF NOT EXISTS `$database` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
|
|||
|
|
& docker exec fendx-mysql-test mysql -u test -ptest -e $sql >$null 2>&1
|
|||
|
|
} else {
|
|||
|
|
$sql = "CREATE DATABASE IF NOT EXISTS `$database` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
|
|||
|
|
& mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password -e $sql >$null 2>&1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "数据库创建成功"
|
|||
|
|
return $true
|
|||
|
|
} else {
|
|||
|
|
Write-Error "数据库创建失败"
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 检查表结构
|
|||
|
|
function Get-DatabaseTables {
|
|||
|
|
param($Config, [switch]$UseDocker)
|
|||
|
|
|
|||
|
|
Write-Info "检查数据库表..."
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
$tables = & docker exec fendx-mysql-test mysql -u test -ptest $Config.Database -e "SHOW TABLES" 2>$null
|
|||
|
|
} else {
|
|||
|
|
$tables = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password $Config.Database -e "SHOW TABLES" 2>$null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not $tables -or $tables.Split("`n").Length -le 1) {
|
|||
|
|
Write-Warning "数据库中没有表"
|
|||
|
|
Write-Info "建议运行迁移命令:"
|
|||
|
|
Write-Info " php bin/console migrate:run"
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Success "数据库表列表:"
|
|||
|
|
$tableList = $tables.Split("`n") | Where-Object { $_ -and $_ -notmatch "Tables_in_" }
|
|||
|
|
|
|||
|
|
foreach ($table in $tableList) {
|
|||
|
|
if ($table.Trim()) {
|
|||
|
|
$count = Get-TableRecordCount $table $Config $UseDocker
|
|||
|
|
Write-Host " - $table ($count 条记录)"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取表记录数
|
|||
|
|
function Get-TableRecordCount {
|
|||
|
|
param($Table, $Config, [switch]$UseDocker)
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
$result = & docker exec fendx-mysql-test mysql -u test -ptest $Config.Database -e "SELECT COUNT(*) FROM `$Table`" 2>$null
|
|||
|
|
} else {
|
|||
|
|
$result = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password $Config.Database -e "SELECT COUNT(*) FROM `$Table`" 2>$null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($result -match '\d+') {
|
|||
|
|
return [int]$matches[0]
|
|||
|
|
}
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 运行数据库迁移
|
|||
|
|
function Invoke-DatabaseMigration {
|
|||
|
|
param([switch]$UseDocker)
|
|||
|
|
|
|||
|
|
Write-Info "运行数据库迁移..."
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
& docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:run
|
|||
|
|
} else {
|
|||
|
|
& php bin/console migrate:run
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "数据库迁移完成"
|
|||
|
|
return $true
|
|||
|
|
} else {
|
|||
|
|
Write-Error "数据库迁移失败"
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 填充测试数据
|
|||
|
|
function Invoke-DatabaseSeed {
|
|||
|
|
param([switch]$UseDocker)
|
|||
|
|
|
|||
|
|
Write-Info "填充测试数据..."
|
|||
|
|
|
|||
|
|
if ($UseDocker) {
|
|||
|
|
& docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:seed
|
|||
|
|
} else {
|
|||
|
|
& php bin/console migrate:seed
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($LASTEXITCODE -eq 0) {
|
|||
|
|
Write-Success "测试数据填充完成"
|
|||
|
|
return $true
|
|||
|
|
} else {
|
|||
|
|
Write-Error "测试数据填充失败"
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 完整检查
|
|||
|
|
function Invoke-FullCheck {
|
|||
|
|
Write-Info "开始完整数据库检查..."
|
|||
|
|
Write-Host "==================================================" -ForegroundColor Cyan
|
|||
|
|
|
|||
|
|
# 加载环境配置
|
|||
|
|
Load-Environment
|
|||
|
|
|
|||
|
|
# 测试数据库连接
|
|||
|
|
$connectionResult = Test-DatabaseConnection
|
|||
|
|
|
|||
|
|
if (-not $connectionResult.Success) {
|
|||
|
|
Write-Host "`n💡 解决建议:" -ForegroundColor Yellow
|
|||
|
|
Write-Host " 1. 检查数据库服务是否启动" -ForegroundColor White
|
|||
|
|
Write-Host " 2. 验证数据库连接配置" -ForegroundColor White
|
|||
|
|
Write-Host " 3. 确认用户权限正确" -ForegroundColor White
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$config = $connectionResult.Config
|
|||
|
|
$useDocker = $connectionResult.Docker
|
|||
|
|
|
|||
|
|
Write-Host "`n--------------------------------------------------" -ForegroundColor Cyan
|
|||
|
|
|
|||
|
|
# 检查数据库是否存在
|
|||
|
|
if (-not (Test-DatabaseExists $config -UseDocker:$useDocker)) {
|
|||
|
|
Write-Host "`n🔧 尝试创建数据库..." -ForegroundColor Yellow
|
|||
|
|
if (New-Database $config -UseDocker:$useDocker) {
|
|||
|
|
Write-Success "数据库已创建,请运行迁移命令:"
|
|||
|
|
Write-Info " php bin/console migrate:run"
|
|||
|
|
}
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Host "`n--------------------------------------------------" -ForegroundColor Cyan
|
|||
|
|
|
|||
|
|
# 检查表结构
|
|||
|
|
Get-DatabaseTables $config -UseDocker:$useDocker
|
|||
|
|
|
|||
|
|
Write-Host "`n==================================================" -ForegroundColor Cyan
|
|||
|
|
Write-Success "数据库检查完成"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 修复数据库
|
|||
|
|
function Repair-Database {
|
|||
|
|
Write-Info "开始修复数据库..."
|
|||
|
|
|
|||
|
|
# 加载环境配置
|
|||
|
|
Load-Environment
|
|||
|
|
|
|||
|
|
# 测试数据库连接
|
|||
|
|
$connectionResult = Test-DatabaseConnection
|
|||
|
|
|
|||
|
|
if (-not $connectionResult.Success) {
|
|||
|
|
Write-Error "数据库连接失败,无法修复"
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$config = $connectionResult.Config
|
|||
|
|
$useDocker = $connectionResult.Docker
|
|||
|
|
|
|||
|
|
# 创建数据库
|
|||
|
|
if (-not (Test-DatabaseExists $config -UseDocker:$useDocker)) {
|
|||
|
|
New-Database $config -UseDocker:$useDocker
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 运行迁移
|
|||
|
|
Invoke-DatabaseMigration -UseDocker:$useDocker
|
|||
|
|
|
|||
|
|
# 填充数据
|
|||
|
|
Invoke-DatabaseSeed -UseDocker:$useDocker
|
|||
|
|
|
|||
|
|
Write-Success "数据库修复完成"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 显示帮助
|
|||
|
|
function Show-Help {
|
|||
|
|
Write-Host @"
|
|||
|
|
FendxPHP 数据库检查工具 (PowerShell)
|
|||
|
|
|
|||
|
|
用法: .\scripts\check-database.ps1 [选项]
|
|||
|
|
|
|||
|
|
选项:
|
|||
|
|
check 检查数据库状态 (默认)
|
|||
|
|
fix 修复数据库问题
|
|||
|
|
migrate 运行数据库迁移
|
|||
|
|
seed 填充测试数据
|
|||
|
|
help 显示帮助信息
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
.\scripts\check-database.ps1 # 检查数据库
|
|||
|
|
.\scripts\check-database.ps1 check # 检查数据库
|
|||
|
|
.\scripts\check-database.ps1 fix # 修复数据库
|
|||
|
|
.\scripts\check-database.ps1 migrate # 运行迁移
|
|||
|
|
.\scripts\check-database.ps1 seed # 填充数据
|
|||
|
|
|
|||
|
|
"@ -ForegroundColor White
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 主函数
|
|||
|
|
function Main {
|
|||
|
|
Write-Host "🚀 FendxPHP 数据库检查 (PowerShell)" -ForegroundColor Green
|
|||
|
|
Write-Host "==================================================" -ForegroundColor Cyan
|
|||
|
|
|
|||
|
|
switch ($Action.ToLower()) {
|
|||
|
|
"check" {
|
|||
|
|
Invoke-FullCheck
|
|||
|
|
}
|
|||
|
|
"fix" {
|
|||
|
|
Repair-Database
|
|||
|
|
}
|
|||
|
|
"migrate" {
|
|||
|
|
Load-Environment
|
|||
|
|
$connectionResult = Test-DatabaseConnection
|
|||
|
|
if ($connectionResult.Success) {
|
|||
|
|
Invoke-DatabaseMigration -UseDocker:$connectionResult.Docker
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
"seed" {
|
|||
|
|
Load-Environment
|
|||
|
|
$connectionResult = Test-DatabaseConnection
|
|||
|
|
if ($connectionResult.Success) {
|
|||
|
|
Invoke-DatabaseSeed -UseDocker:$connectionResult.Docker
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
"help" {
|
|||
|
|
Show-Help
|
|||
|
|
}
|
|||
|
|
default {
|
|||
|
|
Write-Error "未知选项: $Action"
|
|||
|
|
Show-Help
|
|||
|
|
exit 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 运行主函数
|
|||
|
|
try {
|
|||
|
|
Main
|
|||
|
|
} catch {
|
|||
|
|
Write-Error "脚本执行失败: $($_.Exception.Message)"
|
|||
|
|
exit 1
|
|||
|
|
}
|