ruby-pg-extras 5.3.0 → 5.4.0

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: 4db68e685bfd403720469ba3b28c3f0c8eeac489dd8c2ec030a7cc2b12a45f8c
4
- data.tar.gz: 39097e6d101eff027ce4ac09b4c04a89eca69c697c3b9bd270123a2052cf3b26
3
+ metadata.gz: 7ddb04fe6f72f45595c16a533c58ef34fc59dc551ab78e131f0cec1ca4a56d3b
4
+ data.tar.gz: d8763349854102e5bfd2174461f7d3c43de7c74526dba14d1982c68705f59055
5
5
  SHA512:
6
- metadata.gz: b8fb4fe982ee57b2641625a598488c870b5c45d3ac06a380c98139c8c20cfc27e5d139ce029902fe7ee509fbcbcfb3764c4b12823252ec3e47dbad31a07cb2bb
7
- data.tar.gz: a4751fe92639df23050110e6359b8dc1a6d3ec9746893d0c0a248fc007723a24eea146ee82d013347e7a69c5d76ad79f0fe834548eff9c18a9d2dbfed3d95dce
6
+ metadata.gz: 2b33851aaed74e98903aee07d92bf4a048300f7e99bec1e7cb541c14a7669cbdf2bd8c5d784d922f276c3c287d6cf7bb65df16a7788e2b58fdcd20ca1c3a4ec4
7
+ data.tar.gz: '085b52d651b6dbf60a5a44129416fccc8801e7be6c321fb0ac9083667902bdd7025a52a2e7dc20e6756f3062492820342f1aabbcf1bfe8be9b5c43bf0362d6a2'
@@ -57,8 +57,7 @@ jobs:
57
57
  ruby-version: ${{ matrix.ruby-version }}
58
58
  - name: Setup dependencies
59
59
  run: |
60
- gem update --system
61
- gem install bundler
60
+ gem install bundler -v 2.4.22
62
61
  sudo apt-get update --allow-releaseinfo-change
63
62
  sudo apt install postgresql-client
64
63
  sudo apt install libpq-dev
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
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/")
9
9
  end
@@ -1,15 +1,15 @@
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
@@ -27,6 +27,8 @@ module RubyPgExtras
27
27
  buffercache_usage ssl_used connections
28
28
  )
29
29
 
30
+ DEFAULT_SCHEMA = ENV["PG_EXTRAS_SCHEMA"] || "public"
31
+
30
32
  DEFAULT_ARGS = Hash.new({}).merge({
31
33
  calls: { limit: 10 },
32
34
  calls_legacy: { limit: 10 },
@@ -37,18 +39,18 @@ module RubyPgExtras
37
39
  outliers_legacy: { limit: 10 },
38
40
  buffercache_stats: { limit: 10 },
39
41
  buffercache_usage: { limit: 20 },
40
- unused_indexes: { max_scans: 50, schema: "public" },
42
+ unused_indexes: { max_scans: 50, schema: DEFAULT_SCHEMA },
41
43
  null_indexes: { min_relation_size_mb: 10 },
42
- index_usage: { schema: "public" },
43
- index_cache_hit: { schema: "public" },
44
- table_cache_hit: { schema: "public" },
45
- index_scans: { schema: "public" },
46
- cache_hit: { schema: "public" },
47
- seq_scans: { schema: "public" },
48
- table_index_scans: { schema: "public" },
49
- records_rank: { schema: "public" },
50
- tables: { schema: "public" },
51
- kill_pid: { pid: 0 }
44
+ index_usage: { schema: DEFAULT_SCHEMA },
45
+ index_cache_hit: { schema: DEFAULT_SCHEMA },
46
+ table_cache_hit: { schema: DEFAULT_SCHEMA },
47
+ index_scans: { schema: DEFAULT_SCHEMA },
48
+ cache_hit: { schema: DEFAULT_SCHEMA },
49
+ seq_scans: { schema: DEFAULT_SCHEMA },
50
+ table_index_scans: { schema: DEFAULT_SCHEMA },
51
+ records_rank: { schema: DEFAULT_SCHEMA },
52
+ tables: { schema: DEFAULT_SCHEMA },
53
+ kill_pid: { pid: 0 },
52
54
  })
53
55
 
54
56
  QUERIES.each do |query_name|
@@ -56,7 +58,7 @@ module RubyPgExtras
56
58
  run_query(
57
59
  query_name: query_name,
58
60
  in_format: options.fetch(:in_format, :display_table),
59
- args: options.fetch(:args, {})
61
+ args: options.fetch(:args, {}),
60
62
  )
61
63
  end
62
64
  end
@@ -73,16 +75,16 @@ module RubyPgExtras
73
75
  end
74
76
 
75
77
  sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
76
- sql_for(query_name: query_name) % custom_args
77
- else
78
- sql_for(query_name: query_name)
79
- end
78
+ sql_for(query_name: query_name) % custom_args
79
+ else
80
+ sql_for(query_name: query_name)
81
+ end
80
82
  result = connection.exec(sql)
81
83
 
82
84
  display_result(
83
85
  result,
84
86
  title: description_for(query_name: query_name),
85
- in_format: in_format
87
+ in_format: in_format,
86
88
  )
87
89
  end
88
90
 
@@ -138,15 +140,15 @@ module RubyPgExtras
138
140
  result
139
141
  when :display_table
140
142
  headings = if result.count > 0
141
- result[0].keys
142
- else
143
- ["No results"]
144
- end
143
+ result[0].keys
144
+ else
145
+ ["No results"]
146
+ end
145
147
 
146
148
  puts Terminal::Table.new(
147
149
  title: title,
148
150
  headings: headings,
149
- rows: result.values
151
+ rows: result.values,
150
152
  )
151
153
  else
152
154
  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,
@@ -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,
@@ -6,6 +6,7 @@ SELECT
6
6
  pg_size_pretty(pg_relation_size(c.oid)) AS index_size,
7
7
  i.indisunique AS unique,
8
8
  a.attname AS indexed_column,
9
+ s.tablename AS table,
9
10
  CASE s.null_frac
10
11
  WHEN 0 THEN ''
11
12
  ELSE to_char(s.null_frac * 100, '999.00%%')
@@ -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.0"
4
+ VERSION = "5.4.0"
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,22 @@
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
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
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
20
20
 
21
21
  ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-extras-test"
22
22
 
@@ -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.0
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-25 00:00:00.000000000 Z
11
+ date: 2024-09-19 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. "
@@ -144,7 +158,7 @@ licenses:
144
158
  - MIT
145
159
  metadata:
146
160
  rubygems_mfa_required: 'true'
147
- post_install_message:
161
+ post_install_message:
148
162
  rdoc_options: []
149
163
  require_paths:
150
164
  - lib
@@ -159,8 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
173
  - !ruby/object:Gem::Version
160
174
  version: '0'
161
175
  requirements: []
162
- rubygems_version: 3.1.6
163
- signing_key:
176
+ rubygems_version: 3.5.4
177
+ signing_key:
164
178
  specification_version: 4
165
179
  summary: Ruby PostgreSQL performance database insights
166
180
  test_files: