table_inspector 0.1.2 → 0.3.0
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/README.md +15 -3
- data/lib/table_inspector/column.rb +45 -0
- data/lib/table_inspector/grid.rb +26 -0
- data/lib/table_inspector/indexes.rb +75 -0
- data/lib/table_inspector/presenter.rb +28 -0
- data/lib/table_inspector/table.rb +41 -0
- data/lib/table_inspector/text.rb +14 -0
- data/lib/table_inspector/version.rb +1 -1
- data/lib/table_inspector.rb +12 -46
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13d2e909962ad986dd0d91e00067ccb1329951a2235fa3cee6e24b702043d8de
|
4
|
+
data.tar.gz: bfd53531536b24cd6b701106a505731d03212984d332627a34085e277bdef76f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aafe5d2d7e3bafb8b8138572668af4ea163ae367ac2ccd92cf35e6e09512315ef99c23f607ac40f5a00507b37111da2862eccb762d7f872764b39e95e7621f10
|
7
|
+
data.tar.gz: ff22018ac69756f6cf3f795331e1697f9116e5329d27dea11195f6200d5b5cad32808d6e213bb06b637af02ffaa3249cfcaf42032cb96f677000a68bffb81524
|
data/README.md
CHANGED
@@ -1,21 +1,33 @@
|
|
1
1
|
# TableInspector
|
2
2
|
This is a rails gem for print the definition of table. Sometimes we use some gems to embed the table schema to model file(like `annotate`).
|
3
|
-
but sometimes it is hard to maintain
|
3
|
+
but sometimes it is hard to maintain, and it has a little noise. I want to find another way to check the schema of table instead of
|
4
|
+
using `annotate`, So I wrote this gem to do this.
|
4
5
|
|
5
6
|
## Usage
|
6
|
-
Assuming there is a model
|
7
|
-
|
7
|
+
Assuming there is a model call `User` which has `id` and `name` column, and has a unique index for `name`.
|
8
|
+
For print the definition of User, we can use:
|
8
9
|
```ruby
|
9
10
|
require "table_inspector"
|
10
11
|
|
11
12
|
TableInspector.scan User
|
12
13
|
```
|
13
14
|
|
15
|
+

|
16
|
+
|
17
|
+
It will print the all table definition and all indexes.
|
18
|
+
|
14
19
|
And to print specific column by:
|
15
20
|
|
16
21
|
```ruby
|
17
22
|
TableInspector.scan User, :name
|
18
23
|
```
|
24
|
+

|
25
|
+
|
26
|
+
It will print the column definition and which indexes that contains this column.
|
27
|
+
|
28
|
+
Also, you can print `sql_type` which type of column in database by provide `sql_type: true` option:
|
29
|
+
|
30
|
+

|
19
31
|
|
20
32
|
## Installation
|
21
33
|
Add this line to your application's Gemfile:
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
module TableInspector
|
3
|
+
class Column
|
4
|
+
attr_reader :column, :klass, :sql_type, :presenter
|
5
|
+
|
6
|
+
def initialize(klass, column_name, sql_type: false)
|
7
|
+
@column = klass.columns.find {|column| column.name == column_name.to_s}
|
8
|
+
raise_column_not_found_error! unless @column
|
9
|
+
@klass = klass
|
10
|
+
@sql_type = sql_type
|
11
|
+
@presenter = Presenter.new(klass, sql_type: sql_type)
|
12
|
+
end
|
13
|
+
|
14
|
+
def render
|
15
|
+
Text.break_line
|
16
|
+
|
17
|
+
render_title
|
18
|
+
render_body
|
19
|
+
|
20
|
+
Text.break_line
|
21
|
+
|
22
|
+
Indexes.new(klass, column.name).render
|
23
|
+
|
24
|
+
Text.break_line
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def render_title
|
30
|
+
Grid.new.render padding: [0, 2] do |grid|
|
31
|
+
grid << ["#{Text.bold('Table')}: #{klass.table_name}", "#{Text.bold('Column')}: #{column.name}"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_body
|
36
|
+
Grid.new(header: presenter.header).render_ascii do |grid|
|
37
|
+
grid << @presenter.extract_meta(column).values
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def raise_column_not_found_error!
|
42
|
+
raise TableInspector::Error, "Column not found!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module TableInspector
|
3
|
+
class Grid
|
4
|
+
attr_reader :grid
|
5
|
+
|
6
|
+
def initialize(**options)
|
7
|
+
@grid = TTY::Table.new(**options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def render(**with)
|
11
|
+
yield grid
|
12
|
+
puts grid.render(**common_render_options.merge(with))
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_ascii(**with)
|
16
|
+
yield grid
|
17
|
+
puts grid.render(:ascii, **common_render_options.merge(with))
|
18
|
+
end
|
19
|
+
|
20
|
+
def common_render_options
|
21
|
+
{
|
22
|
+
multiline: true
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
module TableInspector
|
3
|
+
class Indexes
|
4
|
+
attr_reader :klass, :column
|
5
|
+
|
6
|
+
def initialize(klass, column = nil)
|
7
|
+
@klass = klass
|
8
|
+
@column = column
|
9
|
+
end
|
10
|
+
|
11
|
+
def render
|
12
|
+
render_title
|
13
|
+
|
14
|
+
if column
|
15
|
+
render_indexes_with_specify_column
|
16
|
+
else
|
17
|
+
render_indexes
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def render_title
|
24
|
+
Grid.new.render padding: [0, 2] do |grid|
|
25
|
+
grid << [Text.bold("Indexes")]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def render_indexes_with_specify_column
|
30
|
+
if indexes_with_specific_column.blank?
|
31
|
+
puts "Empty."
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
Grid.new.render do |grid|
|
36
|
+
indexes_with_specific_column.each do |index|
|
37
|
+
grid << [
|
38
|
+
index.name,
|
39
|
+
"[#{index.columns.join(', ')}]",
|
40
|
+
index.unique ? "UNIQUE" : ""
|
41
|
+
]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def render_indexes
|
47
|
+
if indexes.blank?
|
48
|
+
puts "Empty."
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
Grid.new.render do |grid|
|
53
|
+
indexes.each do |index|
|
54
|
+
grid << [
|
55
|
+
index.name,
|
56
|
+
"[#{index.columns.join(', ')}]",
|
57
|
+
index.unique ? "UNIQUE" : ""
|
58
|
+
]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def indexes
|
64
|
+
@indexes ||= connection.indexes(klass.table_name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def indexes_with_specific_column
|
68
|
+
indexes.select{|index| index.columns.include?(column) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def connection
|
72
|
+
@connection ||= ActiveRecord::Base.connection
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module TableInspector
|
3
|
+
class Presenter
|
4
|
+
attr_reader :klass, :sql_type
|
5
|
+
|
6
|
+
def initialize(klass, sql_type:)
|
7
|
+
@klass = klass
|
8
|
+
@sql_type = sql_type
|
9
|
+
end
|
10
|
+
|
11
|
+
def extract_meta(column)
|
12
|
+
column.as_json.merge(column.sql_type_metadata.as_json).slice(*ordered_keys)
|
13
|
+
end
|
14
|
+
|
15
|
+
def header
|
16
|
+
first_column = klass.columns.first
|
17
|
+
extract_meta(first_column).keys.map(&:humanize)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ordered_keys
|
23
|
+
%w[name type limit null default precision scale comment].tap do |keys|
|
24
|
+
keys << "sql_type" if sql_type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module TableInspector
|
3
|
+
class Table
|
4
|
+
attr_reader :klass, :sql_type, :presenter
|
5
|
+
|
6
|
+
def initialize(klass, sql_type: false)
|
7
|
+
@klass = klass
|
8
|
+
@sql_type = sql_type
|
9
|
+
@presenter = Presenter.new(klass, sql_type: sql_type)
|
10
|
+
end
|
11
|
+
|
12
|
+
def render
|
13
|
+
Text.break_line
|
14
|
+
|
15
|
+
render_title
|
16
|
+
render_body
|
17
|
+
|
18
|
+
Text.break_line
|
19
|
+
|
20
|
+
Indexes.new(klass).render
|
21
|
+
|
22
|
+
Text.break_line
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def render_title
|
28
|
+
Grid.new.render with: {padding: [0, 2]} do |grid|
|
29
|
+
grid << ["#{Text.bold('Table')}: #{klass.table_name}"]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def render_body
|
34
|
+
Grid.new(header: presenter.header).render_ascii do |grid|
|
35
|
+
klass.columns.each do |column|
|
36
|
+
grid << presenter.extract_meta(column).values
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/table_inspector.rb
CHANGED
@@ -1,73 +1,39 @@
|
|
1
1
|
require "table_inspector/version"
|
2
2
|
require "table_inspector/railtie"
|
3
3
|
require "tty-table"
|
4
|
+
require "table_inspector/table"
|
5
|
+
require "table_inspector/grid"
|
6
|
+
require "table_inspector/indexes"
|
7
|
+
require "table_inspector/text"
|
8
|
+
require "table_inspector/column"
|
9
|
+
require "table_inspector/presenter"
|
4
10
|
|
5
11
|
module TableInspector
|
12
|
+
extend self
|
13
|
+
|
6
14
|
Error = Class.new(StandardError)
|
7
15
|
|
8
|
-
|
9
|
-
|
10
|
-
def scan(klass, column_name = nil)
|
16
|
+
def scan(klass, column_name = nil, sql_type: false)
|
11
17
|
begin
|
12
18
|
unless klass.is_a?(Class)
|
13
19
|
klass = klass.constantize
|
14
20
|
end
|
15
|
-
rescue NameError
|
21
|
+
rescue NameError
|
16
22
|
raise_invalid_model_error!
|
17
23
|
end
|
18
24
|
|
19
25
|
raise_invalid_model_error! unless klass < ActiveRecord::Base
|
20
26
|
|
21
27
|
if column_name
|
22
|
-
|
28
|
+
Column.new(klass, column_name, sql_type: sql_type).render
|
23
29
|
else
|
24
|
-
|
30
|
+
Table.new(klass, sql_type: sql_type).render
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
28
34
|
private
|
29
35
|
|
30
|
-
def scan_column(klass, col_name)
|
31
|
-
columns = klass.columns
|
32
|
-
column = columns.find{|col| col.name == col_name.to_s}
|
33
|
-
|
34
|
-
raise_column_not_found_error! unless column
|
35
|
-
|
36
|
-
meta = extract_meta(column)
|
37
|
-
header = meta.keys.map(&:upcase_first)
|
38
|
-
|
39
|
-
table = TTY::Table.new(header: header)
|
40
|
-
table << extract_meta(column).values
|
41
|
-
|
42
|
-
puts table.render(:ascii)
|
43
|
-
end
|
44
|
-
|
45
|
-
def scan_table(klass)
|
46
|
-
columns = klass.columns
|
47
|
-
first_column_meta = extract_meta(columns.first)
|
48
|
-
header = first_column_meta.keys.map(&:upcase_first)
|
49
|
-
table = TTY::Table.new(header: header)
|
50
|
-
|
51
|
-
columns.each do |column|
|
52
|
-
table << extract_meta(column).values
|
53
|
-
end
|
54
|
-
|
55
|
-
puts table.render(:ascii)
|
56
|
-
end
|
57
|
-
|
58
|
-
def extract_meta(column)
|
59
|
-
column.as_json.merge(column.sql_type_metadata.as_json).slice(*ordered_keys)
|
60
|
-
end
|
61
|
-
|
62
|
-
def ordered_keys
|
63
|
-
%w[ name type limit null default precision scale comment]
|
64
|
-
end
|
65
|
-
|
66
36
|
def raise_invalid_model_error!
|
67
37
|
raise Error, "Passed class is not a Model class!"
|
68
38
|
end
|
69
|
-
|
70
|
-
def raise_column_not_found_error!
|
71
|
-
raise Error, "Column not found!"
|
72
|
-
end
|
73
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: table_inspector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -49,7 +49,13 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
51
|
- lib/table_inspector.rb
|
52
|
+
- lib/table_inspector/column.rb
|
53
|
+
- lib/table_inspector/grid.rb
|
54
|
+
- lib/table_inspector/indexes.rb
|
55
|
+
- lib/table_inspector/presenter.rb
|
52
56
|
- lib/table_inspector/railtie.rb
|
57
|
+
- lib/table_inspector/table.rb
|
58
|
+
- lib/table_inspector/text.rb
|
53
59
|
- lib/table_inspector/version.rb
|
54
60
|
- lib/tasks/table_inspector_tasks.rake
|
55
61
|
homepage: https://github.com/table_inspector
|