Class: PgInsights::QueryExecution
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- PgInsights::QueryExecution
- Defined in:
- app/models/pg_insights/query_execution.rb
Constant Summary collapse
- EXECUTION_TYPES =
%w[execute analyze both].freeze
- STATUSES =
%w[pending running completed failed].freeze
Instance Method Summary collapse
- #completed? ⇒ Boolean
- #display_summary ⇒ Object
-
#display_title ⇒ Object
History display helpers (public methods).
- #failed? ⇒ Boolean
- #formatted_query_cost ⇒ Object
- #formatted_total_time ⇒ Object
- #has_performance_issues? ⇒ Boolean
-
#has_plan_data? ⇒ Boolean
Plan analysis helpers.
-
#has_result_data? ⇒ Boolean
Result data helpers.
-
#has_timing_data? ⇒ Boolean
Performance metrics.
- #includes_analysis? ⇒ Boolean
-
#includes_execution? ⇒ Boolean
Execution type checks.
- #mark_as_completed!(results = {}) ⇒ Object
- #mark_as_failed!(error_msg, error_detail = nil) ⇒ Object
-
#mark_as_running! ⇒ Object
Status transitions.
- #optimization_suggestions ⇒ Object
-
#pending? ⇒ Boolean
Status management.
- #performance_class ⇒ Object
- #plan_nodes ⇒ Object
- #result_summary ⇒ Object
- #running? ⇒ Boolean
- #success? ⇒ Boolean
Instance Method Details
#completed? ⇒ Boolean
33 34 35 |
# File 'app/models/pg_insights/query_execution.rb', line 33 def completed? status == "completed" end |
#display_summary ⇒ Object
151 152 153 154 155 156 157 |
# File 'app/models/pg_insights/query_execution.rb', line 151 def display_summary parts = [] parts << "#{formatted_total_time}" if total_time_ms.present? parts << "Cost: #{formatted_query_cost}" if query_cost.present? parts << "#{result_rows_count} rows" if result_rows_count.present? parts.join(" • ") end |
#display_title ⇒ Object
History display helpers (public methods)
146 147 148 149 |
# File 'app/models/pg_insights/query_execution.rb', line 146 def display_title return sql_text.truncate(50) if sql_text.present? "Query ##{id}" end |
#failed? ⇒ Boolean
37 38 39 |
# File 'app/models/pg_insights/query_execution.rb', line 37 def failed? status == "failed" end |
#formatted_query_cost ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'app/models/pg_insights/query_execution.rb', line 69 def formatted_query_cost return nil unless query_cost if query_cost < 1000 query_cost.round(2) else "#{(query_cost / 1000).round(1)}K" end end |
#formatted_total_time ⇒ Object
59 60 61 62 63 64 65 66 67 |
# File 'app/models/pg_insights/query_execution.rb', line 59 def formatted_total_time return nil unless total_time_ms if total_time_ms < 1000 "#{total_time_ms.round(2)}ms" else "#{(total_time_ms / 1000).round(2)}s" end end |
#has_performance_issues? ⇒ Boolean
98 99 100 101 102 103 104 105 |
# File 'app/models/pg_insights/query_execution.rb', line 98 def has_performance_issues? return false unless performance_insights.present? insights = performance_insights insights["issues_detected"] == true || insights["slow_operations"].present? || insights["missing_indexes"].present? end |
#has_plan_data? ⇒ Boolean
Plan analysis helpers
80 81 82 |
# File 'app/models/pg_insights/query_execution.rb', line 80 def has_plan_data? execution_plan.present? end |
#has_result_data? ⇒ Boolean
Result data helpers
108 109 110 |
# File 'app/models/pg_insights/query_execution.rb', line 108 def has_result_data? result_data.present? && result_rows_count.present? end |
#has_timing_data? ⇒ Boolean
Performance metrics
55 56 57 |
# File 'app/models/pg_insights/query_execution.rb', line 55 def has_timing_data? planning_time_ms.present? || execution_time_ms.present? end |
#includes_analysis? ⇒ Boolean
50 51 52 |
# File 'app/models/pg_insights/query_execution.rb', line 50 def includes_analysis? execution_type.in?([ "analyze", "both" ]) end |
#includes_execution? ⇒ Boolean
Execution type checks
46 47 48 |
# File 'app/models/pg_insights/query_execution.rb', line 46 def includes_execution? execution_type.in?([ "execute", "both" ]) end |
#mark_as_completed!(results = {}) ⇒ Object
126 127 128 129 130 131 132 133 |
# File 'app/models/pg_insights/query_execution.rb', line 126 def mark_as_completed!(results = {}) update!( status: "completed", completed_at: Time.current, duration_ms: calculate_duration, **results ) end |
#mark_as_failed!(error_msg, error_detail = nil) ⇒ Object
135 136 137 138 139 140 141 142 143 |
# File 'app/models/pg_insights/query_execution.rb', line 135 def mark_as_failed!(error_msg, error_detail = nil) update!( status: "failed", completed_at: Time.current, duration_ms: calculate_duration, error_message: error_msg, error_detail: error_detail ) end |
#mark_as_running! ⇒ Object
Status transitions
119 120 121 122 123 124 |
# File 'app/models/pg_insights/query_execution.rb', line 119 def mark_as_running! update!( status: "running", started_at: Time.current ) end |
#optimization_suggestions ⇒ Object
92 93 94 95 96 |
# File 'app/models/pg_insights/query_execution.rb', line 92 def optimization_suggestions return [] unless performance_insights.present? performance_insights["suggestions"] || [] end |
#pending? ⇒ Boolean
Status management
25 26 27 |
# File 'app/models/pg_insights/query_execution.rb', line 25 def pending? status == "pending" end |
#performance_class ⇒ Object
159 160 161 162 163 164 165 |
# File 'app/models/pg_insights/query_execution.rb', line 159 def performance_class return "performance-excellent" if total_time_ms && total_time_ms < 50 return "performance-good" if total_time_ms && total_time_ms < 200 return "performance-fair" if total_time_ms && total_time_ms < 1000 return "performance-poor" if total_time_ms && total_time_ms >= 1000 "performance-unknown" end |
#plan_nodes ⇒ Object
84 85 86 87 88 89 90 |
# File 'app/models/pg_insights/query_execution.rb', line 84 def plan_nodes return [] unless execution_plan.present? # Extract plan nodes from PostgreSQL EXPLAIN output plan_data = execution_plan.is_a?(Array) ? execution_plan.first : execution_plan extract_plan_nodes(plan_data["Plan"]) if plan_data && plan_data["Plan"] end |
#result_summary ⇒ Object
112 113 114 115 116 |
# File 'app/models/pg_insights/query_execution.rb', line 112 def result_summary return nil unless has_result_data? "#{result_rows_count} #{'row'.pluralize(result_rows_count)} • #{result_columns_count} #{'column'.pluralize(result_columns_count)}" end |
#running? ⇒ Boolean
29 30 31 |
# File 'app/models/pg_insights/query_execution.rb', line 29 def running? status == "running" end |
#success? ⇒ Boolean
41 42 43 |
# File 'app/models/pg_insights/query_execution.rb', line 41 def success? completed? && .blank? end |