# 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 }