rails-pg-extras-web 1.4.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abc008aaf05163eebc554ac1bb9eb7746f51fe83ff7557c4f924e5fc19b151ae
4
- data.tar.gz: 41a7833a4550b17c93a884a9abdd17b7304822db9dc85d560469469e8728791e
3
+ metadata.gz: 5699fd3b704d3c1b44dba980a4c7f744bceb7a8ac56e59c7cc013b8b68544871
4
+ data.tar.gz: 9d881723852e10a275e0e146a0a2586275b7830e0ef21a9f10e263d9523c5d25
5
5
  SHA512:
6
- metadata.gz: f0527a2d23300b0602a807e68fb2c058941051cac537f0828420a3cd8ac3a450df256c43dd52dba9e9556705015cd86833cea9e0c470866e3c9b5e5d60b51b05
7
- data.tar.gz: 6dcd0d8dc82528e9eaa3afd75caec3e9642c54bb7115410982914ea313b22e37fcadec35fa44884c1c987efbb98ba1470e989c55fbe8d9e06a1168644a8f7d7d
6
+ metadata.gz: 62c46bf2750fe4582b78454b610cf187735bccc48b39a33150d8445bb90c52e785e83d52f8d6ecb1fb01309eeb83c58eb2b1e2f1f2185e9364ed4dc132c05033
7
+ data.tar.gz: 49e2b3c3c17b16f4cad995d0ff79162699e51294aa0c93e6e2e71c31acb34a731a750b8fe05c4e3780f1d0cf39b18bd95a442c505bb9b2a16c2740d7e6ea35cc
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # RailsPgExtrasWeb
2
- Web UI for rails-pg-extras-web
2
+ Web UI for [rails-pg-extras](https://github.com/pawurb/rails-pg-extras)
3
3
 
4
4
  ## Installation
5
5
  Add this line to your application's Gemfile:
@@ -7,30 +7,5 @@ module RailsPgExtrasWeb
7
7
  if Rails.env.production? && ENV['PG_EXTRAS_USER'].present? && ENV['PG_EXTRAS_PASSWORD'].present?
8
8
  http_basic_authenticate_with name: ENV['PG_EXTRAS_USER'], password: ENV['PG_EXTRAS_PASSWORD']
9
9
  end
10
-
11
- protect_from_forgery with: :exception
12
-
13
- helper_method :pg_stats_statements_enabled?
14
-
15
- private
16
-
17
- def load_queries
18
- @all_queries = {}
19
-
20
- ::RailsPGExtras::QUERIES.each do |query_name|
21
- @all_queries[query_name] = {
22
- disabled: query_disabled?(query_name),
23
- command: query_name == :kill_all
24
- }
25
- end
26
- end
27
-
28
- def query_disabled?(query_name)
29
- query_name.in?([:calls, :outliers]) && !pg_stats_statements_enabled?
30
- end
31
-
32
- def pg_stats_statements_enabled?
33
- ActiveRecord::Base.connection.extensions.include?("pg_stat_statements")
34
- end
35
10
  end
36
11
  end
@@ -1,19 +1,49 @@
1
1
  module RailsPgExtrasWeb
2
2
  class QueriesController < ApplicationController
3
+ REQUIRED_EXTENSIONS = {
4
+ pg_stat_statements: %i[calls outliers],
5
+ pg_buffercache: %i[buffercache_stats buffercache_usage]
6
+ }
7
+
3
8
  before_action :load_queries
9
+ helper_method :unavailable_extensions
4
10
 
5
- def index; end
11
+ def index
12
+ if params[:query_name].present?
13
+ @query_name = params[:query_name].to_sym.presence_in(@all_queries.keys)
14
+ return unless @query_name
6
15
 
7
- def run
8
- if @query_name = params[:query_name].presence
9
16
  begin
10
17
  @result = RailsPGExtras.run_query(query_name: @query_name.to_sym, in_format: :raw)
11
18
  rescue ActiveRecord::StatementInvalid => e
12
19
  @error = e.message
13
20
  end
14
- else
15
- redirect_to root_path
21
+
22
+ render :show
16
23
  end
17
24
  end
25
+
26
+ private
27
+
28
+ def load_queries
29
+ @all_queries = RailsPGExtras::QUERIES.inject({}) do |memo, query_name|
30
+ unless query_name.in? %i[kill_all mandelbrot]
31
+ memo[query_name] = { disabled: query_disabled?(query_name) }
32
+ end
33
+
34
+ memo
35
+ end
36
+ end
37
+
38
+ def query_disabled?(query_name)
39
+ unavailable_extensions.values.flatten.include?(query_name)
40
+ end
41
+
42
+ def unavailable_extensions
43
+ return @unavailable_extensions if defined?(@unavailable_extensions)
44
+
45
+ enabled_extensions = ActiveRecord::Base.connection.extensions
46
+ @unavailable_extensions = REQUIRED_EXTENSIONS.delete_if { |ext| ext.to_s.in?(enabled_extensions) }
47
+ end
18
48
  end
19
49
  end
@@ -1,21 +1,10 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>PG::Extras</title>
5
- <%= csrf_meta_tags %>
6
- <%= csp_meta_tag %>
4
+ <title><%= content_for :title %></title>
5
+ <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
7
6
  </head>
8
- <body onload="document.forms.queries.query_name.focus()">
9
- <%= form_with url: run_query_url, id: "queries" do |f| %>
10
- <%= f.select :query_name, options_for_select(@all_queries.except(:kill_all, :mandelbrot), params[:query_name]),
11
- prompt: "--- select query ---"
12
- %>
13
-
14
- <button type="submit">Run</button>
15
- <% end %>
16
-
17
- <div style='margin-top: 20px'>
18
- <%= yield %>
19
- </div>
7
+ <body class="p-5 text-xs">
8
+ <%= yield %>
20
9
  </body>
21
10
  </html>
@@ -0,0 +1,22 @@
1
+ <h1 class="font-bold text-xl my-5"><%= title %></h1>
2
+
3
+ <table class="w-full font-mono border-collapse border border-green-800 my-5">
4
+ <thead>
5
+ <tr class="bg-gray-300">
6
+ <% headers.each do |header| %>
7
+ <th class="p-2 border text-left"><%= header %></th>
8
+ <% end %>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <% rows.each.with_index do |row, i| %>
13
+ <tr class="hover:bg-gray-400 hover:text-white <%= i.even? ? "bg-gray-100" : "bg-gray-200" %>">
14
+ <% row.each do |column| %>
15
+ <td class="p-1 border"><%= column %></td>
16
+ <% end %>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ </table>
21
+
22
+ <span class="italic">run_at: <%= Time.now.utc %></span>
@@ -0,0 +1,48 @@
1
+ <div class="text-red-500 p-3 font-mono my-5">
2
+ <% unavailable_extensions.each do |extension, queries| %>
3
+ WARNING: Queries <%= queries.map { |q| "<b><u>#{q}</u></b>" }.join(", ").html_safe %> require extension: <b><%= extension %></b>
4
+ <br>
5
+ <% end %>
6
+ </div>
7
+
8
+
9
+ <span id="rails" class="font-mono font-bold p-3 bg-gray-100 cursor-pointer select-none">RAILS</span> <span id="sql" class="font-mono font-normal p-3 bg-gray-50 cursor-pointer select-none">SQL</span>
10
+ <pre id="rails_code" class="font-mono p-5 bg-gray-100 block">
11
+ <% unavailable_extensions.each do |extension, queries| %>
12
+ ActiveRecord::Base.connection.enable_extension "<%= extension %>"
13
+ <% end %>
14
+ </pre>
15
+
16
+ <pre id="sql_code" class="font-mono p-5 bg-gray-100 hidden">
17
+ <% unavailable_extensions.each do |extension, queries| %>
18
+ CREATE EXTENSION <%= extension %>;
19
+ <% end %>
20
+ </pre>
21
+
22
+ <script>
23
+ const rails = document.getElementById('rails')
24
+ const sql = document.getElementById('sql')
25
+ const railsCode = document.getElementById('rails_code')
26
+ const sqlCode = document.getElementById('sql_code')
27
+
28
+ rails.addEventListener('click', (e) => {
29
+ railsCode.classList.remove('hidden')
30
+ sqlCode.classList.add('hidden')
31
+
32
+ rails.classList.replace('bg-gray-50','bg-gray-100')
33
+ sql.classList.replace('bg-gray-100','bg-gray-50')
34
+ rails.classList.replace('font-normal','font-bold')
35
+ sql.classList.replace('font-bold','font-normal')
36
+ })
37
+
38
+ sql.addEventListener('click', (e) => {
39
+ railsCode.classList.add('hidden')
40
+ sqlCode.classList.remove('hidden')
41
+
42
+ rails.classList.replace('bg-gray-100','bg-gray-50')
43
+ sql.classList.replace('bg-gray-50','bg-gray-100')
44
+ rails.classList.replace('font-bold','font-normal')
45
+ sql.classList.replace('font-normal','font-bold')
46
+ })
47
+ </script>
48
+
@@ -1,10 +1,4 @@
1
- <% unless pg_stats_statements_enabled? %>
2
- <span style='color: red'>
3
- WARNING: <b><u>outliers</u></b>, <b><u>calls</u></b> require extension: <b>pg_stat_statements</b>
4
- </span>
1
+ <%= content_for :title, "pg_extras" %>
2
+ <%= render "rails_pg_extras_web/shared/queries_selector" %>
5
3
 
6
- <h4>Rails</h4>
7
- <pre style='background-color: #e2e2e2; padding: 10px'>ActiveRecord::Base.connection.enable_extension "pg_stat_statements"</pre>
8
- <h4>SQL</h4>
9
- <pre style='background-color: #e2e2e2; padding: 10px'>CREATE EXTENSION pg_stat_statements</pre>
10
- <% end %>
4
+ <%= render "unavailable_extensions_warning" if unavailable_extensions.any? %>
@@ -0,0 +1,24 @@
1
+ <%= content_for :title, params[:query_name].presence || "pg_extras" %>
2
+ <%= render "rails_pg_extras_web/shared/queries_selector" %>
3
+
4
+ <% if @error %>
5
+ <span class="text-red"><%= @error %></span>
6
+ <% else %>
7
+ <% if @result&.any? %>
8
+ <%= render "result",
9
+ title: RubyPGExtras.description_for(query_name: @query_name),
10
+ headers: @result[0].keys,
11
+ rows: @result.values
12
+ %>
13
+ <% else %>
14
+ <div class="font-mono p-3 bg-gray-100 mt-3">No results</div>
15
+ <% end %>
16
+ <% end %>
17
+
18
+ <style>
19
+ @media print {
20
+ form {
21
+ display: none
22
+ }
23
+ }
24
+ </style>
@@ -0,0 +1,11 @@
1
+ <%= form_with url: queries_path, id: "queries", method: :get do |f| %>
2
+ <%= f.select :query_name, options_for_select(@all_queries, params[:query_name]),
3
+ {prompt: "--- select query ---"},
4
+ {class: "border p-2 font-bold", autofocus: true}
5
+ %>
6
+ <% end %>
7
+ <script>
8
+ document.getElementById('queries').addEventListener('change', (e) => {
9
+ e.target.form.submit()
10
+ })
11
+ </script>
data/config/routes.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  RailsPgExtrasWeb::Engine.routes.draw do
2
- root to: "queries#index"
2
+ resources :queries, only: [:index]
3
3
 
4
- post "/queries/run", as: :run_query
4
+ root to: "queries#index"
5
5
  end
@@ -1,3 +1,3 @@
1
1
  module RailsPgExtrasWeb
2
- VERSION = '1.4.1'
2
+ VERSION = '2.0.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-pg-extras-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Mazur
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-04 00:00:00.000000000 Z
11
+ date: 2021-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -30,15 +30,15 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.4.0
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.4.0
41
- description:
40
+ version: '2.0'
41
+ description:
42
42
  email:
43
43
  - tomasz.mazur@hey.com
44
44
  executables: []
@@ -51,8 +51,11 @@ files:
51
51
  - app/controllers/rails_pg_extras_web/application_controller.rb
52
52
  - app/controllers/rails_pg_extras_web/queries_controller.rb
53
53
  - app/views/layouts/rails_pg_extras_web/application.html.erb
54
+ - app/views/rails_pg_extras_web/queries/_result.html.erb
55
+ - app/views/rails_pg_extras_web/queries/_unavailable_extensions_warning.html.erb
54
56
  - app/views/rails_pg_extras_web/queries/index.html.erb
55
- - app/views/rails_pg_extras_web/queries/run.html.erb
57
+ - app/views/rails_pg_extras_web/queries/show.html.erb
58
+ - app/views/rails_pg_extras_web/shared/_queries_selector.html.erb
56
59
  - config/routes.rb
57
60
  - lib/rails-pg-extras-web.rb
58
61
  - lib/rails_pg_extras_web/engine.rb
@@ -61,7 +64,7 @@ homepage: https://github.com/defkode/rails-pg-extras-web
61
64
  licenses:
62
65
  - MIT
63
66
  metadata: {}
64
- post_install_message:
67
+ post_install_message:
65
68
  rdoc_options: []
66
69
  require_paths:
67
70
  - lib
@@ -76,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
79
  - !ruby/object:Gem::Version
77
80
  version: '0'
78
81
  requirements: []
79
- rubygems_version: 3.1.4
80
- signing_key:
82
+ rubygems_version: 3.1.6
83
+ signing_key:
81
84
  specification_version: 4
82
85
  summary: Web UI for rails-pg-extras
83
86
  test_files: []
@@ -1,59 +0,0 @@
1
- <% if @error %>
2
- <span style='color: red'><%= @error %></span>
3
- <% else %>
4
- <% if @result && @result.any? %>
5
- <table>
6
- <caption><%= RubyPGExtras.description_for(query_name: @query_name) %></caption>
7
- <thead>
8
- <tr>
9
- <% @result[0].keys.each do |header| %>
10
- <th><%= header %></th>
11
- <% end %>
12
- </tr>
13
- </thead>
14
- <tbody>
15
- <% @result.values.each do |row| %>
16
- <tr>
17
- <% row.each do |column| %>
18
- <td><%= column %></td>
19
- <% end %>
20
- </tr>
21
- <% end %>
22
- </tbody>
23
- </table>
24
-
25
- <pre>run_at: <%= Time.now.utc %></pre>
26
- <% else %>
27
- <pre>No results</pre>
28
- <% end %>
29
- <% end %>
30
-
31
- <style media="screen">
32
- table {
33
- font-family: monospace;
34
- border-collapse: collapse;
35
- width: 100%;
36
- }
37
-
38
- table th {
39
- background-color: #c9c9;
40
- }
41
-
42
- table th, table td {
43
- text-align: left;
44
- border: 1px solid #c9c9;
45
- padding: 3px;
46
- }
47
-
48
- table td {
49
- overflow: hidden;
50
- text-overflow: ellipsis;
51
- white-space: nowrap;
52
- }
53
-
54
- table caption {
55
- padding: 5px;
56
- font-size: 15px;
57
- font-weight: bold;
58
- }
59
- </style>