generateRecommendations generates actionable recommendations
()
| 453 | |
| 454 | // generateRecommendations generates actionable recommendations |
| 455 | func (a *SQLAnalyzer) generateRecommendations() []string { |
| 456 | var recommendations []string |
| 457 | |
| 458 | // Get security issues |
| 459 | securityIssues := 0 |
| 460 | performanceIssues := 0 |
| 461 | for _, issue := range a.Issues { |
| 462 | switch issue.Category { |
| 463 | case IssueCategorySecurity: |
| 464 | securityIssues++ |
| 465 | case IssueCategoryPerformance: |
| 466 | performanceIssues++ |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | // Security recommendations |
| 471 | if securityIssues > 0 { |
| 472 | recommendations = append(recommendations, "Review and fix security vulnerabilities before production deployment") |
| 473 | } |
| 474 | |
| 475 | // Performance recommendations |
| 476 | if a.PerformanceScore < 70 { |
| 477 | recommendations = append(recommendations, "Consider query optimization techniques to improve performance") |
| 478 | } |
| 479 | |
| 480 | if a.hasSelectStar { |
| 481 | recommendations = append(recommendations, "Replace SELECT * with explicit column lists") |
| 482 | } |
| 483 | |
| 484 | if a.hasCartesian { |
| 485 | recommendations = append(recommendations, "Review JOIN conditions to avoid cartesian products") |
| 486 | } |
| 487 | |
| 488 | if a.joinCount > 3 { |
| 489 | recommendations = append(recommendations, "Consider denormalization or materialized views for complex JOINs") |
| 490 | } |
| 491 | |
| 492 | // Complexity recommendations |
| 493 | if a.ComplexityMetrics.OverallComplexity == "HIGH" || a.ComplexityMetrics.OverallComplexity == "VERY_HIGH" { |
| 494 | recommendations = append(recommendations, "Break down complex queries into simpler components") |
| 495 | } |
| 496 | |
| 497 | if len(recommendations) == 0 { |
| 498 | recommendations = append(recommendations, "Query follows good SQL practices") |
| 499 | } |
| 500 | |
| 501 | return recommendations |
| 502 | } |
| 503 | |
| 504 | // buildQueryInfo constructs query metadata from the AST |
| 505 | func (a *SQLAnalyzer) buildQueryInfo(astObj *ast.AST, sql string) QueryInfo { |