Module: QueryGuard::Core::FindingBuilders
- Defined in:
- lib/query_guard/core/finding_builders.rb
Overview
Factory builders for common finding types. Provides convenient methods to create well-structured findings without manually specifying all parameters.
Example:
finding = FindingBuilders.slow_query(
query,
duration_ms: 250.5,
threshold_ms: 100.0
)
Class Method Summary collapse
-
.build(analyzer_name:, rule_name:, **opts) ⇒ Object
Generic builder for custom findings.
-
.migration_risk(migration_file:, issue:, **opts) ⇒ Object
Migration-related finding (prepared for Phase 2).
-
.pattern_detected(query, pattern_type:, **opts) ⇒ Object
Pattern matching finding (prepared for future analyzers).
-
.select_star(query, **opts) ⇒ Object
SELECT * finding.
-
.slow_query(query, duration_ms:, threshold_ms:, **opts) ⇒ Object
Slow query finding.
-
.too_many_queries(count:, limit:, total_duration_ms:, **opts) ⇒ Object
Too many queries finding.
Class Method Details
.build(analyzer_name:, rule_name:, **opts) ⇒ Object
Generic builder for custom findings
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/query_guard/core/finding_builders.rb', line 93 def self.build(analyzer_name:, rule_name:, **opts) Finding.new( analyzer_name: analyzer_name, rule_name: rule_name, severity: opts[:severity] || :warn, title: opts[:title], description: opts[:description], message: opts[:message], sql: opts[:sql], metadata: opts[:metadata] || {}, recommendations: opts[:recommendations] || [], query: opts[:query], file_path: opts[:file_path], line_number: opts[:line_number] ) end |
.migration_risk(migration_file:, issue:, **opts) ⇒ Object
Migration-related finding (prepared for Phase 2)
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/query_guard/core/finding_builders.rb', line 111 def self.migration_risk(migration_file:, issue:, **opts) Finding.new( analyzer_name: :migration_safety, rule_name: opts[:rule_name] || :unsafe_operation, severity: opts[:severity] || :error, title: opts[:title] || "Migration Risk Detected", description: opts[:description] || "Migration may cause data loss or downtime.", message: issue, file_path: migration_file, line_number: opts[:line_number], metadata: opts[:metadata] || {}, recommendations: opts[:recommendations] || [ "Review migration carefully before deploying", "Test on a staging environment", "Consider phased rollout for large tables" ] ) end |
.pattern_detected(query, pattern_type:, **opts) ⇒ Object
Pattern matching finding (prepared for future analyzers)
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/query_guard/core/finding_builders.rb', line 131 def self.pattern_detected(query, pattern_type:, **opts) Finding.new( analyzer_name: opts[:analyzer_name] || :pattern_detector, rule_name: opts[:rule_name] || :pattern_detected, severity: opts[:severity] || :info, title: opts[:title] || "Pattern Detected", description: opts[:description] || "A query pattern was detected.", message: opts[:message] || "#{pattern_type} pattern detected", sql: query&.sql, metadata: { pattern_type: pattern_type, **(opts[:metadata] || {}) }, recommendations: opts[:recommendations] || [], query: query, file_path: opts[:file_path], line_number: opts[:line_number] ) end |
.select_star(query, **opts) ⇒ Object
SELECT * finding
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/query_guard/core/finding_builders.rb', line 68 def self.select_star(query, **opts) Finding.new( analyzer_name: :select_star, rule_name: :select_star_detected, severity: opts[:severity] || :warn, title: "SELECT * Used", description: "Query uses SELECT * instead of specifying columns.", message: "SELECT * detected in query", sql: query&.sql, metadata: { sql: query&.sql }, recommendations: [ "Specify only required columns explicitly", "Reduces bandwidth and improves query efficiency", "Makes schema changes less error-prone", "Enables better query optimization by the database" ], query: query, file_path: opts[:file_path], line_number: opts[:line_number] ) end |
.slow_query(query, duration_ms:, threshold_ms:, **opts) ⇒ Object
Slow query finding
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/query_guard/core/finding_builders.rb', line 17 def self.slow_query(query, duration_ms:, threshold_ms:, **opts) Finding.new( analyzer_name: :slow_query, rule_name: :duration_exceeded, severity: opts[:severity] || :warn, title: "Slow Query Detected", description: "Query execution time exceeded the configured threshold.", message: "Query took #{duration_ms.round(2)}ms (limit: #{threshold_ms}ms)", sql: query&.sql, metadata: { duration_ms: duration_ms, threshold_ms: threshold_ms }, recommendations: [ "Add indexes on frequently queried columns", "Review and optimize the query logic", "Consider using pagination for large result sets", "Check database statistics" ], query: query, file_path: opts[:file_path], line_number: opts[:line_number] ) end |
.too_many_queries(count:, limit:, total_duration_ms:, **opts) ⇒ Object
Too many queries finding
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/query_guard/core/finding_builders.rb', line 43 def self.too_many_queries(count:, limit:, total_duration_ms:, **opts) Finding.new( analyzer_name: :query_count, rule_name: :count_exceeded, severity: opts[:severity] || :warn, title: "Too Many Queries", description: "Request executed more queries than the configured limit.", message: "Executed #{count} queries (limit: #{limit})", metadata: { count: count, limit: limit, total_duration_ms: total_duration_ms }, recommendations: [ "Use eager loading (N+1 query prevention)", "Consolidate multiple queries into one", "Use database-level aggregations where possible", "Consider caching results" ], file_path: opts[:file_path], line_number: opts[:line_number] ) end |