ruby-pg-extras 2.3.0 → 3.0.6

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: a93ebb6cb69e2591e7e9c327b326edf9353105b985f0023ec00deceec631e398
4
- data.tar.gz: 0e6b50933c072c9c04fba24875d71c0c561ecf4b5a0cb60f8cb66df9cb000075
3
+ metadata.gz: ed716b44ced4653bf0c794ea1690b99cecf460f30dc767a56f328748790d4c0f
4
+ data.tar.gz: 3652a5add3cfd162959578af4d840ee494f99311d4b2e48ffbd2f1ca5c078b1e
5
5
  SHA512:
6
- metadata.gz: b855303347b32b4e20e9a9061f058843f8a337968344d3517a14a70000849691f378e077163720f487c2798df441c1a59f7f53e80b6d45ef2fe7796854cf79f6
7
- data.tar.gz: 4429a4634e5b154dca182bdb232c64009178f287a00b1c58594dd089221ab2cc1520522ba2112153dd645905685d7751b7c51f9d9a87968d0ab416af93797d26
6
+ metadata.gz: 3078b1e69e4a36686cc76a2c5326a35b8a61b4751cfe1031df74cda6306ae62fcd07026be2218ca40ac83dd535d0748e608bf00e5e3571aae9de0f1d794d43ff
7
+ data.tar.gz: 116e9de1f4a0dc927eef92e6bc88f354c54a5929831d68d7a19c58efbd8085329b0abff6cde1d482757c41d27225191e50bf2852acd9d57637d2306f61568fa7
data/.circleci/config.yml CHANGED
@@ -31,7 +31,8 @@ jobs:
31
31
  - checkout
32
32
  - run: gem update --system
33
33
  - run: gem install bundler
34
- - run: bundle install --path vendor/bundle
34
+ - run: bundle config set --local path 'vendor/bundle'
35
+ - run: bundle install
35
36
  - run: sudo apt-get update --allow-releaseinfo-change
36
37
  - run: sudo apt install postgresql-client-11
37
38
  - run: dockerize -wait tcp://postgres11:5432 -timeout 1m
data/README.md CHANGED
@@ -26,7 +26,7 @@ In your Gemfile
26
26
  gem "ruby-pg-extras"
27
27
  ```
28
28
 
29
- Some of the queries (e.g., `calls` and `outliers`) require [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) extension enabled.
29
+ `calls` and `outliers` queries require [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) extension.
30
30
 
31
31
  You can check if it is enabled in your database by running:
32
32
 
@@ -39,6 +39,12 @@ You should see the similar line in the output:
39
39
  | pg_stat_statements | 1.7 | 1.7 | track execution statistics of all SQL statements executed |
40
40
  ```
41
41
 
42
+ `ssl_used` requires `sslinfo` extension, and `buffercache_usage`/`buffercache_usage` queries need `pg_buffercache`. You can enable them all by running:
43
+
44
+ ```ruby
45
+ RubyPGExtras.add_extensions
46
+ ```
47
+
42
48
  ## Usage
43
49
 
44
50
  Gem expects the `ENV['DATABASE_URL']` value in the following format:
@@ -92,6 +98,18 @@ RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
92
98
 
93
99
  ```
94
100
 
101
+ ## Diagnose report
102
+
103
+ 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:
104
+
105
+ ```ruby
106
+ RubyPGExtras.diagnose
107
+ ```
108
+
109
+ ![Diagnose report](https://github.com/pawurb/ruby-pg-extras/raw/master/ruby-pg-extras-diagnose.png)
110
+
111
+ Keep reading to learn about methods that `diagnose` uses under the hood.
112
+
95
113
  ## Available methods
96
114
 
97
115
  ### `cache_hit`
@@ -236,7 +254,7 @@ This command displays all the current locks, regardless of their type.
236
254
 
237
255
  RubyPGExtras.outliers(args: { limit: 20 })
238
256
 
239
- qry | exec_time | prop_exec_time | ncalls | sync_io_time
257
+ query | exec_time | prop_exec_time | ncalls | sync_io_time
240
258
  -----------------------------------------+------------------+----------------+-------------+--------------
241
259
  SELECT * FROM archivable_usage_events.. | 154:39:26.431466 | 72.2% | 34,211,877 | 00:00:00
242
260
  COPY public.archivable_usage_events (.. | 50:38:33.198418 | 23.6% | 13 | 13:34:21.00108
@@ -387,7 +405,7 @@ This command displays the total size of each table and materialized view in the
387
405
 
388
406
  ```ruby
389
407
 
390
- RubyPGExtras.unused_indexes(args: { min_scans: 20 })
408
+ RubyPGExtras.unused_indexes(args: { max_scans: 20 })
391
409
 
392
410
  table | index | index_size | index_scans
393
411
  ---------------------+--------------------------------------------+------------+-------------
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'filesize'
4
+
5
+ module RubyPGExtras
6
+ class DiagnoseData
7
+ PG_EXTRAS_TABLE_CACHE_HIT_MIN_EXPECTED = "0.985"
8
+ PG_EXTRAS_INDEX_CACHE_HIT_MIN_EXPECTED = "0.985"
9
+ PG_EXTRAS_UNUSED_INDEXES_MAX_SCANS = 20
10
+ PG_EXTRAS_UNUSED_INDEXES_MIN_SIZE_BYTES = Filesize.from("1 MB").to_i # 1000000 bytes
11
+ PG_EXTRAS_NULL_INDEXES_MIN_SIZE_MB = 1 # 1 MB
12
+ PG_EXTRAS_NULL_MIN_NULL_FRAC_PERCENT = 50 # 50%
13
+ PG_EXTRAS_BLOAT_MIN_VALUE = 10
14
+ PG_EXTRAS_OUTLIERS_MIN_EXEC_RATIO = 33 # 33%
15
+
16
+ def self.call
17
+ new.call
18
+ end
19
+
20
+ def call
21
+ {
22
+ table_cache_hit: table_cache_hit,
23
+ index_cache_hit: index_cache_hit,
24
+ unused_indexes: unused_indexes,
25
+ null_indexes: null_indexes,
26
+ bloat: bloat,
27
+ duplicate_indexes: duplicate_indexes
28
+ }.yield_self do |checks|
29
+ extensions_data = query_module.extensions(in_format: :hash)
30
+ pg_stats_enabled = extensions_data.find do |el|
31
+ el.fetch("name") == "pg_stat_statements"
32
+ end.fetch("installed_version", false)
33
+
34
+ ssl_info_enabled = extensions_data.find do |el|
35
+ el.fetch("name") == "sslinfo"
36
+ end.fetch("installed_version", false)
37
+
38
+ if pg_stats_enabled
39
+ checks.merge!({
40
+ outliers: outliers
41
+ })
42
+ end
43
+
44
+ if ssl_info_enabled
45
+ checks.merge!({
46
+ ssl_used: ssl_used
47
+ })
48
+ end
49
+
50
+ checks
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def query_module
57
+ RubyPGExtras
58
+ end
59
+
60
+ def table_cache_hit
61
+ min_expected = ENV.fetch(
62
+ "PG_EXTRAS_TABLE_CACHE_HIT_MIN_EXPECTED",
63
+ PG_EXTRAS_TABLE_CACHE_HIT_MIN_EXPECTED
64
+ ).to_f
65
+
66
+ table_cache_hit_ratio = query_module.cache_hit(in_format: :hash)[1].fetch("ratio").to_f.round(6)
67
+
68
+ if table_cache_hit_ratio > min_expected
69
+ {
70
+ ok: true,
71
+ message: "Table cache hit ratio is correct: #{table_cache_hit_ratio}."
72
+ }
73
+ else
74
+ {
75
+ ok: false,
76
+ message: "Table hit ratio is too low: #{table_cache_hit_ratio}."
77
+ }
78
+ end
79
+ end
80
+
81
+ def index_cache_hit
82
+ min_expected = ENV.fetch(
83
+ "PG_EXTRAS_INDEX_CACHE_HIT_MIN_EXPECTED",
84
+ PG_EXTRAS_INDEX_CACHE_HIT_MIN_EXPECTED
85
+ ).to_f
86
+
87
+ index_cache_hit_ratio = query_module.cache_hit(in_format: :hash)[0].fetch("ratio").to_f.round(6)
88
+
89
+ if index_cache_hit_ratio > min_expected
90
+ {
91
+ ok: true,
92
+ message: "Index hit ratio is correct: #{index_cache_hit_ratio}."
93
+ }
94
+ else
95
+ {
96
+ ok: false,
97
+ message: "Index hit ratio is too low: #{index_cache_hit_ratio}."
98
+ }
99
+ end
100
+ end
101
+
102
+ def ssl_used
103
+ ssl_connection = query_module.ssl_used(in_format: :hash)[0].fetch("ssl_is_used")
104
+
105
+ if ssl_connection
106
+ {
107
+ ok: true,
108
+ message: "Database client is using a secure SSL connection."
109
+ }
110
+ else
111
+ {
112
+ ok: false,
113
+ message: "Database client is using an unencrypted connection."
114
+ }
115
+ end
116
+ end
117
+
118
+ def unused_indexes
119
+ indexes = query_module.unused_indexes(
120
+ in_format: :hash,
121
+ args: { min_scans: PG_EXTRAS_UNUSED_INDEXES_MAX_SCANS }
122
+ ).select do |i|
123
+ Filesize.from(i.fetch("index_size")).to_i >= PG_EXTRAS_UNUSED_INDEXES_MIN_SIZE_BYTES
124
+ end
125
+
126
+ if indexes.count == 0
127
+ {
128
+ ok: true,
129
+ message: "No unused indexes detected."
130
+ }
131
+ else
132
+ print_indexes = indexes.map do |i|
133
+ "'#{i.fetch('index')}' on '#{i.fetch('table')}' size #{i.fetch('index_size')}"
134
+ end.join(",\n")
135
+ {
136
+ ok: false,
137
+ message: "Unused indexes detected:\n#{print_indexes}"
138
+ }
139
+ end
140
+ end
141
+
142
+ def null_indexes
143
+ indexes = query_module.null_indexes(
144
+ in_format: :hash,
145
+ args: { min_relation_size_mb: PG_EXTRAS_NULL_INDEXES_MIN_SIZE_MB }
146
+ ).select do |i|
147
+ i.fetch("null_frac").gsub("%", "").to_f >= PG_EXTRAS_NULL_MIN_NULL_FRAC_PERCENT
148
+ end
149
+
150
+ if indexes.count == 0
151
+ {
152
+ ok: true,
153
+ message: "No null indexes detected."
154
+ }
155
+ else
156
+ print_indexes = indexes.map do |i|
157
+ "'#{i.fetch('index')}' size #{i.fetch('index_size')} null values fraction #{i.fetch('null_frac')}"
158
+ end.join(",\n")
159
+ {
160
+ ok: false,
161
+ message: "Null indexes detected:\n#{print_indexes}"
162
+ }
163
+ end
164
+ end
165
+
166
+ def bloat
167
+ bloat_data = query_module.bloat(in_format: :hash).select do |b|
168
+ b.fetch("bloat").to_f >= PG_EXTRAS_BLOAT_MIN_VALUE
169
+ end
170
+
171
+ if bloat_data.count == 0
172
+ {
173
+ ok: true,
174
+ message: "No bloat detected."
175
+ }
176
+ else
177
+ print_bloat = bloat_data.map do |b|
178
+ "'#{b.fetch('object_name')}' bloat #{b.fetch('bloat')} waste #{b.fetch('waste')}"
179
+ end.join(",\n")
180
+
181
+ {
182
+ ok: false,
183
+ message: "Bloat detected:\n#{print_bloat}"
184
+ }
185
+ end
186
+ end
187
+
188
+ def duplicate_indexes
189
+ indexes = query_module.duplicate_indexes(in_format: :hash)
190
+
191
+ if indexes.count == 0
192
+ {
193
+ ok: true,
194
+ message: "No duplicate indexes detected."
195
+ }
196
+ else
197
+ print_indexes = indexes.map do |i|
198
+ "'#{i.fetch('idx1')}' of size #{i.fetch('size')} is identical to '#{i.fetch('idx2')}'"
199
+ end.join(",\n")
200
+
201
+ {
202
+ ok: false,
203
+ message: "Duplicate indexes detected:\n#{print_indexes}"
204
+ }
205
+ end
206
+ end
207
+
208
+ def outliers
209
+ queries = query_module.outliers(in_format: :hash).select do |q|
210
+ q.fetch("prop_exec_time").gsub("%", "").to_f >= PG_EXTRAS_OUTLIERS_MIN_EXEC_RATIO
211
+ end
212
+
213
+ if queries.count == 0
214
+ {
215
+ ok: true,
216
+ message: "No queries using significant execution ratio detected."
217
+ }
218
+ else
219
+ print_queries = queries.map do |q|
220
+ "'#{q.fetch('query').slice(0, 30)}...' called #{q.fetch('ncalls')} times, using #{q.fetch('prop_exec_time')} of total exec time."
221
+ end.join(",\n")
222
+
223
+ {
224
+ ok: false,
225
+ message: "Queries using significant execution ratio detected:\n#{print_queries}"
226
+ }
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'terminal-table'
4
+
5
+ module RubyPGExtras
6
+ class DiagnosePrint
7
+ def self.call(data)
8
+ new.call(data)
9
+ end
10
+
11
+ def call(data)
12
+ rows = data.sort do |key|
13
+ key[1].fetch(:ok) ? 1 : -1
14
+ end.map do |el|
15
+ key = el[0]
16
+ val = el[1]
17
+ symbol = val.fetch(:ok) ? "√" : "x"
18
+ color = val.fetch(:ok) ? :green : :red
19
+
20
+ [
21
+ colorize("[#{symbol}] - #{key}", color),
22
+ colorize(val.fetch(:message), color)
23
+ ]
24
+ end
25
+
26
+ puts Terminal::Table.new(
27
+ title: title,
28
+ rows: rows
29
+ )
30
+ end
31
+
32
+ private
33
+
34
+ def title
35
+ "ruby-pg-extras - diagnose report"
36
+ end
37
+
38
+ def colorize(string, color)
39
+ if color == :red
40
+ "\e[0;31;49m#{string}\e[0m"
41
+ elsif color == :green
42
+ "\e[0;32;49m#{string}\e[0m"
43
+ else
44
+ raise "Unsupported color: #{color}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ /* Configure extensions necessary for other queries to work */
2
+
3
+ CREATE EXTENSION IF NOT EXISTS sslinfo;
4
+ CREATE EXTENSION IF NOT EXISTS pg_buffercache;
5
+ CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
@@ -1,4 +1,3 @@
1
1
  /* Check if SSL connection is used */
2
2
 
3
- CREATE EXTENSION IF NOT EXISTS sslinfo;
4
3
  SELECT ssl_is_used();
@@ -11,6 +11,6 @@ SELECT
11
11
  idx_scan as index_scans
12
12
  FROM pg_stat_user_indexes ui
13
13
  JOIN pg_index i ON ui.indexrelid = i.indexrelid
14
- WHERE NOT indisunique AND idx_scan < %{min_scans} AND pg_relation_size(relid) > 5 * 8192
14
+ WHERE NOT indisunique AND idx_scan < %{max_scans} AND pg_relation_size(relid) > 5 * 8192
15
15
  ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
16
16
  pg_relation_size(i.indexrelid) DESC;
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyPGExtras
4
- VERSION = "2.3.0"
4
+ VERSION = "3.0.6"
5
5
  end
@@ -3,13 +3,15 @@
3
3
  require 'terminal-table'
4
4
  require 'uri'
5
5
  require 'pg'
6
+ require 'ruby-pg-extras/diagnose_data'
7
+ require 'ruby-pg-extras/diagnose_print'
6
8
 
7
9
  module RubyPGExtras
8
10
  @@database_url = nil
9
11
  NEW_PG_STAT_STATEMENTS = "1.8"
10
12
 
11
13
  QUERIES = %i(
12
- bloat blocking cache_hit db_settings
14
+ add_extensions bloat blocking cache_hit db_settings
13
15
  calls extensions table_cache_hit index_cache_hit
14
16
  index_size index_usage null_indexes locks all_locks
15
17
  long_running_queries mandelbrot outliers
@@ -28,7 +30,7 @@ module RubyPGExtras
28
30
  outliers_legacy: { limit: 10 },
29
31
  buffercache_stats: { limit: 10 },
30
32
  buffercache_usage: { limit: 20 },
31
- unused_indexes: { min_scans: 50 },
33
+ unused_indexes: { max_scans: 50 },
32
34
  null_indexes: { min_relation_size_mb: 10 }
33
35
  })
34
36
 
@@ -67,6 +69,18 @@ module RubyPGExtras
67
69
  )
68
70
  end
69
71
 
72
+ def self.diagnose(in_format: :display_table)
73
+ data = RubyPGExtras::DiagnoseData.call
74
+
75
+ if in_format == :display_table
76
+ RubyPGExtras::DiagnosePrint.call(data)
77
+ elsif in_format == :hash
78
+ data
79
+ else
80
+ raise "Invalid 'in_format' argument!"
81
+ end
82
+ end
83
+
70
84
  def self.display_result(result, title:, in_format:)
71
85
  case in_format
72
86
  when :array
Binary file
@@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.license = "MIT"
18
18
  gem.add_dependency "pg"
19
+ gem.add_dependency "filesize"
19
20
  gem.add_dependency "terminal-table"
20
21
  gem.add_development_dependency "rake"
21
22
  gem.add_development_dependency "rspec"
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe RubyPGExtras::DiagnoseData do
6
+ subject(:result) do
7
+ RubyPGExtras::DiagnoseData.call
8
+ end
9
+
10
+ describe "call" do
11
+ context "stubbed cases" do
12
+ before do
13
+ expect(RubyPGExtras).to receive(:unused_indexes) {
14
+ [
15
+ { "table" => "public.plans", "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "index_scans" => 0 },
16
+ { "table" => "public.feedbacks", "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "index_scans" => 1 },
17
+ { "table" => "public.channels", "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "index_scans" => 7}
18
+ ]
19
+ }
20
+
21
+ expect(RubyPGExtras).to receive(:null_indexes) {
22
+ [
23
+ { "oid" => 123, "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "unique" => "t", "null_frac" => "00.00%", "expected_saving" => "0 kb" },
24
+ { "oid" => 321, "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "unique" => "f", "null_frac" => "97.00%", "expected_saving" => "77 kb" },
25
+ { "oid" => 231, "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "unique" => "t", "null_frac" => "49.99%", "expected_saving" => "28 MB" }
26
+ ]
27
+ }
28
+
29
+ expect(RubyPGExtras).to receive(:bloat) {
30
+ [
31
+ { "type" => "table", "schemaname" => "public", "object_name" => "bloated_table_1", "bloat" => 8, "waste" => "0 kb" },
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" }
34
+ ]
35
+ }
36
+
37
+ expect(RubyPGExtras).to receive(:duplicate_indexes) {
38
+ [
39
+ { "size" => "128 kb", "idx1" => "users_pkey", "idx2" => "index_users_id" }
40
+ ]
41
+ }
42
+
43
+ expect(RubyPGExtras).to receive(:outliers) {
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" }
46
+ ]
47
+ }
48
+ end
49
+
50
+ it "works" do
51
+ expect {
52
+ RubyPGExtras::DiagnosePrint.call(result)
53
+ }.not_to raise_error
54
+ end
55
+ end
56
+
57
+ context "real database data" do
58
+ before do
59
+ expect(RubyPGExtras).to receive(:unused_indexes) {
60
+ [
61
+ { "table" => "public.plans", "index" => "index_plans_on_payer_id", "index_size" => "2 MB", "index_scans" => 0 },
62
+ { "table" => "public.feedbacks", "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "index_scans" => 1 },
63
+ { "table" => "public.channels", "index" => "index_channels_on_slack_id", "index_size" => "1.1 MB", "index_scans" => 7}
64
+ ]
65
+ }
66
+
67
+ end
68
+
69
+ it "works" do
70
+ expect {
71
+ RubyPGExtras::DiagnosePrint.call(result)
72
+ }.not_to raise_error
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe RubyPGExtras::DiagnosePrint do
6
+ subject(:print_result) do
7
+ RubyPGExtras::DiagnosePrint.call(data)
8
+ end
9
+
10
+ let(:data) do
11
+ {
12
+ :table_cache_hit => {
13
+ :ok => false,
14
+ :message => "Table hit ratio too low: 0.906977."
15
+ },
16
+ :index_cache_hit => {
17
+ :ok => false,
18
+ :message => "Index hit ratio is too low: 0.818182."
19
+ },
20
+ :ssl_used => {
21
+ :ok => true,
22
+ :message => "Database client is using a secure SSL connection."
23
+ }
24
+ }
25
+ end
26
+
27
+ describe "call" do
28
+ it "works" do
29
+ expect {
30
+ print_result
31
+ }.not_to raise_error
32
+ end
33
+ end
34
+ end
data/spec/smoke_spec.rb CHANGED
@@ -3,11 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe RubyPGExtras do
6
- before(:all) do
7
- RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
8
- RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
9
- end
10
-
11
6
  RubyPGExtras::QUERIES.each do |query_name|
12
7
  it "#{query_name} description can be read" do
13
8
  expect do
data/spec/spec_helper.rb CHANGED
@@ -17,3 +17,11 @@ else
17
17
  end
18
18
 
19
19
  ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-extras-test"
20
+
21
+ RSpec.configure do |config|
22
+ config.before(:suite) do
23
+ RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
24
+ RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
25
+ RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS sslinfo;")
26
+ end
27
+ end
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: 2.3.0
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-27 00:00:00.000000000 Z
11
+ date: 2021-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: filesize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: terminal-table
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -83,6 +97,9 @@ files:
83
97
  - Rakefile
84
98
  - docker-compose.yml.sample
85
99
  - lib/ruby-pg-extras.rb
100
+ - lib/ruby-pg-extras/diagnose_data.rb
101
+ - lib/ruby-pg-extras/diagnose_print.rb
102
+ - lib/ruby-pg-extras/queries/add_extensions.sql
86
103
  - lib/ruby-pg-extras/queries/all_locks.sql
87
104
  - lib/ruby-pg-extras/queries/bloat.sql
88
105
  - lib/ruby-pg-extras/queries/blocking.sql
@@ -116,7 +133,10 @@ files:
116
133
  - lib/ruby-pg-extras/queries/unused_indexes.sql
117
134
  - lib/ruby-pg-extras/queries/vacuum_stats.sql
118
135
  - lib/ruby-pg-extras/version.rb
136
+ - ruby-pg-extras-diagnose.png
119
137
  - ruby-pg-extras.gemspec
138
+ - spec/diagnose_data_spec.rb
139
+ - spec/diagnose_print_spec.rb
120
140
  - spec/smoke_spec.rb
121
141
  - spec/spec_helper.rb
122
142
  homepage: http://github.com/pawurb/ruby-pg-extras
@@ -143,5 +163,7 @@ signing_key:
143
163
  specification_version: 4
144
164
  summary: Ruby PostgreSQL performance database insights
145
165
  test_files:
166
+ - spec/diagnose_data_spec.rb
167
+ - spec/diagnose_print_spec.rb
146
168
  - spec/smoke_spec.rb
147
169
  - spec/spec_helper.rb