ruby-pg-extras 5.6.15 → 5.6.17

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: e20ed34b0677aa7e50c14ca2d5a511d4854f0eb34a1ad7e04a4f94fe2349895b
4
- data.tar.gz: ef35f2a431195ba26a0271808315b54985254df379412ffb4eef9dc4ff81f7e8
3
+ metadata.gz: 743910d2bd970c03a9ca1d79d56de46d40c5742aae37d0e24021d58e5c2883c6
4
+ data.tar.gz: e6a50ce83c92f55f49119feaeddf6796c3035a9b1b1d30a2d2439af4231c744a
5
5
  SHA512:
6
- metadata.gz: 6145da151dc40da7d0f79a3a2c9ff3d059dd9b320e44b751f6d5a9d0b00d395a78aff3c8bd1bf51453aa65ccb7cf12953ec73e54b4a350d7ee34ec61b5f661a0
7
- data.tar.gz: 72861cc4517a977e39266f2617094db82be77ba31f932831785540c3bc3ae078e1deccbc32b5b025343bbbe2e2c2d25529e24dad170ea9e8969795dfe3ee64de
6
+ metadata.gz: 7c9f78aed2dfbbadbb41e9957b390b1dc4f0effd997515b7fd8679d677c210d0da9a664f14e16a0bb5f5d26016c98c40331acb9db8327073ec9ee3514a3519e8
7
+ data.tar.gz: 73f758201aac10e76af41a531b9e0bf0badec4eba00491174225ac46981d1c92e9cfedaaebba694472b036d7b603197d361948999d1a11a2d4af0d990271db7c
data/README.md CHANGED
@@ -118,7 +118,7 @@ Keep reading to learn about methods that `diagnose` uses under the hood.
118
118
 
119
119
  ### `missing_fk_indexes`
120
120
 
121
- This method lists columns likely to be foreign keys (i.e. column name ending in `_id` and related table exists) which don't have an index. It's recommended to always index foreign key columns because they are used for searching relation objects.
121
+ This method lists **actual foreign key columns** (based on existing foreign key constraints) which don't have a supporting index. It's recommended to always index foreign key columns because they are commonly used for lookups and join conditions.
122
122
 
123
123
  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.
124
124
 
@@ -136,14 +136,34 @@ RubyPgExtras.missing_fk_indexes(args: { table_name: "users" })
136
136
 
137
137
  ```
138
138
 
139
+ You can also exclude known/intentional cases using `ignore_list` (array or comma-separated string), with entries like:
140
+ - `"posts.topic_id"` (ignore a specific table+column)
141
+ - `"topic_id"` (ignore this column name for all tables)
142
+ - `"posts.*"` (ignore all columns on a table)
143
+ - `"*"` (ignore everything)
144
+
145
+ ```ruby
146
+ RubyPgExtras.missing_fk_indexes(args: { ignore_list: ["users.company_id", "posts.*"] })
147
+ ```
148
+
139
149
  `table_name` argument is optional, if omitted, the method will display missing fk indexes for all the tables.
140
150
 
141
151
  ## `missing_fk_constraints`
142
152
 
143
- 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).
153
+ This method shows **columns that look like foreign keys** but don't have a corresponding foreign key constraint yet. 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).
154
+
155
+ Heuristic notes:
156
+ - A column is considered a candidate if it matches `<table_singular>_id` and the related table exists (underscored prefixes like `account_user_id` are supported).
157
+ - Rails polymorphic associations (`<name>_id` + `<name>_type`) are ignored since they cannot be expressed as real FK constraints.
158
+
159
+ You can also exclude known/intentional cases using `ignore_list` (array or comma-separated string), with entries like:
160
+ - `"posts.category_id"` (ignore a specific table+column)
161
+ - `"category_id"` (ignore this column name for all tables)
162
+ - `"posts.*"` (ignore all columns on a table)
163
+ - `"*"` (ignore everything)
144
164
 
145
165
  ```ruby
146
- RubyPgExtras.missing_fk_constraints(args: { table_name: "users" })
166
+ RubyPgExtras.missing_fk_constraints(args: { table_name: "users", ignore_list: ["users.customer_id", "posts.*"] })
147
167
 
148
168
  +---------------------------------+
149
169
  | Missing foreign key constraints |
@@ -36,7 +36,7 @@ services:
36
36
  ports:
37
37
  - '5436:5432'
38
38
  postgres17:
39
- image: postgres:17.0-alpine
39
+ image: postgres:17.7-alpine
40
40
  command: postgres -c shared_preload_libraries=pg_stat_statements
41
41
  environment:
42
42
  POSTGRES_USER: postgres
@@ -44,4 +44,13 @@ services:
44
44
  POSTGRES_PASSWORD: secret
45
45
  ports:
46
46
  - '5437:5432'
47
+ postgres18:
48
+ image: postgres:18.1-alpine
49
+ command: postgres -c shared_preload_libraries=pg_stat_statements
50
+ environment:
51
+ POSTGRES_USER: postgres
52
+ POSTGRES_DB: ruby-pg-extras-test
53
+ POSTGRES_PASSWORD: secret
54
+ ports:
55
+ - '5438:5432'
47
56
 
@@ -192,7 +192,7 @@ module RubyPgExtras
192
192
  end
193
193
 
194
194
  def self.missing_fk_indexes(args: {}, in_format: :display_table)
195
- RubyPgExtras::MissingFkIndexes.call(args[:table_name])
195
+ RubyPgExtras::MissingFkIndexes.call(args[:table_name], ignore_list: args[:ignore_list])
196
196
  end
197
197
 
198
198
  def self.missing_fk_constraints(args: {}, in_format: :display_table)
@@ -247,6 +247,8 @@ module RubyPgExtras
247
247
  end
248
248
 
249
249
  def self.database_url=(value)
250
+ @_connection&.close
251
+ @_connection = nil
250
252
  @@database_url = value
251
253
  end
252
254
 
@@ -2,11 +2,18 @@
2
2
 
3
3
  module RubyPgExtras
4
4
  class MissingFkIndexes
5
- def self.call(table_name)
6
- new.call(table_name)
5
+ # ignore_list: array (or comma-separated string) of entries like:
6
+ # - "posts.topic_id" (ignore a specific table+column)
7
+ # - "topic_id" (ignore this column name for all tables)
8
+ # - "posts.*" (ignore all columns on a table)
9
+ # - "*" (ignore everything)
10
+ def self.call(table_name, ignore_list: nil)
11
+ new.call(table_name, ignore_list: ignore_list)
7
12
  end
8
13
 
9
- def call(table_name)
14
+ def call(table_name, ignore_list: nil)
15
+ ignore_list_matcher = IgnoreList.new(ignore_list)
16
+
10
17
  indexes_info = query_module.indexes(in_format: :hash)
11
18
  foreign_keys = query_module.foreign_keys(in_format: :hash)
12
19
 
@@ -23,6 +30,9 @@ module RubyPgExtras
23
30
  table_fks.each do |fk|
24
31
  column_name = fk.fetch("column_name")
25
32
 
33
+ # Skip columns explicitly excluded via ignore list.
34
+ next if ignore_list_matcher.ignored?(table: table, column_name: column_name)
35
+
26
36
  if index_info.none? { |row| row.fetch("columns").split(",").first == column_name }
27
37
  agg.push(
28
38
  {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyPgExtras
4
- VERSION = "5.6.15"
4
+ VERSION = "5.6.17"
5
5
  end
@@ -18,4 +18,26 @@ describe "missing_fk_indexes" do
18
18
  { table: "posts", column_name: "topic_id" },
19
19
  ])
20
20
  end
21
+
22
+ it "supports ignoring a specific table+column via args" do
23
+ result = RubyPgExtras.missing_fk_indexes(
24
+ args: { ignore_list: ["posts.topic_id"] },
25
+ in_format: :hash
26
+ )
27
+
28
+ expect(result).to eq([
29
+ { table: "users", column_name: "company_id" },
30
+ ])
31
+ end
32
+
33
+ it "supports ignoring a column name globally via args" do
34
+ result = RubyPgExtras.missing_fk_indexes(
35
+ args: { ignore_list: ["company_id"] },
36
+ in_format: :hash
37
+ )
38
+
39
+ expect(result).to eq([
40
+ { table: "posts", column_name: "topic_id" },
41
+ ])
42
+ end
21
43
  end
data/spec/smoke_spec.rb CHANGED
@@ -65,5 +65,17 @@ describe RubyPgExtras do
65
65
  RubyPgExtras.bloat(in_format: :hash)
66
66
  end.not_to raise_error
67
67
  end
68
+
69
+ it "resets the connection when setting database URL" do
70
+ old_connection = RubyPgExtras.connection
71
+ expect(old_connection).not_to be_finished
72
+
73
+ RubyPgExtras.database_url = ENV.fetch("DATABASE_URL")
74
+
75
+ expect(old_connection).to be_finished
76
+ new_connection = RubyPgExtras.connection
77
+ expect(new_connection).not_to eq(old_connection)
78
+ expect(new_connection).not_to be_finished
79
+ end
68
80
  end
69
81
  end
data/spec/spec_helper.rb CHANGED
@@ -12,9 +12,10 @@ PG_PORTS = {
12
12
  "15" => "5435",
13
13
  "16" => "5436",
14
14
  "17" => "5437",
15
+ "18" => "5438",
15
16
  }
16
17
 
17
- port = PG_PORTS.fetch(pg_version, "5432")
18
+ port = PG_PORTS.fetch(pg_version, "5438")
18
19
 
19
20
  ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-extras-test"
20
21
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-pg-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.15
4
+ version: 5.6.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-12-16 00:00:00.000000000 Z
11
+ date: 2026-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg