ruby-pg-extras 5.3.1 → 5.4.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: 79aedbc5d3b30aadde2362bceebac04fe7bc3d3a27e8fc47f1f6b6c0ae287616
4
- data.tar.gz: ceea8978021edc90088a012a1fec34c0502da15f5ce60356074d741bcbc82682
3
+ metadata.gz: 809377163a6ca42ea4b8b0087e1d4ede8cfe326d0ee10a85a32df4d6f0e447f5
4
+ data.tar.gz: 295812fd83c470552c330bcf520749ebfcd6574270c7f2ee7d58d74c0877b968
5
5
  SHA512:
6
- metadata.gz: 6cd117553f43c9b211cb07e313f2b83932992a38e5217bdee70dd9d3688e441919bc0dd5a3db32cd7dc20a5c35dddd7b61e34a26ba403f690f3a9d3531a16eb4
7
- data.tar.gz: 484c04040d0d1579ce01e9874fd7f7df4dbc6209f3e262e55fc6b77246072c1315962e223f915b5311fe08a89268f7ac0193a04e50179307001ac37e5690f0e4
6
+ metadata.gz: bf48947fd5d74c8e7052cfcf9383521366887e22b7206cc4f830c91cbc17fa75db07279240d6a611febc0b7af6a9f03b9db7431b4a3b21cb80c416becaa13e2f
7
+ data.tar.gz: 1aa0b28a52a83e76f31a5101af38fa006f07ab2180980d3d149206925eba96ca76a7589cf194e534f621e32513fe7c313d45137933824a6600b86bb42295849d
@@ -12,43 +12,52 @@ jobs:
12
12
  strategy:
13
13
  fail-fast: false
14
14
  matrix:
15
- ruby-version: ['3.2', '3.1', '3.0', '2.7', '2.6']
15
+ ruby-version: ['3.3', '3.2', '3.1', '3.0', '2.7', '2.6']
16
16
  steps:
17
- - uses: actions/checkout@v3
18
- - name: Run PostgreSQL 11
17
+ - uses: actions/checkout@v4
18
+ - name: Run PostgreSQL 12
19
19
  run: |
20
20
  docker run --env POSTGRES_USER=postgres \
21
21
  --env POSTGRES_DB=ruby-pg-extras-test \
22
22
  --env POSTGRES_PASSWORD=secret \
23
- -d -p 5432:5432 postgres:11.18-alpine \
23
+ -d -p 5432:5432 postgres:12.20-alpine \
24
24
  postgres -c shared_preload_libraries=pg_stat_statements
25
- - name: Run PostgreSQL 12
25
+ - name: Run PostgreSQL 13
26
26
  run: |
27
27
  docker run --env POSTGRES_USER=postgres \
28
28
  --env POSTGRES_DB=ruby-pg-extras-test \
29
29
  --env POSTGRES_PASSWORD=secret \
30
- -d -p 5433:5432 postgres:12.13-alpine \
30
+ -d -p 5433:5432 postgres:13.16-alpine \
31
31
  postgres -c shared_preload_libraries=pg_stat_statements
32
- - name: Run PostgreSQL 13
32
+ - name: Run PostgreSQL 14
33
33
  run: |
34
34
  docker run --env POSTGRES_USER=postgres \
35
35
  --env POSTGRES_DB=ruby-pg-extras-test \
36
36
  --env POSTGRES_PASSWORD=secret \
37
- -d -p 5434:5432 postgres:13.9-alpine \
37
+ -d -p 5434:5432 postgres:14.13-alpine \
38
38
  postgres -c shared_preload_libraries=pg_stat_statements
39
- - name: Run PostgreSQL 14
39
+ - name: Run PostgreSQL 15
40
40
  run: |
41
41
  docker run --env POSTGRES_USER=postgres \
42
42
  --env POSTGRES_DB=ruby-pg-extras-test \
43
43
  --env POSTGRES_PASSWORD=secret \
44
- -d -p 5435:5432 postgres:14.6-alpine \
44
+ -d -p 5435:5432 postgres:15.8-alpine \
45
45
  postgres -c shared_preload_libraries=pg_stat_statements
46
- - name: Run PostgreSQL 15
46
+ sleep 15
47
+ - name: Run PostgreSQL 16
48
+ run: |
49
+ docker run --env POSTGRES_USER=postgres \
50
+ --env POSTGRES_DB=ruby-pg-extras-test \
51
+ --env POSTGRES_PASSWORD=secret \
52
+ -d -p 5436:5432 postgres:16.4-alpine \
53
+ postgres -c shared_preload_libraries=pg_stat_statements
54
+ sleep 15
55
+ - name: Run PostgreSQL 17
47
56
  run: |
48
57
  docker run --env POSTGRES_USER=postgres \
49
58
  --env POSTGRES_DB=ruby-pg-extras-test \
50
59
  --env POSTGRES_PASSWORD=secret \
51
- -d -p 5436:5432 postgres:15.1-alpine \
60
+ -d -p 5437:5432 postgres:17.0-alpine \
52
61
  postgres -c shared_preload_libraries=pg_stat_statements
53
62
  sleep 15
54
63
  - name: Set up Ruby ${{ matrix.ruby-version }}
@@ -57,72 +66,65 @@ jobs:
57
66
  ruby-version: ${{ matrix.ruby-version }}
58
67
  - name: Setup dependencies
59
68
  run: |
60
- gem update --system
61
- gem install bundler
69
+ gem install bundler -v 2.4.22
62
70
  sudo apt-get update --allow-releaseinfo-change
63
71
  sudo apt install postgresql-client
64
72
  sudo apt install libpq-dev
65
73
  bundle config set --local path 'vendor/bundle'
66
74
  bundle install
67
75
  sleep 10
68
- - name: Run tests for PG 11
76
+ - name: Run tests for PG 12
69
77
  env:
70
- PG_VERSION: 11
78
+ PG_VERSION: 12
71
79
  POSTGRES_HOST: localhost
72
80
  POSTGRES_USER: postgres
73
81
  POSTGRES_DB: ruby-pg-extras-test
74
82
  POSTGRES_PASSWORD: secret
75
- DATABASE_URL: postgresql://postgres:secret@localhost:5432/ruby-pg-extras-test
76
83
  run: |
77
84
  bundle exec rspec spec/
78
- - name: Run tests for PG 11
85
+ - name: Run tests for PG 13
79
86
  env:
80
- PG_VERSION: 11
87
+ PG_VERSION: 13
81
88
  POSTGRES_HOST: localhost
82
89
  POSTGRES_USER: postgres
83
90
  POSTGRES_DB: ruby-pg-extras-test
84
91
  POSTGRES_PASSWORD: secret
85
- DATABASE_URL: postgresql://postgres:secret@localhost:5432/ruby-pg-extras-test
86
92
  run: |
87
93
  bundle exec rspec spec/
88
- - name: Run tests for PG 12
94
+ - name: Run tests for PG 14
89
95
  env:
90
- PG_VERSION: 12
96
+ PG_VERSION: 14
91
97
  POSTGRES_HOST: localhost
92
98
  POSTGRES_USER: postgres
93
99
  POSTGRES_DB: ruby-pg-extras-test
94
100
  POSTGRES_PASSWORD: secret
95
- DATABASE_URL: postgresql://postgres:secret@localhost:5433/ruby-pg-extras-test
96
101
  run: |
97
102
  bundle exec rspec spec/
98
- - name: Run tests for PG 13
103
+ - name: Run tests for PG 15
99
104
  env:
100
- PG_VERSION: 13
105
+ PG_VERSION: 15
101
106
  POSTGRES_HOST: localhost
102
107
  POSTGRES_USER: postgres
103
108
  POSTGRES_DB: ruby-pg-extras-test
104
109
  POSTGRES_PASSWORD: secret
105
- DATABASE_URL: postgresql://postgres:secret@localhost:5434/ruby-pg-extras-test
106
110
  run: |
107
111
  bundle exec rspec spec/
108
- - name: Run tests for PG 14
112
+ - name: Run tests for PG 16
109
113
  env:
110
- PG_VERSION: 14
114
+ PG_VERSION: 16
111
115
  POSTGRES_HOST: localhost
112
116
  POSTGRES_USER: postgres
113
117
  POSTGRES_DB: ruby-pg-extras-test
114
118
  POSTGRES_PASSWORD: secret
115
- DATABASE_URL: postgresql://postgres:secret@localhost:5435/ruby-pg-extras-test
116
119
  run: |
117
120
  bundle exec rspec spec/
118
- - name: Run tests for PG 15
121
+ - name: Run tests for PG 17
119
122
  env:
120
- PG_VERSION: 15
123
+ PG_VERSION: 17
121
124
  POSTGRES_HOST: localhost
122
125
  POSTGRES_USER: postgres
123
126
  POSTGRES_DB: ruby-pg-extras-test
124
127
  POSTGRES_PASSWORD: secret
125
- DATABASE_URL: postgresql://postgres:secret@localhost:5436/ruby-pg-extras-test
126
128
  run: |
127
129
  bundle exec rspec spec/
128
130
 
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/README.md CHANGED
@@ -10,6 +10,8 @@ Alternative versions:
10
10
 
11
11
  - [Ruby on Rails](https://github.com/pawurb/rails-pg-extras)
12
12
 
13
+ - [Rust](https://github.com/pawurb/rust-pg-extras)
14
+
13
15
  - [NodeJS](https://github.com/pawurb/node-postgres-extras)
14
16
 
15
17
  - [Elixir](https://github.com/pawurb/ecto_psql_extras)
@@ -98,6 +100,8 @@ RubyPgExtras.long_running_queries(args: { threshold: "200 milliseconds" })
98
100
 
99
101
  ```
100
102
 
103
+ You can customize the default `public` schema by setting `ENV['PG_EXTRAS_SCHEMA']` value.
104
+
101
105
  ## Diagnose report
102
106
 
103
107
  The simplest way to start using pg-extras is to execute a `diagnose` method. It runs a set of checks and prints out a report highlighting areas that may require additional investigation:
@@ -437,7 +441,7 @@ This command displays the total size of each table and materialized view in the
437
441
 
438
442
  ```ruby
439
443
 
440
- RubyPgExtras.unused_indexes(args: { max_scans: 20 })
444
+ RubyPgExtras.unused_indexes(args: { max_scans: 50 })
441
445
 
442
446
  table | index | index_size | index_scans
443
447
  ---------------------+--------------------------------------------+------------+-------------
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
2
+ require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- desc 'Test all PG versions'
6
+ desc "Test all PG versions"
7
7
  task :test_all do
8
- system("PG_VERSION=11 bundle exec rspec spec/ && PG_VERSION=12 bundle exec rspec spec/ && PG_VERSION=13 bundle exec rspec spec/ && PG_VERSION=14 bundle exec rspec spec/")
8
+ system("PG_VERSION=12 bundle exec rspec spec/ && PG_VERSION=13 bundle exec rspec spec/ && PG_VERSION=14 bundle exec rspec spec/ && PG_VERSION=15 bundle exec rspec spec/ && PG_VERSION=16 bundle exec rspec spec/ && PG_VERSION=17 bundle exec rspec spec/")
9
9
  end
@@ -1,8 +1,6 @@
1
- version: '3'
2
-
3
1
  services:
4
- postgres11:
5
- image: postgres:11.16-alpine
2
+ postgres12:
3
+ image: postgres:12.20-alpine
6
4
  command: postgres -c shared_preload_libraries=pg_stat_statements
7
5
  environment:
8
6
  POSTGRES_USER: postgres
@@ -10,8 +8,8 @@ services:
10
8
  POSTGRES_PASSWORD: secret
11
9
  ports:
12
10
  - '5432:5432'
13
- postgres12:
14
- image: postgres:12.11-alpine
11
+ postgres13:
12
+ image: postgres:13.16-alpine
15
13
  command: postgres -c shared_preload_libraries=pg_stat_statements
16
14
  environment:
17
15
  POSTGRES_USER: postgres
@@ -19,8 +17,8 @@ services:
19
17
  POSTGRES_PASSWORD: secret
20
18
  ports:
21
19
  - '5433:5432'
22
- postgres13:
23
- image: postgres:13.7-alpine
20
+ postgres14:
21
+ image: postgres:14.13-alpine
24
22
  command: postgres -c shared_preload_libraries=pg_stat_statements
25
23
  environment:
26
24
  POSTGRES_USER: postgres
@@ -28,8 +26,8 @@ services:
28
26
  POSTGRES_PASSWORD: secret
29
27
  ports:
30
28
  - '5434:5432'
31
- postgres14:
32
- image: postgres:14.3-alpine
29
+ postgres15:
30
+ image: postgres:15.8-alpine
33
31
  command: postgres -c shared_preload_libraries=pg_stat_statements
34
32
  environment:
35
33
  POSTGRES_USER: postgres
@@ -37,3 +35,22 @@ services:
37
35
  POSTGRES_PASSWORD: secret
38
36
  ports:
39
37
  - '5435:5432'
38
+ postgres16:
39
+ image: postgres:16.4-alpine
40
+ command: postgres -c shared_preload_libraries=pg_stat_statements
41
+ environment:
42
+ POSTGRES_USER: postgres
43
+ POSTGRES_DB: ruby-pg-extras-test
44
+ POSTGRES_PASSWORD: secret
45
+ ports:
46
+ - '5436:5432'
47
+ postgres17:
48
+ image: postgres:17.0-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
+ - '5437:5432'
56
+
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'terminal-table'
4
- require 'uri'
5
- require 'pg'
6
- require 'ruby_pg_extras/size_parser'
7
- require 'ruby_pg_extras/diagnose_data'
8
- require 'ruby_pg_extras/diagnose_print'
9
- require 'ruby_pg_extras/index_info'
10
- require 'ruby_pg_extras/index_info_print'
11
- require 'ruby_pg_extras/table_info'
12
- require 'ruby_pg_extras/table_info_print'
3
+ require "terminal-table"
4
+ require "uri"
5
+ require "pg"
6
+ require "ruby_pg_extras/size_parser"
7
+ require "ruby_pg_extras/diagnose_data"
8
+ require "ruby_pg_extras/diagnose_print"
9
+ require "ruby_pg_extras/index_info"
10
+ require "ruby_pg_extras/index_info_print"
11
+ require "ruby_pg_extras/table_info"
12
+ require "ruby_pg_extras/table_info_print"
13
13
 
14
14
  module RubyPgExtras
15
15
  @@database_url = nil
16
16
  NEW_PG_STAT_STATEMENTS = "1.8"
17
+ PG_STAT_STATEMENTS_17 = "1.11"
17
18
 
18
19
  QUERIES = %i(
19
20
  add_extensions bloat blocking cache_hit db_settings
@@ -27,16 +28,18 @@ module RubyPgExtras
27
28
  buffercache_usage ssl_used connections
28
29
  )
29
30
 
30
- DEFAULT_SCHEMA = ENV["PG_EXTRAS_SCHEMA"] || 'public'
31
+ DEFAULT_SCHEMA = ENV["PG_EXTRAS_SCHEMA"] || "public"
31
32
 
32
33
  DEFAULT_ARGS = Hash.new({}).merge({
33
34
  calls: { limit: 10 },
34
35
  calls_legacy: { limit: 10 },
36
+ calls_17: { limit: 10 },
35
37
  long_running_queries: { threshold: "500 milliseconds" },
36
38
  locks: { limit: 20 },
37
39
  blocking: { limit: 20 },
38
40
  outliers: { limit: 10 },
39
41
  outliers_legacy: { limit: 10 },
42
+ outliers_17: { limit: 10 },
40
43
  buffercache_stats: { limit: 10 },
41
44
  buffercache_usage: { limit: 20 },
42
45
  unused_indexes: { max_scans: 50, schema: DEFAULT_SCHEMA },
@@ -50,7 +53,7 @@ module RubyPgExtras
50
53
  table_index_scans: { schema: DEFAULT_SCHEMA },
51
54
  records_rank: { schema: DEFAULT_SCHEMA },
52
55
  tables: { schema: DEFAULT_SCHEMA },
53
- kill_pid: { pid: 0 }
56
+ kill_pid: { pid: 0 },
54
57
  })
55
58
 
56
59
  QUERIES.each do |query_name|
@@ -58,7 +61,7 @@ module RubyPgExtras
58
61
  run_query(
59
62
  query_name: query_name,
60
63
  in_format: options.fetch(:in_format, :display_table),
61
- args: options.fetch(:args, {})
64
+ args: options.fetch(:args, {}),
62
65
  )
63
66
  end
64
67
  end
@@ -70,21 +73,23 @@ module RubyPgExtras
70
73
  if pg_stat_statements_ver != nil
71
74
  if Gem::Version.new(pg_stat_statements_ver) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
72
75
  query_name = "#{query_name}_legacy".to_sym
76
+ elsif Gem::Version.new(pg_stat_statements_ver) >= Gem::Version.new(PG_STAT_STATEMENTS_17)
77
+ query_name = "#{query_name}_17".to_sym
73
78
  end
74
79
  end
75
80
  end
76
81
 
77
82
  sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
78
- sql_for(query_name: query_name) % custom_args
79
- else
80
- sql_for(query_name: query_name)
81
- end
83
+ sql_for(query_name: query_name) % custom_args
84
+ else
85
+ sql_for(query_name: query_name)
86
+ end
82
87
  result = connection.exec(sql)
83
88
 
84
89
  display_result(
85
90
  result,
86
91
  title: description_for(query_name: query_name),
87
- in_format: in_format
92
+ in_format: in_format,
88
93
  )
89
94
  end
90
95
 
@@ -140,15 +145,15 @@ module RubyPgExtras
140
145
  result
141
146
  when :display_table
142
147
  headings = if result.count > 0
143
- result[0].keys
144
- else
145
- ["No results"]
146
- end
148
+ result[0].keys
149
+ else
150
+ ["No results"]
151
+ end
147
152
 
148
153
  puts Terminal::Table.new(
149
154
  title: title,
150
155
  headings: headings,
151
- rows: result.values
156
+ rows: result.values,
152
157
  )
153
158
  else
154
159
  raise "Invalid in_format option"
@@ -22,7 +22,7 @@ module RubyPgExtras
22
22
  :unused_indexes,
23
23
  :null_indexes,
24
24
  :bloat,
25
- :duplicate_indexes
25
+ :duplicate_indexes,
26
26
  ].yield_self do |checks|
27
27
  extensions_data = query_module.extensions(in_format: :hash)
28
28
 
@@ -66,12 +66,12 @@ module RubyPgExtras
66
66
  if table_cache_hit_ratio > min_expected
67
67
  {
68
68
  ok: true,
69
- message: "Table cache hit ratio is correct: #{table_cache_hit_ratio}."
69
+ message: "Table cache hit ratio is correct: #{table_cache_hit_ratio}.",
70
70
  }
71
71
  else
72
72
  {
73
73
  ok: false,
74
- message: "Table hit ratio is too low: #{table_cache_hit_ratio}."
74
+ message: "Table hit ratio is too low: #{table_cache_hit_ratio}.",
75
75
  }
76
76
  end
77
77
  end
@@ -87,12 +87,12 @@ module RubyPgExtras
87
87
  if index_cache_hit_ratio > min_expected
88
88
  {
89
89
  ok: true,
90
- message: "Index hit ratio is correct: #{index_cache_hit_ratio}."
90
+ message: "Index hit ratio is correct: #{index_cache_hit_ratio}.",
91
91
  }
92
92
  else
93
93
  {
94
94
  ok: false,
95
- message: "Index hit ratio is too low: #{index_cache_hit_ratio}."
95
+ message: "Index hit ratio is too low: #{index_cache_hit_ratio}.",
96
96
  }
97
97
  end
98
98
  end
@@ -103,12 +103,12 @@ module RubyPgExtras
103
103
  if ssl_connection
104
104
  {
105
105
  ok: true,
106
- message: "Database client is using a secure SSL connection."
106
+ message: "Database client is using a secure SSL connection.",
107
107
  }
108
108
  else
109
109
  {
110
110
  ok: false,
111
- message: "Database client is using an unencrypted connection."
111
+ message: "Database client is using an unencrypted connection.",
112
112
  }
113
113
  end
114
114
  end
@@ -116,7 +116,7 @@ module RubyPgExtras
116
116
  def unused_indexes
117
117
  indexes = query_module.unused_indexes(
118
118
  in_format: :hash,
119
- args: { min_scans: PG_EXTRAS_UNUSED_INDEXES_MAX_SCANS }
119
+ args: { min_scans: PG_EXTRAS_UNUSED_INDEXES_MAX_SCANS },
120
120
  ).select do |i|
121
121
  SizeParser.to_i(i.fetch("index_size").strip) >= PG_EXTRAS_UNUSED_INDEXES_MIN_SIZE_BYTES
122
122
  end
@@ -124,15 +124,15 @@ module RubyPgExtras
124
124
  if indexes.count == 0
125
125
  {
126
126
  ok: true,
127
- message: "No unused indexes detected."
127
+ message: "No unused indexes detected.",
128
128
  }
129
129
  else
130
130
  print_indexes = indexes.map do |i|
131
- "'#{i.fetch('index')}' on '#{i.fetch('table')}' size #{i.fetch('index_size')}"
131
+ "'#{i.fetch("index")}' on '#{i.fetch("table")}' size #{i.fetch("index_size")}"
132
132
  end.join(",\n")
133
133
  {
134
134
  ok: false,
135
- message: "Unused indexes detected:\n#{print_indexes}"
135
+ message: "Unused indexes detected:\n#{print_indexes}",
136
136
  }
137
137
  end
138
138
  end
@@ -140,7 +140,7 @@ module RubyPgExtras
140
140
  def null_indexes
141
141
  indexes = query_module.null_indexes(
142
142
  in_format: :hash,
143
- args: { min_relation_size_mb: PG_EXTRAS_NULL_INDEXES_MIN_SIZE_MB }
143
+ args: { min_relation_size_mb: PG_EXTRAS_NULL_INDEXES_MIN_SIZE_MB },
144
144
  ).select do |i|
145
145
  i.fetch("null_frac").gsub("%", "").to_f >= PG_EXTRAS_NULL_MIN_NULL_FRAC_PERCENT
146
146
  end
@@ -148,15 +148,15 @@ module RubyPgExtras
148
148
  if indexes.count == 0
149
149
  {
150
150
  ok: true,
151
- message: "No null indexes detected."
151
+ message: "No null indexes detected.",
152
152
  }
153
153
  else
154
154
  print_indexes = indexes.map do |i|
155
- "'#{i.fetch('index')}' size #{i.fetch('index_size')} null values fraction #{i.fetch('null_frac')}"
155
+ "'#{i.fetch("index")}' size #{i.fetch("index_size")} null values fraction #{i.fetch("null_frac")}"
156
156
  end.join(",\n")
157
157
  {
158
158
  ok: false,
159
- message: "Null indexes detected:\n#{print_indexes}"
159
+ message: "Null indexes detected:\n#{print_indexes}",
160
160
  }
161
161
  end
162
162
  end
@@ -169,16 +169,16 @@ module RubyPgExtras
169
169
  if bloat_data.count == 0
170
170
  {
171
171
  ok: true,
172
- message: "No bloat detected."
172
+ message: "No bloat detected.",
173
173
  }
174
174
  else
175
175
  print_bloat = bloat_data.map do |b|
176
- "'#{b.fetch('object_name')}' bloat #{b.fetch('bloat')} waste #{b.fetch('waste')}"
176
+ "'#{b.fetch("object_name")}' bloat #{b.fetch("bloat")} waste #{b.fetch("waste")}"
177
177
  end.join(",\n")
178
178
 
179
179
  {
180
180
  ok: false,
181
- message: "Bloat detected:\n#{print_bloat}"
181
+ message: "Bloat detected:\n#{print_bloat}",
182
182
  }
183
183
  end
184
184
  end
@@ -189,16 +189,16 @@ module RubyPgExtras
189
189
  if indexes.count == 0
190
190
  {
191
191
  ok: true,
192
- message: "No duplicate indexes detected."
192
+ message: "No duplicate indexes detected.",
193
193
  }
194
194
  else
195
195
  print_indexes = indexes.map do |i|
196
- "'#{i.fetch('idx1')}' of size #{i.fetch('size')} is identical to '#{i.fetch('idx2')}'"
196
+ "'#{i.fetch("idx1")}' of size #{i.fetch("size")} is identical to '#{i.fetch("idx2")}'"
197
197
  end.join(",\n")
198
198
 
199
199
  {
200
200
  ok: false,
201
- message: "Duplicate indexes detected:\n#{print_indexes}"
201
+ message: "Duplicate indexes detected:\n#{print_indexes}",
202
202
  }
203
203
  end
204
204
  end
@@ -211,16 +211,16 @@ module RubyPgExtras
211
211
  if queries.count == 0
212
212
  {
213
213
  ok: true,
214
- message: "No queries using significant execution ratio detected."
214
+ message: "No queries using significant execution ratio detected.",
215
215
  }
216
216
  else
217
217
  print_queries = queries.map do |q|
218
- "'#{q.fetch('query').slice(0, 30)}...' called #{q.fetch('ncalls')} times, using #{q.fetch('prop_exec_time')} of total exec time."
218
+ "'#{q.fetch("query").slice(0, 30)}...' called #{q.fetch("ncalls")} times, using #{q.fetch("prop_exec_time")} of total exec time."
219
219
  end.join(",\n")
220
220
 
221
221
  {
222
222
  ok: false,
223
- message: "Queries using significant execution ratio detected:\n#{print_queries}"
223
+ message: "Queries using significant execution ratio detected:\n#{print_queries}",
224
224
  }
225
225
  end
226
226
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'terminal-table'
3
+ require "terminal-table"
4
4
 
5
5
  module RubyPgExtras
6
6
  class DiagnosePrint
@@ -17,13 +17,13 @@ module RubyPgExtras
17
17
 
18
18
  [
19
19
  colorize("[#{symbol}] - #{el.fetch(:check_name)}", color),
20
- colorize(el.fetch(:message), color)
20
+ colorize(el.fetch(:message), color),
21
21
  ]
22
22
  end
23
23
 
24
24
  puts Terminal::Table.new(
25
25
  title: title,
26
- rows: rows
26
+ rows: rows,
27
27
  )
28
28
  end
29
29
 
@@ -19,16 +19,16 @@ module RubyPgExtras
19
19
  {
20
20
  index_name: index_name,
21
21
  table_name: index_data.fetch("tablename"),
22
- columns: index_data.fetch("columns").split(',').map(&:strip),
22
+ columns: index_data.fetch("columns").split(",").map(&:strip),
23
23
  index_size: index_size_data.find do |el|
24
24
  el.fetch("name") == index_name
25
25
  end.fetch("size", "N/A"),
26
- index_scans: index_scans_data.find do |el|
26
+ index_scans: index_scans_data.find do |el|
27
27
  el.fetch("index") == index_name
28
28
  end.fetch("index_scans", "N/A"),
29
29
  null_frac: null_indexes_data.find do |el|
30
30
  el.fetch("index") == index_name
31
- end&.fetch("null_frac", "N/A")&.strip || "0.00%"
31
+ end&.fetch("null_frac", "N/A")&.strip || "0.00%",
32
32
  }
33
33
  end
34
34
  end
@@ -40,7 +40,7 @@ module RubyPgExtras
40
40
  def null_indexes_data
41
41
  @_null_indexes_data ||= query_module.null_indexes(
42
42
  in_format: :hash,
43
- args: { min_relation_size_mb: 0 }
43
+ args: { min_relation_size_mb: 0 },
44
44
  )
45
45
  end
46
46
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'terminal-table'
3
+ require "terminal-table"
4
4
 
5
5
  module RubyPgExtras
6
6
  class IndexInfoPrint
@@ -13,10 +13,10 @@ module RubyPgExtras
13
13
  [
14
14
  el.fetch(:index_name),
15
15
  el.fetch(:table_name),
16
- el.fetch(:columns).join(', '),
16
+ el.fetch(:columns).join(", "),
17
17
  el.fetch(:index_size),
18
18
  el.fetch(:index_scans),
19
- el.fetch(:null_frac)
19
+ el.fetch(:null_frac),
20
20
  ]
21
21
  end
22
22
 
@@ -27,10 +27,10 @@ module RubyPgExtras
27
27
  "Columns",
28
28
  "Index size",
29
29
  "Index scans",
30
- "Null frac"
30
+ "Null frac",
31
31
  ],
32
32
  title: title,
33
- rows: rows
33
+ rows: rows,
34
34
  )
35
35
  end
36
36
 
@@ -4,6 +4,8 @@ SELECT
4
4
  pg_stat_activity.pid,
5
5
  pg_class.relname,
6
6
  pg_locks.transactionid,
7
+ pg_locks.locktype,
8
+ pg_locks.database,
7
9
  pg_locks.granted,
8
10
  pg_locks.mode,
9
11
  pg_stat_activity.query AS query_snippet,
@@ -0,0 +1,9 @@
1
+ /* Queries that have highest frequency of execution */
2
+
3
+ SELECT query AS qry,
4
+ interval '1 millisecond' * total_exec_time AS exec_time,
5
+ to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%%' AS prop_exec_time,
6
+ to_char(calls, 'FM999G999G990') AS ncalls,
7
+ interval '1 millisecond' * (shared_blk_read_time + shared_blk_write_time) AS sync_io_time
8
+ FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
9
+ ORDER BY calls DESC LIMIT %{limit};
@@ -4,6 +4,8 @@ SELECT
4
4
  pg_stat_activity.pid,
5
5
  pg_class.relname,
6
6
  pg_locks.transactionid,
7
+ pg_locks.locktype,
8
+ pg_locks.database,
7
9
  pg_locks.granted,
8
10
  pg_locks.mode,
9
11
  pg_stat_activity.query AS query_snippet,
@@ -0,0 +1,10 @@
1
+ /* Queries that have longest execution time in aggregate */
2
+
3
+ SELECT interval '1 millisecond' * total_exec_time AS total_exec_time,
4
+ to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%%' AS prop_exec_time,
5
+ to_char(calls, 'FM999G999G999G990') AS ncalls,
6
+ interval '1 millisecond' * (shared_blk_read_time + shared_blk_write_time) AS sync_io_time,
7
+ query AS query
8
+ FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
9
+ ORDER BY total_exec_time DESC
10
+ LIMIT %{limit};
@@ -10,7 +10,7 @@ module RubyPgExtras
10
10
  end
11
11
 
12
12
  def self.regexp_for_units(units)
13
- /\A(-?\d+)\s?(#{units.join('|')})\z/i
13
+ /\A(-?\d+)\s?(#{units.join("|")})\z/i
14
14
  end
15
15
 
16
16
  SI_UNITS = %w[bytes kB MB GB TB PB EB ZB YB].map(&:downcase).freeze
@@ -32,7 +32,7 @@ module RubyPgExtras
32
32
  return nil unless match_data
33
33
 
34
34
  exponent = units.index(match_data[2].downcase).to_i
35
- match_data[1].to_i * multiplier**exponent
35
+ match_data[1].to_i * multiplier ** exponent
36
36
  end
37
37
 
38
38
  DIGITS_ONLY_REGEXP = /\A(-?\d+)\z/.freeze
@@ -35,7 +35,7 @@ module RubyPgExtras
35
35
  end.fetch("count", "N/A"),
36
36
  indexes_scans: table_index_scans_data.find do |el|
37
37
  el.fetch("name") == table_name
38
- end.fetch("count", "N/A")
38
+ end.fetch("count", "N/A"),
39
39
  }
40
40
  end
41
41
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'terminal-table'
3
+ require "terminal-table"
4
4
 
5
5
  module RubyPgExtras
6
6
  class TableInfoPrint
@@ -17,7 +17,7 @@ module RubyPgExtras
17
17
  el.fetch(:indexes_cache_hit),
18
18
  el.fetch(:estimated_rows),
19
19
  el.fetch(:sequential_scans),
20
- el.fetch(:indexes_scans)
20
+ el.fetch(:indexes_scans),
21
21
  ]
22
22
  end
23
23
 
@@ -29,10 +29,10 @@ module RubyPgExtras
29
29
  "Indexes cache hit",
30
30
  "Estimated rows",
31
31
  "Sequential scans",
32
- "Indexes scans"
32
+ "Indexes scans",
33
33
  ],
34
34
  title: title,
35
- rows: rows
35
+ rows: rows,
36
36
  )
37
37
  end
38
38
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyPgExtras
4
- VERSION = "5.3.1"
4
+ VERSION = "5.4.1"
5
5
  end
@@ -1,24 +1,25 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'ruby_pg_extras/version'
4
+ require "ruby_pg_extras/version"
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "ruby-pg-extras"
8
- s.version = RubyPgExtras::VERSION
9
- s.authors = ["pawurb"]
10
- s.email = ["contact@pawelurbanek.com"]
11
- s.summary = %q{ Ruby PostgreSQL performance database insights }
12
- s.description = %q{ Ruby port of Heroku PG Extras. The goal of this project is to provide a powerful insights into PostgreSQL database for Ruby on Rails apps that are not using the default Heroku PostgreSQL plugin. }
13
- s.homepage = "http://github.com/pawurb/ruby-pg-extras"
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = s.files.grep(%r{^(spec)/})
7
+ s.name = "ruby-pg-extras"
8
+ s.version = RubyPgExtras::VERSION
9
+ s.authors = ["pawurb"]
10
+ s.email = ["contact@pawelurbanek.com"]
11
+ s.summary = %q{ Ruby PostgreSQL performance database insights }
12
+ s.description = %q{ Ruby port of Heroku PG Extras. The goal of this project is to provide a powerful insights into PostgreSQL database for Ruby on Rails apps that are not using the default Heroku PostgreSQL plugin. }
13
+ s.homepage = "http://github.com/pawurb/ruby-pg-extras"
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = s.files.grep(%r{^(spec)/})
16
16
  s.require_paths = ["lib"]
17
- s.license = "MIT"
17
+ s.license = "MIT"
18
18
  s.add_dependency "pg"
19
19
  s.add_dependency "terminal-table"
20
20
  s.add_development_dependency "rake"
21
21
  s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rufo"
22
23
 
23
24
  if s.respond_to?(:metadata=)
24
25
  s.metadata = { "rubygems_mfa_required" => "true" }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras::DiagnoseData do
6
6
  subject(:result) do
@@ -14,7 +14,7 @@ describe RubyPgExtras::DiagnoseData do
14
14
  [
15
15
  { "table" => "public.plans", "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "index_scans" => 0 },
16
16
  { "table" => "public.feedbacks", "index" => "index_feedbacks_on_target_id", "index_size" => "111180 bytes", "index_scans" => 1 },
17
- { "table" => "public.channels", "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "index_scans" => 7}
17
+ { "table" => "public.channels", "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "index_scans" => 7 },
18
18
  ]
19
19
  }
20
20
 
@@ -22,7 +22,7 @@ describe RubyPgExtras::DiagnoseData do
22
22
  [
23
23
  { "oid" => 123, "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "unique" => true, "null_frac" => "00.00%", "expected_saving" => "0 kb" },
24
24
  { "oid" => 321, "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "unique" => true, "null_frac" => "97.00%", "expected_saving" => "77 kb" },
25
- { "oid" => 231, "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "unique" => true, "null_frac" => "49.99%", "expected_saving" => "28 MB" }
25
+ { "oid" => 231, "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "unique" => true, "null_frac" => "49.99%", "expected_saving" => "28 MB" },
26
26
  ]
27
27
  }
28
28
 
@@ -30,19 +30,19 @@ describe RubyPgExtras::DiagnoseData do
30
30
  [
31
31
  { "type" => "table", "schemaname" => "public", "object_name" => "bloated_table_1", "bloat" => 8, "waste" => "0 kb" },
32
32
  { "type" => "table", "schemaname" => "public", "object_name" => "bloated_table_2", "bloat" => 8, "waste" => "77 kb" },
33
- { "type" => "schemaname", "public" => "index_channels_on_slack_id", "object_name" => "bloated_index", "bloat" => 11, "waste" => "28 MB" }
33
+ { "type" => "schemaname", "public" => "index_channels_on_slack_id", "object_name" => "bloated_index", "bloat" => 11, "waste" => "28 MB" },
34
34
  ]
35
35
  }
36
36
 
37
37
  expect(RubyPgExtras).to receive(:duplicate_indexes) {
38
38
  [
39
- { "size" => "128 kb", "idx1" => "users_pkey", "idx2" => "index_users_id" }
39
+ { "size" => "128 kb", "idx1" => "users_pkey", "idx2" => "index_users_id" },
40
40
  ]
41
41
  }
42
42
 
43
43
  expect(RubyPgExtras).to receive(:outliers) {
44
44
  [
45
- { "query" => "SELECT * FROM users WHERE users.age > 20 AND users.height > 160", "exec_time" => "154:39:26.431466", "prop_exec_time" => "72.2%", "ncalls" => "34,211,877", "sync_io_time" => "00:34:19.784318" }
45
+ { "query" => "SELECT * FROM users WHERE users.age > 20 AND users.height > 160", "exec_time" => "154:39:26.431466", "prop_exec_time" => "72.2%", "ncalls" => "34,211,877", "sync_io_time" => "00:34:19.784318" },
46
46
  ]
47
47
  }
48
48
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras::DiagnosePrint do
6
6
  subject(:print_result) do
@@ -12,18 +12,18 @@ describe RubyPgExtras::DiagnosePrint do
12
12
  {
13
13
  :check_name => :table_cache_hit,
14
14
  :ok => false,
15
- :message => "Table hit ratio too low: 0.906977."
15
+ :message => "Table hit ratio too low: 0.906977.",
16
16
  },
17
17
  {
18
18
  :check_name => :index_cache_hit,
19
19
  :ok => false,
20
- :message => "Index hit ratio is too low: 0.818182."
20
+ :message => "Index hit ratio is too low: 0.818182.",
21
21
  },
22
22
  {
23
23
  :check_name => :ssl_used,
24
24
  :ok => true,
25
- :message => "Database client is using a secure SSL connection."
26
- }
25
+ :message => "Database client is using a secure SSL connection.",
26
+ },
27
27
  ]
28
28
  end
29
29
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras::IndexInfo do
6
6
  subject(:result) do
@@ -13,27 +13,27 @@ describe RubyPgExtras::IndexInfo do
13
13
  expect(RubyPgExtras).to receive(:indexes) {
14
14
  [
15
15
  { "schemaname" => "public", "indexname" => "index_users_on_api_auth_token", "tablename" => "users", "columns" => "api_auth_token, column2" },
16
- {"schemaname" => "public", "indexname" => "index_teams_on_slack_id", "tablename" => "teams", "columns" => "slack_id" },
16
+ { "schemaname" => "public", "indexname" => "index_teams_on_slack_id", "tablename" => "teams", "columns" => "slack_id" },
17
17
  ]
18
18
  }
19
19
 
20
20
  expect(RubyPgExtras).to receive(:index_size) {
21
21
  [
22
22
  { "name" => "index_users_on_api_auth_token", "size" => "1744 kB" },
23
- {"name" => "index_teams_on_slack_id", "size" => "500 kB"},
23
+ { "name" => "index_teams_on_slack_id", "size" => "500 kB" },
24
24
  ]
25
25
  }
26
26
 
27
27
  expect(RubyPgExtras).to receive(:null_indexes) {
28
28
  [
29
- { "oid" => 16803, "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "unique"=>true, "indexed_column" => "api_auth_token", "null_frac" => "25.00%", "expected_saving" => "300 kB" }
29
+ { "oid" => 16803, "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "unique" => true, "indexed_column" => "api_auth_token", "null_frac" => "25.00%", "expected_saving" => "300 kB" },
30
30
  ]
31
31
  }
32
32
 
33
33
  expect(RubyPgExtras).to receive(:index_scans) {
34
34
  [
35
- { "schemaname" => "public", "table" => "users", "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "index_scans"=> 0 },
36
- { "schemaname" => "public", "table" => "teams", "index" => "index_teams_on_slack_id", "index_size" => "500 kB", "index_scans"=> 0 }
35
+ { "schemaname" => "public", "table" => "users", "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "index_scans" => 0 },
36
+ { "schemaname" => "public", "table" => "teams", "index" => "index_teams_on_slack_id", "index_size" => "500 kB", "index_scans" => 0 },
37
37
  ]
38
38
  }
39
39
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras::SizeParser do
6
6
  subject(:result) { described_class.to_i(arg) }
7
7
 
8
- describe 'SI Units' do
8
+ describe "SI Units" do
9
9
  let(:arg) { "#{num_units} #{unit}" }
10
10
 
11
11
  context "when the argument is a number followed by 'bytes', with possible case variations" do
@@ -72,7 +72,7 @@ describe RubyPgExtras::SizeParser do
72
72
  end
73
73
  end
74
74
 
75
- describe 'Binary Units' do
75
+ describe "Binary Units" do
76
76
  let(:arg) { "#{num_units} #{unit}" }
77
77
 
78
78
  context "when the argument is a number followed by 'bytes', with possible case variations" do
@@ -139,28 +139,28 @@ describe RubyPgExtras::SizeParser do
139
139
  end
140
140
  end
141
141
 
142
- context 'when the argument has only digits' do
143
- let(:arg) { '654245' }
142
+ context "when the argument has only digits" do
143
+ let(:arg) { "654245" }
144
144
 
145
145
  it { is_expected.to eq(arg.to_i) }
146
146
  end
147
147
 
148
- describe 'errors' do
149
- it 'raises an error when the argument has an invalid prefix' do
148
+ describe "errors" do
149
+ it "raises an error when the argument has an invalid prefix" do
150
150
  expect do
151
- described_class.to_i('123 qb')
151
+ described_class.to_i("123 qb")
152
152
  end.to raise_error ArgumentError
153
153
  end
154
154
 
155
- it 'raises an error when the argument does not have a unit in bytes' do
155
+ it "raises an error when the argument does not have a unit in bytes" do
156
156
  expect do
157
- described_class.to_i('123 mL')
157
+ described_class.to_i("123 mL")
158
158
  end.to raise_error ArgumentError
159
159
  end
160
160
 
161
- it 'when the argument cannot be parsed an number of units' do
161
+ it "when the argument cannot be parsed an number of units" do
162
162
  expect do
163
- described_class.to_i('1c3 MB')
163
+ described_class.to_i("1c3 MB")
164
164
  end.to raise_error ArgumentError
165
165
  end
166
166
  end
data/spec/smoke_spec.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras do
6
6
  RubyPgExtras::QUERIES.each do |query_name|
7
7
  it "#{query_name} description can be read" do
8
8
  expect do
9
9
  RubyPgExtras.description_for(
10
- query_name: query_name
10
+ query_name: query_name,
11
11
  )
12
12
  end.not_to raise_error
13
13
  end
@@ -18,7 +18,7 @@ describe RubyPgExtras do
18
18
  expect do
19
19
  RubyPgExtras.run_query(
20
20
  query_name: query_name,
21
- in_format: :hash
21
+ in_format: :hash,
22
22
  )
23
23
  end.not_to raise_error
24
24
  end
data/spec/spec_helper.rb CHANGED
@@ -1,22 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
- require 'bundler/setup'
5
- require_relative '../lib/ruby-pg-extras'
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+ require_relative "../lib/ruby-pg-extras"
6
6
 
7
7
  pg_version = ENV["PG_VERSION"]
8
8
 
9
- port = if pg_version == "11"
10
- "5432"
11
- elsif pg_version == "12"
12
- "5433"
13
- elsif pg_version == "13"
14
- "5434"
15
- elsif pg_version == "14"
16
- "5435"
17
- else
18
- "5432"
19
- end
9
+ port = if pg_version == "12"
10
+ "5432"
11
+ elsif pg_version == "13"
12
+ "5433"
13
+ elsif pg_version == "14"
14
+ "5434"
15
+ elsif pg_version == "15"
16
+ "5435"
17
+ elsif pg_version == "16"
18
+ "5436"
19
+ elsif pg_version == "17"
20
+ "5437"
21
+ else
22
+ "5432"
23
+ end
20
24
 
21
25
  ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-extras-test"
22
26
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe RubyPgExtras::TableInfo do
6
6
  subject(:result) do
@@ -13,14 +13,14 @@ describe RubyPgExtras::TableInfo do
13
13
  expect(RubyPgExtras).to receive(:tables) {
14
14
  [
15
15
  { "schemaname" => "public", "tablename" => "users" },
16
- { "schemaname" => "public", "tablename" => "teams" }
16
+ { "schemaname" => "public", "tablename" => "teams" },
17
17
  ]
18
18
  }
19
19
 
20
20
  expect(RubyPgExtras).to receive(:table_size) {
21
21
  [
22
22
  { "name" => "teams", "size" => "25 MB" },
23
- {"name" => "users", "size" => "250 MB"},
23
+ { "name" => "users", "size" => "250 MB" },
24
24
  ]
25
25
  }
26
26
 
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.3.1
4
+ version: 5.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-14 00:00:00.000000000 Z
11
+ date: 2024-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rufo
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: " Ruby port of Heroku PG Extras. The goal of this project is to provide
70
84
  a powerful insights into PostgreSQL database for Ruby on Rails apps that are not
71
85
  using the default Heroku PostgreSQL plugin. "
@@ -95,6 +109,7 @@ files:
95
109
  - lib/ruby_pg_extras/queries/buffercache_usage.sql
96
110
  - lib/ruby_pg_extras/queries/cache_hit.sql
97
111
  - lib/ruby_pg_extras/queries/calls.sql
112
+ - lib/ruby_pg_extras/queries/calls_17.sql
98
113
  - lib/ruby_pg_extras/queries/calls_legacy.sql
99
114
  - lib/ruby_pg_extras/queries/connections.sql
100
115
  - lib/ruby_pg_extras/queries/db_settings.sql
@@ -112,6 +127,7 @@ files:
112
127
  - lib/ruby_pg_extras/queries/mandelbrot.sql
113
128
  - lib/ruby_pg_extras/queries/null_indexes.sql
114
129
  - lib/ruby_pg_extras/queries/outliers.sql
130
+ - lib/ruby_pg_extras/queries/outliers_17.sql
115
131
  - lib/ruby_pg_extras/queries/outliers_legacy.sql
116
132
  - lib/ruby_pg_extras/queries/pg_stat_statements_reset.sql
117
133
  - lib/ruby_pg_extras/queries/records_rank.sql
@@ -159,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
175
  - !ruby/object:Gem::Version
160
176
  version: '0'
161
177
  requirements: []
162
- rubygems_version: 3.3.7
178
+ rubygems_version: 3.5.4
163
179
  signing_key:
164
180
  specification_version: 4
165
181
  summary: Ruby PostgreSQL performance database insights