ruby-pg-extras 3.0.6 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ruby-pg-extras/diagnose_data.rb +12 -14
- data/lib/ruby-pg-extras/diagnose_print.rb +6 -8
- data/lib/ruby-pg-extras/index_info.rb +61 -0
- data/lib/ruby-pg-extras/index_info_print.rb +43 -0
- data/lib/ruby-pg-extras/queries/index_scans.sql +12 -0
- data/lib/ruby-pg-extras/queries/indexes.sql +9 -0
- data/lib/ruby-pg-extras/queries/table_index_scans.sql +7 -0
- data/lib/ruby-pg-extras/queries/tables.sql +3 -0
- data/lib/ruby-pg-extras/table_info.rb +77 -0
- data/lib/ruby-pg-extras/table_info_print.rb +45 -0
- data/lib/ruby-pg-extras/version.rb +1 -1
- data/lib/ruby-pg-extras.rb +37 -3
- data/spec/diagnose_data_spec.rb +3 -14
- data/spec/diagnose_print_spec.rb +9 -6
- data/spec/index_info_spec.rb +56 -0
- data/spec/table_info_spec.rb +78 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfa2e40b65be7fbe29e449251cad9a146a828341bdeeb9d76190f75033e0fb5e
|
4
|
+
data.tar.gz: f2e17ec2660caa6b1641e638d6ac1085c7a9a71187aea8865c69a01cf0c457e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 388a2ca937dcabafb36419e9c851a0eed52945348eb1a9386d3d00fcf39bf7e842cff6f1cd29b8b7a711996d84a85acaa1c0cd2e9ca30c926b1843deb9458d97
|
7
|
+
data.tar.gz: 2f443245c762629fe79b78af4795d31ae277b81cb05acc4c839369ec7e36c7ca04d874ab4488f406c520a9966b25f4f71265eec44cec03b1cb4d8cfcdbee08ba
|
@@ -18,14 +18,14 @@ module RubyPGExtras
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
[
|
22
|
+
:table_cache_hit,
|
23
|
+
:index_cache_hit,
|
24
|
+
:unused_indexes,
|
25
|
+
:null_indexes,
|
26
|
+
:bloat,
|
27
|
+
:duplicate_indexes
|
28
|
+
].yield_self do |checks|
|
29
29
|
extensions_data = query_module.extensions(in_format: :hash)
|
30
30
|
pg_stats_enabled = extensions_data.find do |el|
|
31
31
|
el.fetch("name") == "pg_stat_statements"
|
@@ -36,18 +36,16 @@ module RubyPGExtras
|
|
36
36
|
end.fetch("installed_version", false)
|
37
37
|
|
38
38
|
if pg_stats_enabled
|
39
|
-
checks.
|
40
|
-
outliers: outliers
|
41
|
-
})
|
39
|
+
checks = checks.concat([:outliers])
|
42
40
|
end
|
43
41
|
|
44
42
|
if ssl_info_enabled
|
45
|
-
checks.
|
46
|
-
ssl_used: ssl_used
|
47
|
-
})
|
43
|
+
checks = checks.concat([:ssl_used])
|
48
44
|
end
|
49
45
|
|
50
46
|
checks
|
47
|
+
end.map do |check|
|
48
|
+
send(check).merge(check_name: check)
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
@@ -9,17 +9,15 @@ module RubyPGExtras
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(data)
|
12
|
-
rows = data.sort do |
|
13
|
-
|
12
|
+
rows = data.sort do |el|
|
13
|
+
el.fetch(:ok) ? 1 : -1
|
14
14
|
end.map do |el|
|
15
|
-
|
16
|
-
|
17
|
-
symbol = val.fetch(:ok) ? "√" : "x"
|
18
|
-
color = val.fetch(:ok) ? :green : :red
|
15
|
+
symbol = el.fetch(:ok) ? "√" : "x"
|
16
|
+
color = el.fetch(:ok) ? :green : :red
|
19
17
|
|
20
18
|
[
|
21
|
-
colorize("[#{symbol}] - #{
|
22
|
-
colorize(
|
19
|
+
colorize("[#{symbol}] - #{el.fetch(:check_name)}", color),
|
20
|
+
colorize(el.fetch(:message), color)
|
23
21
|
]
|
24
22
|
end
|
25
23
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RubyPGExtras
|
2
|
+
class IndexInfo
|
3
|
+
def self.call(table_name = nil)
|
4
|
+
new.call(table_name)
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(table_name = nil)
|
8
|
+
indexes_data.select do |index_data|
|
9
|
+
if table_name == nil
|
10
|
+
true
|
11
|
+
else
|
12
|
+
index_data.fetch("tablename") == table_name
|
13
|
+
end
|
14
|
+
end.sort_by do |index_data|
|
15
|
+
index_data.fetch("tablename")
|
16
|
+
end.map do |index_data|
|
17
|
+
index_name = index_data.fetch("indexname")
|
18
|
+
|
19
|
+
{
|
20
|
+
index_name: index_name,
|
21
|
+
table_name: index_data.fetch("tablename"),
|
22
|
+
columns: index_data.fetch("columns").split(',').map(&:strip),
|
23
|
+
index_size: index_size_data.find do |el|
|
24
|
+
el.fetch("name") == index_name
|
25
|
+
end.fetch("size", "N/A"),
|
26
|
+
index_scans: index_scans_data.find do |el|
|
27
|
+
el.fetch("index") == index_name
|
28
|
+
end.fetch("index_scans", "N/A"),
|
29
|
+
null_frac: null_indexes_data.find do |el|
|
30
|
+
el.fetch("index") == index_name
|
31
|
+
end&.fetch("null_frac", "N/A") || "0.00%"
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def index_size_data
|
37
|
+
@_index_size_data ||= query_module.index_size(in_format: :hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def null_indexes_data
|
41
|
+
@_null_indexes_data ||= query_module.null_indexes(
|
42
|
+
in_format: :hash,
|
43
|
+
args: { min_relation_size_mb: 0 }
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def index_scans_data
|
48
|
+
@_index_scans_data ||= query_module.index_scans(in_format: :hash)
|
49
|
+
end
|
50
|
+
|
51
|
+
def indexes_data
|
52
|
+
@_indexes_data ||= query_module.indexes(in_format: :hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def query_module
|
58
|
+
RubyPGExtras
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terminal-table'
|
4
|
+
|
5
|
+
module RubyPGExtras
|
6
|
+
class IndexInfoPrint
|
7
|
+
def self.call(data)
|
8
|
+
new.call(data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(data)
|
12
|
+
rows = data.map do |el|
|
13
|
+
[
|
14
|
+
el.fetch(:index_name),
|
15
|
+
el.fetch(:table_name),
|
16
|
+
el.fetch(:columns).join(', '),
|
17
|
+
el.fetch(:index_size),
|
18
|
+
el.fetch(:index_scans),
|
19
|
+
el.fetch(:null_frac)
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
puts Terminal::Table.new(
|
24
|
+
headings: [
|
25
|
+
"Index name",
|
26
|
+
"Table name",
|
27
|
+
"Columns",
|
28
|
+
"Index size",
|
29
|
+
"Index scans",
|
30
|
+
"Null frac"
|
31
|
+
],
|
32
|
+
title: title,
|
33
|
+
rows: rows
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def title
|
40
|
+
"Index info"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/* Number of scans performed on indexes */
|
2
|
+
|
3
|
+
SELECT
|
4
|
+
schemaname,
|
5
|
+
relname AS table,
|
6
|
+
indexrelname AS index,
|
7
|
+
pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
|
8
|
+
idx_scan as index_scans
|
9
|
+
FROM pg_stat_user_indexes ui
|
10
|
+
JOIN pg_index i ON ui.indexrelid = i.indexrelid
|
11
|
+
ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
|
12
|
+
pg_relation_size(i.indexrelid) DESC;
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module RubyPGExtras
|
2
|
+
class TableInfo
|
3
|
+
def self.call(table_name = nil)
|
4
|
+
new.call(table_name)
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(table_name)
|
8
|
+
tables_data.select do |table_data|
|
9
|
+
if table_name == nil
|
10
|
+
true
|
11
|
+
else
|
12
|
+
table_data.fetch("tablename") == table_name
|
13
|
+
end
|
14
|
+
end.sort_by do |table_data|
|
15
|
+
table_data.fetch("tablename")
|
16
|
+
end.map do |table_data|
|
17
|
+
table_name = table_data.fetch("tablename")
|
18
|
+
|
19
|
+
{
|
20
|
+
table_name: table_name,
|
21
|
+
table_size: table_size_data.find do |el|
|
22
|
+
el.fetch("name") == table_name
|
23
|
+
end.fetch("size", "N/A"),
|
24
|
+
table_cache_hit: table_cache_hit_data.find do |el|
|
25
|
+
el.fetch("name") == table_name
|
26
|
+
end.fetch("ratio", "N/A"),
|
27
|
+
indexes_cache_hit: index_cache_hit_data.find do |el|
|
28
|
+
el.fetch("name") == table_name
|
29
|
+
end.fetch("ratio", "N/A"),
|
30
|
+
estimated_rows: records_rank_data.find do |el|
|
31
|
+
el.fetch("name") == table_name
|
32
|
+
end.fetch("estimated_count", "N/A"),
|
33
|
+
sequential_scans: seq_scans_data.find do |el|
|
34
|
+
el.fetch("name") == table_name
|
35
|
+
end.fetch("count", "N/A"),
|
36
|
+
indexes_scans: table_index_scans_data.find do |el|
|
37
|
+
el.fetch("name") == table_name
|
38
|
+
end.fetch("count", "N/A")
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def index_cache_hit_data
|
46
|
+
@_index_cache_hit_data ||= query_module.index_cache_hit(in_format: :hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def table_cache_hit_data
|
50
|
+
@_table_cache_hit_data ||= query_module.table_cache_hit(in_format: :hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def table_size_data
|
54
|
+
@_table_size_data ||= query_module.table_size(in_format: :hash)
|
55
|
+
end
|
56
|
+
|
57
|
+
def records_rank_data
|
58
|
+
@_records_rank_data ||= query_module.records_rank(in_format: :hash)
|
59
|
+
end
|
60
|
+
|
61
|
+
def tables_data
|
62
|
+
@_tables_data ||= query_module.tables(in_format: :hash)
|
63
|
+
end
|
64
|
+
|
65
|
+
def seq_scans_data
|
66
|
+
@_seq_scans_data ||= query_module.seq_scans(in_format: :hash)
|
67
|
+
end
|
68
|
+
|
69
|
+
def table_index_scans_data
|
70
|
+
@_table_index_scans_data ||= query_module.table_index_scans(in_format: :hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
def query_module
|
74
|
+
RubyPGExtras
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'terminal-table'
|
4
|
+
|
5
|
+
module RubyPGExtras
|
6
|
+
class TableInfoPrint
|
7
|
+
def self.call(data)
|
8
|
+
new.call(data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(data)
|
12
|
+
rows = data.map do |el|
|
13
|
+
[
|
14
|
+
el.fetch(:table_name),
|
15
|
+
el.fetch(:table_size),
|
16
|
+
el.fetch(:table_cache_hit),
|
17
|
+
el.fetch(:indexes_cache_hit),
|
18
|
+
el.fetch(:estimated_rows),
|
19
|
+
el.fetch(:sequential_scans),
|
20
|
+
el.fetch(:indexes_scans)
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
puts Terminal::Table.new(
|
25
|
+
headings: [
|
26
|
+
"Table name",
|
27
|
+
"Table size",
|
28
|
+
"Table cache hit",
|
29
|
+
"Indexes cache hit",
|
30
|
+
"Estimated rows",
|
31
|
+
"Sequential scans",
|
32
|
+
"Indexes scans"
|
33
|
+
],
|
34
|
+
title: title,
|
35
|
+
rows: rows
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def title
|
42
|
+
"Table info"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/ruby-pg-extras.rb
CHANGED
@@ -5,6 +5,10 @@ require 'uri'
|
|
5
5
|
require 'pg'
|
6
6
|
require 'ruby-pg-extras/diagnose_data'
|
7
7
|
require 'ruby-pg-extras/diagnose_print'
|
8
|
+
require 'ruby-pg-extras/index_info'
|
9
|
+
require 'ruby-pg-extras/index_info_print'
|
10
|
+
require 'ruby-pg-extras/table_info'
|
11
|
+
require 'ruby-pg-extras/table_info_print'
|
8
12
|
|
9
13
|
module RubyPGExtras
|
10
14
|
@@database_url = nil
|
@@ -12,10 +16,10 @@ module RubyPGExtras
|
|
12
16
|
|
13
17
|
QUERIES = %i(
|
14
18
|
add_extensions bloat blocking cache_hit db_settings
|
15
|
-
calls extensions table_cache_hit index_cache_hit
|
16
|
-
index_size index_usage null_indexes locks all_locks
|
19
|
+
calls extensions table_cache_hit tables index_cache_hit
|
20
|
+
indexes index_size index_usage index_scans null_indexes locks all_locks
|
17
21
|
long_running_queries mandelbrot outliers
|
18
|
-
records_rank seq_scans table_indexes_size
|
22
|
+
records_rank seq_scans table_index_scans table_indexes_size
|
19
23
|
table_size total_index_size total_table_size
|
20
24
|
unused_indexes duplicate_indexes vacuum_stats kill_all
|
21
25
|
pg_stat_statements_reset buffercache_stats
|
@@ -76,6 +80,36 @@ module RubyPGExtras
|
|
76
80
|
RubyPGExtras::DiagnosePrint.call(data)
|
77
81
|
elsif in_format == :hash
|
78
82
|
data
|
83
|
+
elsif in_format == :array
|
84
|
+
data.map(&:values)
|
85
|
+
else
|
86
|
+
raise "Invalid 'in_format' argument!"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.index_info(args: {}, in_format: :display_table)
|
91
|
+
data = RubyPGExtras::IndexInfo.call(args[:table_name])
|
92
|
+
|
93
|
+
if in_format == :display_table
|
94
|
+
RubyPGExtras::IndexInfoPrint.call(data)
|
95
|
+
elsif in_format == :hash
|
96
|
+
data
|
97
|
+
elsif in_format == :array
|
98
|
+
data.map(&:values)
|
99
|
+
else
|
100
|
+
raise "Invalid 'in_format' argument!"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.table_info(args: {}, in_format: :display_table)
|
105
|
+
data = RubyPGExtras::TableInfo.call(args[:table_name])
|
106
|
+
|
107
|
+
if in_format == :display_table
|
108
|
+
RubyPGExtras::TableInfoPrint.call(data)
|
109
|
+
elsif in_format == :hash
|
110
|
+
data
|
111
|
+
elsif in_format == :array
|
112
|
+
data.map(&:values)
|
79
113
|
else
|
80
114
|
raise "Invalid 'in_format' argument!"
|
81
115
|
end
|
data/spec/diagnose_data_spec.rb
CHANGED
@@ -20,9 +20,9 @@ describe RubyPGExtras::DiagnoseData do
|
|
20
20
|
|
21
21
|
expect(RubyPGExtras).to receive(:null_indexes) {
|
22
22
|
[
|
23
|
-
{ "oid" => 123, "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "unique" =>
|
24
|
-
{ "oid" => 321, "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "unique" =>
|
25
|
-
{ "oid" => 231, "index" => "index_channels_on_slack_id", "index_size" => "56 MB", "unique" =>
|
23
|
+
{ "oid" => 123, "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "unique" => true, "null_frac" => "00.00%", "expected_saving" => "0 kb" },
|
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" }
|
26
26
|
]
|
27
27
|
}
|
28
28
|
|
@@ -55,17 +55,6 @@ describe RubyPGExtras::DiagnoseData do
|
|
55
55
|
end
|
56
56
|
|
57
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
58
|
it "works" do
|
70
59
|
expect {
|
71
60
|
RubyPGExtras::DiagnosePrint.call(result)
|
data/spec/diagnose_print_spec.rb
CHANGED
@@ -8,20 +8,23 @@ describe RubyPGExtras::DiagnosePrint do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
let(:data) do
|
11
|
-
|
12
|
-
|
11
|
+
[
|
12
|
+
{
|
13
|
+
:check_name => :table_cache_hit,
|
13
14
|
:ok => false,
|
14
15
|
:message => "Table hit ratio too low: 0.906977."
|
15
|
-
|
16
|
-
|
16
|
+
},
|
17
|
+
{
|
18
|
+
:check_name => :index_cache_hit,
|
17
19
|
:ok => false,
|
18
20
|
:message => "Index hit ratio is too low: 0.818182."
|
19
21
|
},
|
20
|
-
|
22
|
+
{
|
23
|
+
:check_name => :ssl_used,
|
21
24
|
:ok => true,
|
22
25
|
:message => "Database client is using a secure SSL connection."
|
23
26
|
}
|
24
|
-
|
27
|
+
]
|
25
28
|
end
|
26
29
|
|
27
30
|
describe "call" do
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RubyPGExtras::IndexInfo do
|
6
|
+
subject(:result) do
|
7
|
+
RubyPGExtras::IndexInfo.call
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "call" do
|
11
|
+
context "stubbed cases" do
|
12
|
+
before do
|
13
|
+
expect(RubyPGExtras).to receive(:indexes) {
|
14
|
+
[
|
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" },
|
17
|
+
]
|
18
|
+
}
|
19
|
+
|
20
|
+
expect(RubyPGExtras).to receive(:index_size) {
|
21
|
+
[
|
22
|
+
{ "name" => "index_users_on_api_auth_token", "size" => "1744 kB" },
|
23
|
+
{"name" => "index_teams_on_slack_id", "size" => "500 kB"},
|
24
|
+
]
|
25
|
+
}
|
26
|
+
|
27
|
+
expect(RubyPGExtras).to receive(:null_indexes) {
|
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" }
|
30
|
+
]
|
31
|
+
}
|
32
|
+
|
33
|
+
expect(RubyPGExtras).to receive(:index_scans) {
|
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 }
|
37
|
+
]
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
it "works" do
|
42
|
+
expect {
|
43
|
+
RubyPGExtras::IndexInfoPrint.call(result)
|
44
|
+
}.not_to raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "real data" do
|
49
|
+
it "works" do
|
50
|
+
expect {
|
51
|
+
RubyPGExtras::IndexInfoPrint.call(result)
|
52
|
+
}.not_to raise_error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RubyPGExtras::TableInfo do
|
6
|
+
subject(:result) do
|
7
|
+
RubyPGExtras::TableInfo.call
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "call" do
|
11
|
+
context "stubbed cases" do
|
12
|
+
before do
|
13
|
+
expect(RubyPGExtras).to receive(:tables) {
|
14
|
+
[
|
15
|
+
{ "schemaname" => "public", "tablename" => "users" },
|
16
|
+
{ "schemaname" => "public", "tablename" => "teams" }
|
17
|
+
]
|
18
|
+
}
|
19
|
+
|
20
|
+
expect(RubyPGExtras).to receive(:table_size) {
|
21
|
+
[
|
22
|
+
{ "name" => "teams", "size" => "25 MB" },
|
23
|
+
{"name" => "users", "size" => "250 MB"},
|
24
|
+
]
|
25
|
+
}
|
26
|
+
|
27
|
+
expect(RubyPGExtras).to receive(:index_cache_hit) {
|
28
|
+
[
|
29
|
+
{ "name" => "teams", "ratio" => "0.98" },
|
30
|
+
{ "name" => "users", "ratio" => "0.999" },
|
31
|
+
]
|
32
|
+
}
|
33
|
+
|
34
|
+
expect(RubyPGExtras).to receive(:table_cache_hit) {
|
35
|
+
[
|
36
|
+
{ "name" => "teams", "ratio" => "0.88" },
|
37
|
+
{ "name" => "users", "ratio" => "0.899" },
|
38
|
+
]
|
39
|
+
}
|
40
|
+
|
41
|
+
expect(RubyPGExtras).to receive(:records_rank) {
|
42
|
+
[
|
43
|
+
{ "name" => "teams", "estimated_count" => "358" },
|
44
|
+
{ "name" => "users", "estimated_count" => "8973" },
|
45
|
+
]
|
46
|
+
}
|
47
|
+
|
48
|
+
expect(RubyPGExtras).to receive(:seq_scans) {
|
49
|
+
[
|
50
|
+
{ "name" => "teams", "count" => "0" },
|
51
|
+
{ "name" => "users", "count" => "409328" },
|
52
|
+
]
|
53
|
+
}
|
54
|
+
|
55
|
+
expect(RubyPGExtras).to receive(:table_index_scans) {
|
56
|
+
[
|
57
|
+
{ "name" => "teams", "count" => "8579" },
|
58
|
+
{ "name" => "users", "count" => "0" },
|
59
|
+
]
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
it "works" do
|
64
|
+
expect {
|
65
|
+
RubyPGExtras::TableInfoPrint.call(result)
|
66
|
+
}.not_to raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "real data" do
|
71
|
+
it "works" do
|
72
|
+
expect {
|
73
|
+
RubyPGExtras::TableInfoPrint.call(result)
|
74
|
+
}.not_to raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
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: 3.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pawurb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -99,6 +99,8 @@ files:
|
|
99
99
|
- lib/ruby-pg-extras.rb
|
100
100
|
- lib/ruby-pg-extras/diagnose_data.rb
|
101
101
|
- lib/ruby-pg-extras/diagnose_print.rb
|
102
|
+
- lib/ruby-pg-extras/index_info.rb
|
103
|
+
- lib/ruby-pg-extras/index_info_print.rb
|
102
104
|
- lib/ruby-pg-extras/queries/add_extensions.sql
|
103
105
|
- lib/ruby-pg-extras/queries/all_locks.sql
|
104
106
|
- lib/ruby-pg-extras/queries/bloat.sql
|
@@ -112,8 +114,10 @@ files:
|
|
112
114
|
- lib/ruby-pg-extras/queries/duplicate_indexes.sql
|
113
115
|
- lib/ruby-pg-extras/queries/extensions.sql
|
114
116
|
- lib/ruby-pg-extras/queries/index_cache_hit.sql
|
117
|
+
- lib/ruby-pg-extras/queries/index_scans.sql
|
115
118
|
- lib/ruby-pg-extras/queries/index_size.sql
|
116
119
|
- lib/ruby-pg-extras/queries/index_usage.sql
|
120
|
+
- lib/ruby-pg-extras/queries/indexes.sql
|
117
121
|
- lib/ruby-pg-extras/queries/kill_all.sql
|
118
122
|
- lib/ruby-pg-extras/queries/locks.sql
|
119
123
|
- lib/ruby-pg-extras/queries/long_running_queries.sql
|
@@ -126,19 +130,25 @@ files:
|
|
126
130
|
- lib/ruby-pg-extras/queries/seq_scans.sql
|
127
131
|
- lib/ruby-pg-extras/queries/ssl_used.sql
|
128
132
|
- lib/ruby-pg-extras/queries/table_cache_hit.sql
|
133
|
+
- lib/ruby-pg-extras/queries/table_index_scans.sql
|
129
134
|
- lib/ruby-pg-extras/queries/table_indexes_size.sql
|
130
135
|
- lib/ruby-pg-extras/queries/table_size.sql
|
136
|
+
- lib/ruby-pg-extras/queries/tables.sql
|
131
137
|
- lib/ruby-pg-extras/queries/total_index_size.sql
|
132
138
|
- lib/ruby-pg-extras/queries/total_table_size.sql
|
133
139
|
- lib/ruby-pg-extras/queries/unused_indexes.sql
|
134
140
|
- lib/ruby-pg-extras/queries/vacuum_stats.sql
|
141
|
+
- lib/ruby-pg-extras/table_info.rb
|
142
|
+
- lib/ruby-pg-extras/table_info_print.rb
|
135
143
|
- lib/ruby-pg-extras/version.rb
|
136
144
|
- ruby-pg-extras-diagnose.png
|
137
145
|
- ruby-pg-extras.gemspec
|
138
146
|
- spec/diagnose_data_spec.rb
|
139
147
|
- spec/diagnose_print_spec.rb
|
148
|
+
- spec/index_info_spec.rb
|
140
149
|
- spec/smoke_spec.rb
|
141
150
|
- spec/spec_helper.rb
|
151
|
+
- spec/table_info_spec.rb
|
142
152
|
homepage: http://github.com/pawurb/ruby-pg-extras
|
143
153
|
licenses:
|
144
154
|
- MIT
|
@@ -165,5 +175,7 @@ summary: Ruby PostgreSQL performance database insights
|
|
165
175
|
test_files:
|
166
176
|
- spec/diagnose_data_spec.rb
|
167
177
|
- spec/diagnose_print_spec.rb
|
178
|
+
- spec/index_info_spec.rb
|
168
179
|
- spec/smoke_spec.rb
|
169
180
|
- spec/spec_helper.rb
|
181
|
+
- spec/table_info_spec.rb
|