diff --git a/CHANGELOG.md b/CHANGELOG.md index 1918c5a62..3832dd243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 3.6.0 (unreleased) +- Improved CSP support - Dropped support for Ruby < 3.1 and Rails < 6.1 ## 3.5.0 (2024-05-21) diff --git a/app/assets/javascripts/pghero/application.js b/app/assets/javascripts/pghero/application.js index c15f5de75..d06a12aeb 100644 --- a/app/assets/javascripts/pghero/application.js +++ b/app/assets/javascripts/pghero/application.js @@ -157,3 +157,17 @@ function initSlider() { refreshStats(false); }); } + +$(document).on("click", ".query-code", function () { + this.style.maxHeight = "none"; +}); + +$(document).on("click", ".migration-link", function (e) { + e.preventDefault(); + $(this).parent().next(".migration").css("display", "block"); +}); + +$(document).on("click", ".show-details", function () { + $(this).nextAll(".details").css("display", "block"); + $(this).css("display", "none"); +}); diff --git a/app/assets/stylesheets/pghero/application.css b/app/assets/stylesheets/pghero/application.css index b2d9155ba..c13dbdcce 100644 --- a/app/assets/stylesheets/pghero/application.css +++ b/app/assets/stylesheets/pghero/application.css @@ -483,12 +483,12 @@ body { line-height: 300px; text-align: center; color: #999; + margin-bottom: 20px; } .pie-chart { height: 260px; line-height: 260px; - margin-bottom: 20px; } .unused-index { @@ -503,8 +503,18 @@ body { font-weight: bold; } +.origins-table { + table-layout: auto; +} + .origin { word-break: break-word; + width: 90%; +} + +.origin-pct { + text-align: right; + width: 10%; } .duplicate-indexes td { @@ -518,3 +528,93 @@ body { .no-outline:focus { outline: none; } + +.width-10 { + width: 10%; +} + +.width-15 { + width: 15%; +} + +.width-20 { + width: 20%; +} + +.width-25 { + width: 25%; +} + +.width-33 { + width: 33.33%; +} + +.right-5 { + margin-right: 5px; +} + +.query-row { + border-top: none; + padding: 0; +} + +.query-pre { + margin-top: 1em; +} + +.query-code { + max-height: 230px; + overflow: hidden; +} + +.break-all { + word-break: break-all; +} + +.migration { + display: none; +} + +.migration pre { + overflow: scroll; + white-space: pre; + word-break: normal; +} + +.space-index { + font-style: italic; +} + +a.relation-link { + color: inherit; +} + +.push-left { + float: left; +} + +.clear-both { + clear: both; +} + +.create-index { + color: #eee; + background-color: #333; +} + +.hide { + display: none; +} + +.show-details { + float: right; + color: #f0ad4e; + margin-top: 0px; + padding: 10px; + cursor: pointer; +} + +.details pre { + color: #f0ad4e; + background-color: #333; +} diff --git a/app/views/layouts/pg_hero/application.html.erb b/app/views/layouts/pg_hero/application.html.erb index ddb4d5b5c..188a49782 100644 --- a/app/views/layouts/pg_hero/application.html.erb +++ b/app/views/layouts/pg_hero/application.html.erb @@ -7,10 +7,10 @@ <%= favicon_link_tag "pghero/favicon.png" %> <% if defined?(Propshaft::Railtie) %> <%= stylesheet_link_tag "pghero/nouislider", "pghero/arduino-light", "pghero/application" %> - <%= javascript_include_tag "pghero/jquery", "pghero/nouislider", "pghero/Chart.bundle", "pghero/chartkick", "pghero/highlight.min", "pghero/application" %> + <%= javascript_include_tag "pghero/jquery", "pghero/nouislider", "pghero/Chart.bundle", "pghero/chartkick", "pghero/highlight.min", "pghero/application", nonce: true %> <% else %> <%= stylesheet_link_tag "pghero/application" %> - <%= javascript_include_tag "pghero/application" %> + <%= javascript_include_tag "pghero/application", nonce: true %> <% end %> diff --git a/app/views/pg_hero/home/_connections_table.html.erb b/app/views/pg_hero/home/_connections_table.html.erb index ccefb8a11..551d74d20 100644 --- a/app/views/pg_hero/home/_connections_table.html.erb +++ b/app/views/pg_hero/home/_connections_table.html.erb @@ -2,7 +2,7 @@ Top Sources - Connections + Connections diff --git a/app/views/pg_hero/home/_live_queries_table.html.erb b/app/views/pg_hero/home/_live_queries_table.html.erb index 5a5bf96df..e74586115 100644 --- a/app/views/pg_hero/home/_live_queries_table.html.erb +++ b/app/views/pg_hero/home/_live_queries_table.html.erb @@ -1,10 +1,10 @@ - - - - + + + + @@ -39,15 +39,15 @@ - <% end %>
PidDurationStatePidDurationState
+ <%= query[:source] %> <%= query[:user] %> -
<%= query[:query] %>
+
<%= query[:query] %>
- +<% end %> diff --git a/app/views/pg_hero/home/_queries_table.html.erb b/app/views/pg_hero/home/_queries_table.html.erb index d103483ef..0c78f3e3d 100644 --- a/app/views/pg_hero/home/_queries_table.html.erb +++ b/app/views/pg_hero/home/_queries_table.html.erb @@ -2,9 +2,9 @@ <% unless local_assigns[:xhr] %> - <%= local_assigns[:sort_headers] ? link_to("Total Time", {sort: nil}, data: {sort: nil}) : "Total Time" %> - <%= local_assigns[:sort_headers] ? link_to("Average Time", {sort: "average_time"}, data: {sort: "average_time"}) : "Average Time" %> - <%= local_assigns[:sort_headers] ? link_to("Calls", {sort: "calls"}, data: {sort: "calls"}) : "Calls" %> + <%= local_assigns[:sort_headers] ? link_to("Total Time", {sort: nil}, data: {sort: nil}) : "Total Time" %> + <%= local_assigns[:sort_headers] ? link_to("Average Time", {sort: "average_time"}, data: {sort: "average_time"}) : "Average Time" %> + <%= local_assigns[:sort_headers] ? link_to("Calls", {sort: "calls"}, data: {sort: "calls"}) : "Calls" %> <% end %> @@ -57,8 +57,8 @@ - -
<%= query[:query] %>
+ +
<%= query[:query] %>
<% if query[:query] == "" %>

For security reasons, only superusers can see queries executed by other users.

<% end %> diff --git a/app/views/pg_hero/home/_query_stats_slider.html.erb b/app/views/pg_hero/home/_query_stats_slider.html.erb index 4a11cf2c8..41eb90686 100644 --- a/app/views/pg_hero/home/_query_stats_slider.html.erb +++ b/app/views/pg_hero/home/_query_stats_slider.html.erb @@ -4,7 +4,7 @@
- +<% end %> diff --git a/app/views/pg_hero/home/_suggested_index.html.erb b/app/views/pg_hero/home/_suggested_index.html.erb index 45605fe69..4afb71d31 100644 --- a/app/views/pg_hero/home/_suggested_index.html.erb +++ b/app/views/pg_hero/home/_suggested_index.html.erb @@ -1,11 +1,11 @@ <% if index && !details[:covering_index] %> <% unless @debug %> -
Details
+
Details
<% end %> -
CREATE INDEX CONCURRENTLY ON <%= index[:table] %><% if index[:using] %> USING <%= index[:using] %><% end %> (<%= index[:columns].join(", ") %>)
+
CREATE INDEX CONCURRENTLY ON <%= index[:table] %><% if index[:using] %> USING <%= index[:using] %><% end %> (<%= index[:columns].join(", ") %>)
<% end %> -
"> -
<% if details[:explanation] %><%= details[:explanation] %>
+
"> +
<% if details[:explanation] %><%= details[:explanation] %>
 <% end %><% if details[:row_estimates] %>Rows: <%= details[:rows] %>
 Row progression: <%= details[:row_progression].to_a.join(", ") %>
 
diff --git a/app/views/pg_hero/home/connections.html.erb b/app/views/pg_hero/home/connections.html.erb
index 981608669..507fe72fd 100644
--- a/app/views/pg_hero/home/connections.html.erb
+++ b/app/views/pg_hero/home/connections.html.erb
@@ -7,24 +7,24 @@
     

By Database

Loading...
- + <% end %>

By User

Loading...
- + <% end %> <% if @connections_by_ssl_status %>

By Security

Loading...
- + <% end %> <% end %> <%= render partial: "connections_table", locals: {connection_sources: @connection_sources} %> diff --git a/app/views/pg_hero/home/explain.html.erb b/app/views/pg_hero/home/explain.html.erb index 127f9908c..194e2dc80 100644 --- a/app/views/pg_hero/home/explain.html.erb +++ b/app/views/pg_hero/home/explain.html.erb @@ -4,9 +4,9 @@ <%= form_tag explain_path do %>
<%= text_area_tag :query, @query, placeholder: "Enter a SQL query" %>

- <%= submit_tag "Explain", class: "btn btn-info", style: "margin-right: 10px;" %> + <%= submit_tag "Explain", class: "btn btn-info right-5" %> <% if @explain_analyze_enabled %> - <%= submit_tag "Analyze", class: "btn btn-danger", style: "margin-right: 10px;" %> + <%= submit_tag "Analyze", class: "btn btn-danger right-5" %> <% end %> <%= submit_tag "Visualize", class: "btn btn-danger" %>

diff --git a/app/views/pg_hero/home/index.html.erb b/app/views/pg_hero/home/index.html.erb index d492eae67..9e0cbcda0 100644 --- a/app/views/pg_hero/home/index.html.erb +++ b/app/views/pg_hero/home/index.html.erb @@ -127,7 +127,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -279,9 +279,9 @@ - - - + + + @@ -332,7 +332,7 @@ - @@ -366,7 +366,7 @@ - @@ -383,15 +383,15 @@

These indexes exist, but aren’t needed. Remove them <% if @show_migrations %> - with a migration + with a migration <% end %> for faster writes.

- - + @@ -518,6 +518,6 @@ pg_stat_statements.track = all <% end %> - +<% end %> diff --git a/app/views/pg_hero/home/index_bloat.html.erb b/app/views/pg_hero/home/index_bloat.html.erb index 238f3c6b3..7d5e23795 100644 --- a/app/views/pg_hero/home/index_bloat.html.erb +++ b/app/views/pg_hero/home/index_bloat.html.erb @@ -25,15 +25,15 @@ ALTER INDEX new_index RENAME TO index; - - + + <% @index_bloat.each do |index| %> <% if @show_sql && !index[:primary] %> - - - + + <% if @show_dead_rows %> - + <% end %> diff --git a/app/views/pg_hero/home/queries.html.erb b/app/views/pg_hero/home/queries.html.erb index 801375a42..16e00c7db 100644 --- a/app/views/pg_hero/home/queries.html.erb +++ b/app/views/pg_hero/home/queries.html.erb @@ -4,13 +4,13 @@ <% end %> <% if !@historical_query_stats_enabled %> -

Queries

+

Queries

<% end %> <% if @historical_query_stats_enabled %> <%= render partial: "query_stats_slider" %> <% elsif @database.query_stats_table_exists? && (columns = @database.missing_query_stats_columns).any? %> -
+

Add missing columns to re-enable historical query stats.

<% @database.missing_query_stats_columns.each do |column| %>ALTER TABLE pghero_query_stats ADD COLUMN "<%= column %>" <%= column == "query_hash" ? "bigint" : "text" %>;
 <% end %>
@@ -23,9 +23,9 @@
Cannot understand start or end time.
<% elsif @query_stats.any? || @historical_query_stats_enabled %> <%= render partial: "queries_table", locals: {queries: @query_stats, sort_headers: true} %> - + <% end %> <% else %>

Stats are not available yet. Come back soon!

<% end %> diff --git a/app/views/pg_hero/home/relation_space.html.erb b/app/views/pg_hero/home/relation_space.html.erb index c3f4e3d1b..9d0a99290 100644 --- a/app/views/pg_hero/home/relation_space.html.erb +++ b/app/views/pg_hero/home/relation_space.html.erb @@ -7,8 +7,8 @@

Size

-
Loading...
- + <% end %>
diff --git a/app/views/pg_hero/home/show_query.html.erb b/app/views/pg_hero/home/show_query.html.erb index 911cd4bf2..41dfb254e 100644 --- a/app/views/pg_hero/home/show_query.html.erb +++ b/app/views/pg_hero/home/show_query.html.erb @@ -1,8 +1,8 @@
-
<%= @query %>
- + <% end %> <% if @explain_enabled && @explainable_query %>

@@ -11,11 +11,11 @@ <% end %> <% if @origins && @origins.keys.select { |k| k.length > 0 }.any? %> -

ColumnColumn Sequence
TableTransactions LeftTransactions Left
ColumnTypeValues Left% LeftTypeValues Left% Left
+
DROP INDEX CONCURRENTLY <%= pghero_pretty_ident(index[:name], schema: index[:schema]) %>;
 <%= index[:definition].sub("CREATE INDEX ", "CREATE INDEX CONCURRENTLY ") %>;
+
ALTER TABLE <%= pghero_pretty_ident(constraint[:table], schema: constraint[:schema]) %> VALIDATE CONSTRAINT <%= pghero_pretty_ident(constraint[:name]) %>;
NameIndex SizeIndex Size
IndexBloatSizeBloatSize
- <%= index[:index] %> + <%= index[:index] %> <% if index[:primary] %> PRIMARY <% end %> @@ -43,7 +43,7 @@ ALTER INDEX new_index RENAME TO index;
+ <% new_index = "new_#{index[:index]}".first(63) %>
<%= index[:definition].sub(" INDEX ", " INDEX CONCURRENTLY \n    ").sub(index[:index], new_index) %>;
 
@@ -67,6 +67,6 @@ ALTER INDEX <%= pghero_pretty_ident(new_index) %>
   <% end %>
 
 
-
+<% end %>
diff --git a/app/views/pg_hero/home/maintenance.html.erb b/app/views/pg_hero/home/maintenance.html.erb
index 149ad050b..f3bf2d1f7 100644
--- a/app/views/pg_hero/home/maintenance.html.erb
+++ b/app/views/pg_hero/home/maintenance.html.erb
@@ -5,10 +5,10 @@
     
TableLast VacuumLast AnalyzeLast VacuumLast AnalyzeDead RowsDead Rows
+
@@ -23,14 +23,14 @@ <% @origins.sort_by { |o, c| [-c, o.to_s] }.each do |origin, count| %> - -
-
Approx. Time
+
Approx. Time
Origin
+ <% if origin.length > 0 %> <%= origin %> <% else %> Unknown <% end %> + <% pct = (100.0 * count / @total_count).round %> <% if pct == 0 %> < 1% @@ -47,22 +47,22 @@ <% if @chart_data %>

Total Time ms

-
Loading...
- + <% end %>

Average Time ms

-
Loading...
- + <% end %>

Calls

-
Loading...
- + <% end %> <% else %>

Enable @@ -77,8 +77,8 @@ - - + + diff --git a/app/views/pg_hero/home/space.html.erb b/app/views/pg_hero/home/space.html.erb index 0376b291b..50b032299 100644 --- a/app/views/pg_hero/home/space.html.erb +++ b/app/views/pg_hero/home/space.html.erb @@ -4,10 +4,10 @@

Database Size: <%= @database_size %>

<% if @system_stats_enabled %> -
Loading...
- + <% end %> <% end %>
NameRowsNameRows Indexes