rails-pg-extras 5.6.12 → 5.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ab5f408e9c0a7f70fea16a4d8d2e5079b130c8bb3536a2da760aa8cc509b1cf
4
- data.tar.gz: 39a83a3ce09da9710884277245c2306ab70b3584f32885651f4553a7faf0ebbb
3
+ metadata.gz: 527209c0372ab51aa819a88d39fca67a8608c4c19c1f05e7229faa2b8fbce050
4
+ data.tar.gz: 2dd5e86b330f95e680e495d3d02bab62dfd809462e90a125e9d5f592b20cc700
5
5
  SHA512:
6
- metadata.gz: 23302e3cf2afab6463cf306dc9d7274d0da0364080e105559260b47f93ec3c55bfb7faed12185f7119a6b4a64fb64568ce637e03a8cef4188fe983039753218d
7
- data.tar.gz: 00bf2ca5b4c857ba53063f3063501d5d2d4a5b561256aef79de379b921461d041e5e50bf4667480d06a2aafad986c8c95b2437ca0cd0f87b457f62e6388104e2
6
+ metadata.gz: 02ab457a4fa05efd333e585e8413d5ea6817463a063fd4d9f546f05882ca7698d9e55f9640ee7390002afeb9bf1e637e61e24abe79487f2a788b7d2587bdb26c
7
+ data.tar.gz: 8d9ecd37ac60697ddbae46fd2e955cc26b35d56ce8252913247f552bed552b235d2eebe6adca1759e09628dfe644e656cf384ca78146b40a4b1c44cb13c21088
@@ -3,6 +3,8 @@ require "rails_pg_extras/version"
3
3
 
4
4
  module RailsPgExtras::Web
5
5
  class ApplicationController < ActionController::Base
6
+ around_action :with_selected_database
7
+ before_action :load_available_databases
6
8
  def self.get_user
7
9
  Rails.application.try(:credentials).try(:pg_extras).try(:user) || ENV["RAILS_PG_EXTRAS_USER"]
8
10
  end
@@ -31,5 +33,36 @@ module RailsPgExtras::Web
31
33
  raise "Missing credentials for rails-pg-extras dashboard! If you want to enable public dashboard please set RAILS_PG_EXTRAS_PUBLIC_DASHBOARD=true"
32
34
  end
33
35
  end
36
+
37
+ private
38
+
39
+ def with_selected_database
40
+ Thread.current[:rails_pg_extras_db_key] = params[:db_key].presence
41
+ yield
42
+ ensure
43
+ Thread.current[:rails_pg_extras_db_key] = nil
44
+ end
45
+
46
+ def load_available_databases
47
+ @available_databases = fetch_available_database_names
48
+ @current_db_key = params[:db_key].presence || default_db_key
49
+ end
50
+
51
+ def fetch_available_database_names
52
+
53
+ ActiveRecord::Base.configurations
54
+ .configs_for(env_name: Rails.env)
55
+ .filter_map { |conf| (conf.respond_to?(:name) && conf.name) || (conf.respond_to?(:spec_name) && conf.spec_name) }
56
+ .uniq
57
+ .sort
58
+
59
+ rescue
60
+ []
61
+ end
62
+
63
+ def default_db_key
64
+ # Prefer primary if available, else first available
65
+ @available_databases.include?("primary") ? "primary" : @available_databases.first
66
+ end
34
67
  end
35
68
  end
@@ -39,7 +39,7 @@ module RailsPgExtras::Web
39
39
  def unavailable_extensions
40
40
  return @unavailable_extensions if defined?(@unavailable_extensions)
41
41
 
42
- enabled_extensions = ActiveRecord::Base.connection.extensions.lazy
42
+ enabled_extensions = RailsPgExtras.connection.extensions.lazy
43
43
  @unavailable_extensions = REQUIRED_EXTENSIONS.delete_if { |ext| enabled_extensions.grep(/^([^.]+\.)?#{ext}$/).any? }
44
44
  end
45
45
  end
@@ -21,6 +21,10 @@
21
21
  </div>
22
22
  <% end %>
23
23
 
24
+ <div class="mb-4">
25
+ <%= render "rails_pg_extras/web/shared/database_selector" %>
26
+ </div>
27
+
24
28
  <%= yield %>
25
29
  </body>
26
30
  </html>
@@ -2,24 +2,32 @@
2
2
  <div class='pg-extras-help pb-4'>
3
3
  (<a href="https://pawelurbanek.com/postgresql-fix-performance"
4
4
  class="text-blue-600 hover:text-blue-800 hover:underline" target='_blank'>Tutorial</a>)
5
- </div>
6
- <div class="overflow-x-auto">
7
- <table class="w-full border border-gray-400 shadow-md rounded-lg overflow-hidden">
8
- <thead>
9
- <tr class="bg-gray-200 text-gray-900 text-left uppercase text-sm font-bold">
10
- <th class="px-4 py-3 border">Ok</th>
11
- <th class="px-4 py-3 border">Check Name</th>
12
- <th class="px-4 py-3 border">Message</th>
13
- </tr>
14
- </thead>
15
- <tbody>
16
- <% RailsPgExtras.diagnose(in_format: :hash).each do |diagnosis| %>
17
- <tr class="<%= diagnosis[:ok] ? "bg-green-100 text-green-900" : "bg-red-100 text-red-900" %> hover:bg-gray-300 transition">
18
- <td class="px-4 py-3 border font-bold"><%= diagnosis[:ok] ? "YES" : "NO" %></td>
19
- <td class="px-4 py-3 border font-semibold"><%= diagnosis[:check_name] %></td>
20
- <td class="px-4 py-3 border"><%= diagnosis[:message] %></td>
5
+ </div>
6
+ <% begin %>
7
+ <% diagnoses = RailsPgExtras.diagnose(in_format: :hash) %>
8
+ <div class="overflow-x-auto">
9
+ <table class="w-full border border-gray-400 shadow-md rounded-lg overflow-hidden">
10
+ <thead>
11
+ <tr class="bg-gray-200 text-gray-900 text-left uppercase text-sm font-bold">
12
+ <th class="px-4 py-3 border">Ok</th>
13
+ <th class="px-4 py-3 border">Check Name</th>
14
+ <th class="px-4 py-3 border">Message</th>
21
15
  </tr>
22
- <% end %>
23
- </tbody>
24
- </table>
25
- </div>
16
+ </thead>
17
+ <tbody>
18
+ <% diagnoses.each do |diagnosis| %>
19
+ <tr class="<%= diagnosis[:ok] ? "bg-green-100 text-green-900" : "bg-red-100 text-red-900" %> hover:bg-gray-300 transition">
20
+ <td class="px-4 py-3 border font-bold"><%= diagnosis[:ok] ? "YES" : "NO" %></td>
21
+ <td class="px-4 py-3 border font-semibold"><%= diagnosis[:check_name] %></td>
22
+ <td class="px-4 py-3 border"><%= diagnosis[:message] %></td>
23
+ </tr>
24
+ <% end %>
25
+ </tbody>
26
+ </table>
27
+ </div>
28
+ <% rescue => e %>
29
+ <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
30
+ <p class="font-bold">Diagnose failed</p>
31
+ <p><%= e.message %></p>
32
+ </div>
33
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <% if @available_databases.present? && @available_databases.size > 1 %>
2
+ <%= form_tag queries_path, id: "db_selector", method: :get, class: "mb-4 flex items-center gap-2" do %>
3
+ <label for="db_key" class="font-semibold">Database:</label>
4
+ <%= select_tag :db_key,
5
+ options_for_select(@available_databases, @current_db_key),
6
+ class: "border p-2 font-bold" %>
7
+ <%# Preserve current query selection if present %>
8
+ <%= hidden_field_tag :query_name, params[:query_name] if params[:query_name].present? %>
9
+ <% end %>
10
+
11
+ <%= javascript_tag nonce: true do -%>
12
+ document.getElementById('db_selector').addEventListener('change', (e) => {
13
+ e.target.form.submit()
14
+ })
15
+ <% end -%>
16
+ <% end %>
@@ -1,7 +1,9 @@
1
- <%= form_tag queries_path, id: "queries", method: :get do |f| %>
2
- <%= select_tag :query_name, options_for_select(@all_queries, params[:query_name]),
3
- { prompt: "diagnose", class: "border p-2 font-bold", autofocus: true } %>
4
- <% end %>
1
+ <%= form_tag queries_path, id: "queries", method: :get do |f| %>
2
+ <%= select_tag :query_name, options_for_select(@all_queries, params[:query_name]),
3
+ { prompt: "diagnose", class: "border p-2 font-bold", autofocus: true } %>
4
+ <%# Preserve selected database across query changes %>
5
+ <%= hidden_field_tag :db_key, params[:db_key] if params[:db_key].present? %>
6
+ <% end %>
5
7
 
6
8
  <%= javascript_tag nonce: true do -%>
7
9
  document.getElementById('queries').addEventListener('change', (e) => {
@@ -148,9 +148,37 @@ module RailsPgExtras
148
148
  end
149
149
 
150
150
  def self.connection
151
+ # Priority:
152
+ # 1) Per-request selected db (thread-local), if present -> use named configuration or URL without altering global Base
153
+ # 2) Explicit URL via setter or ENV override
154
+ # 3) Default ActiveRecord::Base connection
155
+ selected_db_key = Thread.current[:rails_pg_extras_db_key]
151
156
  db_url = @@database_url || ENV["RAILS_PG_EXTRAS_DATABASE_URL"]
152
157
 
153
- if db_url.present?
158
+ if selected_db_key.present?
159
+ const_name = selected_db_key.classify
160
+ # Use an isolated abstract class to avoid changing the global connection
161
+ thread_classes = (Thread.current[:rails_pg_extras_ar_classes] ||= {})
162
+ ar_class = (thread_classes[selected_db_key] ||= begin
163
+ if const_defined?(const_name, false)
164
+ const_get(const_name, false)
165
+ else
166
+ klass = Class.new(ActiveRecord::Base)
167
+ klass.abstract_class = true
168
+ const_set(const_name, klass)
169
+ end
170
+ end)
171
+
172
+ connector = ar_class.establish_connection(selected_db_key.to_sym)
173
+
174
+ if connector.respond_to?(:connection)
175
+ connector.connection
176
+ elsif connector.respond_to?(:lease_connection)
177
+ connector.lease_connection
178
+ else
179
+ raise "Unsupported connector: #{connector.class}"
180
+ end
181
+ elsif db_url.present?
154
182
  connector = ActiveRecord::Base.establish_connection(db_url)
155
183
 
156
184
  if connector.respond_to?(:connection)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsPgExtras
4
- VERSION = "5.6.12"
4
+ VERSION = "5.6.14"
5
5
  end
@@ -16,7 +16,9 @@ Gem::Specification.new do |s|
16
16
  s.require_paths = ["lib"]
17
17
  s.license = "MIT"
18
18
  s.add_dependency "ruby-pg-extras", RailsPgExtras::VERSION
19
- s.add_dependency "rails"
19
+ s.add_dependency "railties"
20
+ s.add_dependency "actionpack"
21
+ s.add_dependency "activerecord"
20
22
  s.add_development_dependency "rake"
21
23
  s.add_development_dependency "rspec"
22
24
  s.add_development_dependency "rufo"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-pg-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.12
4
+ version: 5.6.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-13 00:00:00.000000000 Z
11
+ date: 2025-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-pg-extras
@@ -16,16 +16,44 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.6.12
19
+ version: 5.6.14
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.6.12
26
+ version: 5.6.14
27
27
  - !ruby/object:Gem::Dependency
28
- name: rails
28
+ name: railties
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: actionpack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - ">="
@@ -105,6 +133,7 @@ files:
105
133
  - app/views/rails_pg_extras/web/queries/_unavailable_extensions_warning.html.erb
106
134
  - app/views/rails_pg_extras/web/queries/index.html.erb
107
135
  - app/views/rails_pg_extras/web/queries/show.html.erb
136
+ - app/views/rails_pg_extras/web/shared/_database_selector.html.erb
108
137
  - app/views/rails_pg_extras/web/shared/_queries_selector.html.erb
109
138
  - assets/pg-extras-rails-ujs.js
110
139
  - assets/pg-extras-tailwind.min.css