rails-pg-extras 5.5.0 → 5.6.1
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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/README.md +42 -1
- data/app/controllers/rails_pg_extras/web/application_controller.rb +11 -16
- data/app/controllers/rails_pg_extras/web/queries_controller.rb +3 -1
- data/lib/rails-pg-extras.rb +17 -25
- data/lib/rails_pg_extras/configuration.rb +1 -1
- data/lib/rails_pg_extras/missing_fk_constraints.rb +11 -0
- data/lib/rails_pg_extras/missing_fk_indexes.rb +11 -0
- data/lib/rails_pg_extras/version.rb +1 -1
- data/lib/rails_pg_extras/web.rb +1 -1
- data/spec/smoke_spec.rb +24 -2
- data/spec/spec_helper.rb +10 -15
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12c092356cb3e67c70abd5e49d61227fda3872353846b2fc18f23e83e5b33526
|
4
|
+
data.tar.gz: 795c689588341078ed71d1ab6e522ba3b2d26e968d5f1a060983f70c0a163732
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 821ad0700c0b8d6fc352e15f7c45591354ac49d061c16d67e55b1778ae1ea4b979bfd62f76dc0b0bebd6cf8716803fb7e799434deba397d28496ac634a4c34af
|
7
|
+
data.tar.gz: 5104d36a6a7e7a709f9e8be494178624b2e727d89e6958729dd00497245f11d2f8ae9a329c2ae848a00d41bf85e97b0eadb8cf17597678249e0150aa5837c120
|
data/.github/workflows/ci.yml
CHANGED
data/README.md
CHANGED
@@ -135,7 +135,7 @@ You can enable UI using a Rails engine by adding the following code in `config/r
|
|
135
135
|
mount RailsPgExtras::Web::Engine, at: 'pg_extras'
|
136
136
|
```
|
137
137
|
|
138
|
-
You can enable HTTP basic auth by specifying `Rails.application.credentials.pg_extras.user` (or `RAILS_PG_EXTRAS_USER`) and `Rails.application.credentials.pg_extras.
|
138
|
+
You can enable HTTP basic auth by specifying `Rails.application.credentials.pg_extras.user` (or `RAILS_PG_EXTRAS_USER`) and `Rails.application.credentials.pg_extras.password` (or `RAILS_PG_EXTRAS_PASSWORD`) values. Authentication is mandatory unless you specify `RAILS_PG_EXTRAS_PUBLIC_DASHBOARD=true` or set `RailsPgExtras.configuration.public_dashboard = true`.
|
139
139
|
|
140
140
|
You can configure available web actions in `config/initializers/rails_pg_extras.rb`:
|
141
141
|
|
@@ -210,6 +210,47 @@ you can add this info to the output:
|
|
210
210
|
|
211
211
|

|
212
212
|
|
213
|
+
### `missing_fk_indexes`
|
214
|
+
|
215
|
+
This method lists columns likely to be foreign keys (i.e. column name ending in `_id` and related table exists) but don't have an index. It's recommended to always index foreign key columns because they are used for searching relation objects.
|
216
|
+
|
217
|
+
You can add indexes on the columns returned by this query and later check if they are receiving scans using the [unused_indexes method](#unused_indexes). Please remember that each index decreases write performance and autovacuuming overhead, so be careful when adding multiple indexes to often updated tables.
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
RailsPgExtras.missing_fk_indexes(args: { table_name: "users" })
|
221
|
+
|
222
|
+
+---------------------------------+
|
223
|
+
| Missing foreign key indexes |
|
224
|
+
+-------------------+-------------+
|
225
|
+
| table | column_name |
|
226
|
+
+-------------------+-------------+
|
227
|
+
| feedbacks | team_id |
|
228
|
+
| votes | user_id |
|
229
|
+
+-------------------+-------------+
|
230
|
+
|
231
|
+
```
|
232
|
+
|
233
|
+
`table_name` argument is optional, if omitted, the method will display missing fk indexes for all the tables.
|
234
|
+
|
235
|
+
## `missing_fk_constraints`
|
236
|
+
|
237
|
+
Similarly to the previous method, this one shows columns likely to be foreign keys that don't have a corresponding foreign key constraint. Foreign key constraints improve data integrity in the database by preventing relations with nonexisting objects. You can read more about the benefits of using foreign keys [in this blog post](https://pawelurbanek.com/rails-postgresql-data-integrity).
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
RailsPgExtras.missing_fk_constraints(args: { table_name: "users" })
|
241
|
+
|
242
|
+
+---------------------------------+
|
243
|
+
| Missing foreign key constraints |
|
244
|
+
+-------------------+-------------+
|
245
|
+
| table | column_name |
|
246
|
+
+-------------------+-------------+
|
247
|
+
| feedbacks | team_id |
|
248
|
+
| votes | user_id |
|
249
|
+
+-------------------+-------------+
|
250
|
+
|
251
|
+
```
|
252
|
+
|
253
|
+
`table_name` argument is optional, if omitted, method will display missing fk constraints for all the tables.
|
213
254
|
|
214
255
|
### `table_info`
|
215
256
|
|
@@ -3,6 +3,14 @@ require "rails_pg_extras/version"
|
|
3
3
|
|
4
4
|
module RailsPgExtras::Web
|
5
5
|
class ApplicationController < ActionController::Base
|
6
|
+
def self.get_user
|
7
|
+
Rails.application.try(:credentials).try(:pg_extras).try(:user) || ENV["RAILS_PG_EXTRAS_USER"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.get_password
|
11
|
+
Rails.application.try(:credentials).try(:pg_extras).try(:password) || ENV["RAILS_PG_EXTRAS_PASSWORD"]
|
12
|
+
end
|
13
|
+
|
6
14
|
before_action :validate_credentials!
|
7
15
|
layout "rails_pg_extras/web/application"
|
8
16
|
|
@@ -14,27 +22,14 @@ module RailsPgExtras::Web
|
|
14
22
|
|
15
23
|
ACTIONS = %i[kill_all pg_stat_statements_reset add_extensions]
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if user.present? && password.present?
|
21
|
-
http_basic_authenticate_with name: user, password: password
|
25
|
+
if get_user.present? && get_password.present?
|
26
|
+
http_basic_authenticate_with name: get_user, password: get_password
|
22
27
|
end
|
23
28
|
|
24
29
|
def validate_credentials!
|
25
|
-
if (get_user.blank? || get_password.blank?) && RailsPgExtras.configuration.public_dashboard != true
|
30
|
+
if (self.class.get_user.blank? || self.class.get_password.blank?) && RailsPgExtras.configuration.public_dashboard != true
|
26
31
|
raise "Missing credentials for rails-pg-extras dashboard! If you want to enable public dashboard please set RAILS_PG_EXTRAS_PUBLIC_DASHBOARD=true"
|
27
32
|
end
|
28
33
|
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def get_user
|
33
|
-
Rails.application.try(:credentials).try(:pg_extras).try(:user) || ENV["RAILS_PG_EXTRAS_USER"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_password
|
37
|
-
Rails.application.try(:credentials).try(:pg_extras).try(:password) || ENV["RAILS_PG_EXTRAS_PASSWORD"]
|
38
|
-
end
|
39
34
|
end
|
40
35
|
end
|
@@ -20,8 +20,10 @@ module RailsPgExtras::Web
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
+
SKIP_QUERIES = %i[table_schema table_foreign_keys].freeze
|
24
|
+
|
23
25
|
def load_queries
|
24
|
-
@all_queries = (RailsPgExtras::QUERIES - RailsPgExtras::Web::ACTIONS).inject({}) do |memo, query_name|
|
26
|
+
@all_queries = (RailsPgExtras::QUERIES - RailsPgExtras::Web::ACTIONS - SKIP_QUERIES).inject({}) do |memo, query_name|
|
25
27
|
unless query_name.in? %i[mandelbrot]
|
26
28
|
memo[query_name] = { disabled: query_disabled?(query_name) }
|
27
29
|
end
|
data/lib/rails-pg-extras.rb
CHANGED
@@ -6,6 +6,8 @@ require "rails_pg_extras/diagnose_data"
|
|
6
6
|
require "rails_pg_extras/diagnose_print"
|
7
7
|
require "rails_pg_extras/index_info"
|
8
8
|
require "rails_pg_extras/index_info_print"
|
9
|
+
require "rails_pg_extras/missing_fk_indexes"
|
10
|
+
require "rails_pg_extras/missing_fk_constraints"
|
9
11
|
require "rails_pg_extras/table_info"
|
10
12
|
require "rails_pg_extras/table_info_print"
|
11
13
|
|
@@ -26,32 +28,12 @@ module RailsPgExtras
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.run_query(query_name:, in_format:, args: {})
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if (version = RailsPgExtras.connection.execute(pg_stat_statements_version_sql)
|
34
|
-
.to_a[0].fetch("installed_version", nil))
|
35
|
-
if Gem::Version.new(version) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
|
36
|
-
query_name = "#{query_name}_legacy".to_sym
|
37
|
-
elsif Gem::Version.new(version) >= Gem::Version.new(PG_STAT_STATEMENTS_17)
|
38
|
-
query_name = "#{query_name}_17".to_sym
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
|
44
|
-
RubyPgExtras.sql_for(query_name: query_name) % custom_args
|
45
|
-
else
|
46
|
-
RubyPgExtras.sql_for(query_name: query_name)
|
47
|
-
end
|
48
|
-
|
49
|
-
result = connection.execute(sql)
|
50
|
-
|
51
|
-
RubyPgExtras.display_result(
|
52
|
-
result,
|
53
|
-
title: RubyPgExtras.description_for(query_name: query_name),
|
31
|
+
RubyPgExtras.run_query_base(
|
32
|
+
query_name: query_name,
|
33
|
+
conn: connection,
|
34
|
+
exec_method: :execute,
|
54
35
|
in_format: in_format,
|
36
|
+
args: args,
|
55
37
|
)
|
56
38
|
end
|
57
39
|
|
@@ -150,6 +132,16 @@ module RailsPgExtras
|
|
150
132
|
end
|
151
133
|
end
|
152
134
|
|
135
|
+
def self.missing_fk_indexes(args: {}, in_format: :display_table)
|
136
|
+
result = RailsPgExtras::MissingFkIndexes.call(args[:table_name])
|
137
|
+
RubyPgExtras.display_result(result, title: "Missing foreign key indexes", in_format: in_format)
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.missing_fk_constraints(args: {}, in_format: :display_table)
|
141
|
+
result = RailsPgExtras::MissingFkConstraints.call(args[:table_name])
|
142
|
+
RubyPgExtras.display_result(result, title: "Missing foreign key constraints", in_format: in_format)
|
143
|
+
end
|
144
|
+
|
153
145
|
def self.connection
|
154
146
|
if (db_url = ENV["RAILS_PG_EXTRAS_DATABASE_URL"])
|
155
147
|
connector = ActiveRecord::Base.establish_connection(db_url)
|
@@ -4,7 +4,7 @@ require "rails_pg_extras/web"
|
|
4
4
|
|
5
5
|
module RailsPgExtras
|
6
6
|
class Configuration
|
7
|
-
DEFAULT_CONFIG = { enabled_web_actions: Web::ACTIONS - [:kill_all], public_dashboard: ENV["RAILS_PG_EXTRAS_PUBLIC_DASHBOARD"] == "true" }
|
7
|
+
DEFAULT_CONFIG = { enabled_web_actions: Web::ACTIONS - [:kill_all, :kill_pid], public_dashboard: ENV["RAILS_PG_EXTRAS_PUBLIC_DASHBOARD"] == "true" }
|
8
8
|
|
9
9
|
attr_reader :enabled_web_actions
|
10
10
|
attr_accessor :public_dashboard
|
data/lib/rails_pg_extras/web.rb
CHANGED
@@ -2,7 +2,7 @@ require "rails_pg_extras/web/engine"
|
|
2
2
|
|
3
3
|
module RailsPgExtras
|
4
4
|
module Web
|
5
|
-
ACTIONS = %i[kill_all pg_stat_statements_reset add_extensions].freeze
|
5
|
+
ACTIONS = %i[kill_all pg_stat_statements_reset add_extensions kill_pid].freeze
|
6
6
|
|
7
7
|
def self.action_enabled?(action_name)
|
8
8
|
RailsPgExtras.configuration.enabled_web_actions.include?(action_name.to_sym)
|
data/spec/smoke_spec.rb
CHANGED
@@ -4,7 +4,13 @@ require "spec_helper"
|
|
4
4
|
require "rails-pg-extras"
|
5
5
|
|
6
6
|
describe RailsPgExtras do
|
7
|
-
|
7
|
+
SKIP_QUERIES = %i[
|
8
|
+
kill_all
|
9
|
+
table_schema
|
10
|
+
table_foreign_keys
|
11
|
+
]
|
12
|
+
|
13
|
+
RailsPgExtras::QUERIES.reject { |q| SKIP_QUERIES.include?(q) }.each do |query_name|
|
8
14
|
it "#{query_name} query can be executed" do
|
9
15
|
expect do
|
10
16
|
RailsPgExtras.run_query(
|
@@ -31,7 +37,7 @@ describe RailsPgExtras do
|
|
31
37
|
|
32
38
|
it "collecting queries data works" do
|
33
39
|
output = RailsPgExtras.measure_queries { RailsPgExtras.diagnose(in_format: :hash) }
|
34
|
-
expect(output.fetch(:count)).to eq
|
40
|
+
expect(output.fetch(:count) > 0).to eq(true)
|
35
41
|
end
|
36
42
|
|
37
43
|
it "supports custom RAILS_PG_EXTRAS_DATABASE_URL" do
|
@@ -44,4 +50,20 @@ describe RailsPgExtras do
|
|
44
50
|
|
45
51
|
ENV["RAILS_PG_EXTRAS_DATABASE_URL"] = nil
|
46
52
|
end
|
53
|
+
|
54
|
+
describe "missing_fk_indexes" do
|
55
|
+
it "works" do
|
56
|
+
expect {
|
57
|
+
RailsPgExtras.missing_fk_indexes
|
58
|
+
}.not_to raise_error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "missing_fk_constraints" do
|
63
|
+
it "works" do
|
64
|
+
expect {
|
65
|
+
RailsPgExtras.missing_fk_constraints
|
66
|
+
}.not_to raise_error
|
67
|
+
end
|
68
|
+
end
|
47
69
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,21 +7,16 @@ require_relative "../lib/rails-pg-extras"
|
|
7
7
|
|
8
8
|
pg_version = ENV["PG_VERSION"]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
elsif pg_version == "17"
|
21
|
-
"5437"
|
22
|
-
else
|
23
|
-
"5432"
|
24
|
-
end
|
10
|
+
PG_PORTS = {
|
11
|
+
"12" => "5432",
|
12
|
+
"13" => "5433",
|
13
|
+
"14" => "5434",
|
14
|
+
"15" => "5435",
|
15
|
+
"16" => "5436",
|
16
|
+
"17" => "5437",
|
17
|
+
}
|
18
|
+
|
19
|
+
port = PG_PORTS.fetch(pg_version, "5432")
|
25
20
|
|
26
21
|
ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/rails-pg-extras-test"
|
27
22
|
|
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.
|
4
|
+
version: 5.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pawurb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-pg-extras
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
19
|
+
version: 5.6.1
|
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.
|
26
|
+
version: 5.6.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,6 +116,8 @@ files:
|
|
116
116
|
- lib/rails_pg_extras/diagnose_print.rb
|
117
117
|
- lib/rails_pg_extras/index_info.rb
|
118
118
|
- lib/rails_pg_extras/index_info_print.rb
|
119
|
+
- lib/rails_pg_extras/missing_fk_constraints.rb
|
120
|
+
- lib/rails_pg_extras/missing_fk_indexes.rb
|
119
121
|
- lib/rails_pg_extras/railtie.rb
|
120
122
|
- lib/rails_pg_extras/table_info.rb
|
121
123
|
- lib/rails_pg_extras/table_info_print.rb
|