model_probe 1.1.0 → 1.1.1
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/Gemfile.lock +13 -11
- data/lib/model_probe/probes/columns.rb +95 -0
- data/lib/model_probe/probes/indexes.rb +33 -0
- data/lib/model_probe/probes/metadata.rb +47 -0
- data/lib/model_probe/probes/subclasses.rb +67 -0
- data/lib/model_probe/probes.rb +35 -0
- data/lib/model_probe/version.rb +1 -1
- data/lib/model_probe.rb +3 -176
- data/model_probe.gemspec +2 -0
- data/tags +33 -28
- metadata +26 -8
- data/lib/model_probe/color.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fedda5d159cc8bbc6bd0181bf718555437137143a893ca70c0ebacc9cdb1bf50
|
4
|
+
data.tar.gz: ec4be05cd44a4824637e062a538234327beaf5644630565beedbfd2c520becb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce89a216d52fbace263249b4874c674cc94302305acd38205f2e5f57861cb2af086fb414b7fcd692171732cda07151c8874c4d690579447c25850d30cc700e11
|
7
|
+
data.tar.gz: a30aac6054f3c4beca2d7b745b4628fe9b654fc0265da4c498ceb3e8b9f7385d3f8aac3e19962a4811be5ac487a2ae4f22f66cf1907c8ae5c7a905024e7e0897
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
model_probe (1.1.
|
4
|
+
model_probe (1.1.1)
|
5
|
+
rainbow
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
@@ -17,7 +18,7 @@ GEM
|
|
17
18
|
rainbow (3.1.1)
|
18
19
|
regexp_parser (2.8.0)
|
19
20
|
rexml (3.2.5)
|
20
|
-
rubocop (1.
|
21
|
+
rubocop (1.52.0)
|
21
22
|
json (~> 2.3)
|
22
23
|
parallel (~> 1.10)
|
23
24
|
parser (>= 3.2.0.0)
|
@@ -27,28 +28,29 @@ GEM
|
|
27
28
|
rubocop-ast (>= 1.28.0, < 2.0)
|
28
29
|
ruby-progressbar (~> 1.7)
|
29
30
|
unicode-display_width (>= 2.4.0, < 3.0)
|
30
|
-
rubocop-ast (1.
|
31
|
+
rubocop-ast (1.29.0)
|
31
32
|
parser (>= 3.2.1.0)
|
32
|
-
rubocop-performance (1.
|
33
|
+
rubocop-performance (1.18.0)
|
33
34
|
rubocop (>= 1.7.0, < 2.0)
|
34
35
|
rubocop-ast (>= 0.4.0)
|
35
36
|
ruby-progressbar (1.13.0)
|
36
|
-
standard (1.
|
37
|
+
standard (1.29.0)
|
37
38
|
language_server-protocol (~> 3.17.0.2)
|
38
39
|
lint_roller (~> 1.0)
|
39
|
-
rubocop (~> 1.
|
40
|
+
rubocop (~> 1.52.0)
|
40
41
|
standard-custom (~> 1.0.0)
|
41
|
-
standard-performance (~> 1.0
|
42
|
-
standard-custom (1.0.
|
42
|
+
standard-performance (~> 1.1.0)
|
43
|
+
standard-custom (1.0.1)
|
43
44
|
lint_roller (~> 1.0)
|
44
|
-
standard-performance (1.0
|
45
|
+
standard-performance (1.1.0)
|
45
46
|
lint_roller (~> 1.0)
|
46
|
-
rubocop-performance (~> 1.
|
47
|
+
rubocop-performance (~> 1.18.0)
|
47
48
|
standardrb (1.0.1)
|
48
49
|
standard
|
49
50
|
unicode-display_width (2.4.2)
|
50
51
|
|
51
52
|
PLATFORMS
|
53
|
+
arm64-darwin-21
|
52
54
|
arm64-darwin-22
|
53
55
|
|
54
56
|
DEPENDENCIES
|
@@ -57,4 +59,4 @@ DEPENDENCIES
|
|
57
59
|
standardrb
|
58
60
|
|
59
61
|
BUNDLED WITH
|
60
|
-
2.
|
62
|
+
2.3.5
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelProbe::Probes::Columns
|
4
|
+
def probe_columns
|
5
|
+
name_pad = columns.map { |c| c.name.length }.max + 2
|
6
|
+
type_pad = columns.map { |c| c.type.length }.max + 2
|
7
|
+
sql_type_pad = columns.map { |c| c.sql_type.length }.max + 1
|
8
|
+
columns.sort_by(&:name).each do |column|
|
9
|
+
probe_column column, name_pad: name_pad, type_pad: type_pad, sql_type_pad: sql_type_pad
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def primary_key_columns
|
16
|
+
columns.select { |column| primary_key_column? column }.sort_by(&:name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def foreign_key_columns
|
20
|
+
columns.select { |column| foreign_key_column? column }.sort_by(&:name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def relation_columns
|
24
|
+
columns.select { |column| relation_column? column }.sort_by(&:name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def required_columns
|
28
|
+
columns.select { |column| required_column? column }.sort_by(&:name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def limit_columns
|
32
|
+
columns.select { |column| limit_column? column }.sort_by(&:name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def validation_columns
|
36
|
+
(required_columns + limit_columns).uniq.sort_by(&:name)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def probe_column(column, name_pad:, type_pad:, sql_type_pad:)
|
42
|
+
name = column.name
|
43
|
+
if primary_key_column?(column)
|
44
|
+
print Rainbow("*#{name}".rjust(name_pad)).magenta.bright
|
45
|
+
else
|
46
|
+
print Rainbow(name.to_s.rjust(name_pad)).magenta
|
47
|
+
end
|
48
|
+
print " "
|
49
|
+
print column.type.to_s.ljust(type_pad, ".")
|
50
|
+
print Rainbow(column.sql_type.to_s.ljust(sql_type_pad)).dimgray
|
51
|
+
print Rainbow("NULLABLE ").dimgray.faint if column.null
|
52
|
+
print Rainbow("REQUIRED ").indianred unless column.null
|
53
|
+
print Rainbow("default=").dimgray + Rainbow("#{column.default} ").skyblue if column.default
|
54
|
+
print "- #{Rainbow(column.comment).dimgray}" if column.comment
|
55
|
+
puts
|
56
|
+
end
|
57
|
+
|
58
|
+
def primary_key_column?(column)
|
59
|
+
column.name == primary_key
|
60
|
+
end
|
61
|
+
|
62
|
+
def foreign_key_column?(column)
|
63
|
+
return false if primary_key_column?(column)
|
64
|
+
column.name.end_with? "_id"
|
65
|
+
end
|
66
|
+
|
67
|
+
def timestamp_column?(column)
|
68
|
+
column.type == :datetime && column.name =~ /(created|updated|modified)/
|
69
|
+
end
|
70
|
+
|
71
|
+
def required_column?(column)
|
72
|
+
return false if primary_key_column?(column)
|
73
|
+
return false if foreign_key_column?(column)
|
74
|
+
return false if timestamp_column?(column)
|
75
|
+
!column.null
|
76
|
+
end
|
77
|
+
|
78
|
+
def limit_column?(column)
|
79
|
+
return false if primary_key_column?(column)
|
80
|
+
return false if foreign_key_column?(column)
|
81
|
+
return false if timestamp_column?(column)
|
82
|
+
%i[text string].include?(column.type) && column.limit.to_i > 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def relation_column?(column)
|
86
|
+
return false if column.name == primary_key
|
87
|
+
column.name.end_with?("_id")
|
88
|
+
end
|
89
|
+
|
90
|
+
def fixture_columns
|
91
|
+
columns.sort_by(&:name).select do |column|
|
92
|
+
!primary_key_column?(column) && !timestamp_column?(column)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelProbe::Probes::Indexes
|
4
|
+
def probe_indexes
|
5
|
+
indexes = connection.indexes(table_name)
|
6
|
+
name_pad = indexes.map { |c| c.name.length }.max + 1
|
7
|
+
indexes.sort_by(&:name).each do |index|
|
8
|
+
probe_index index, name_pad: name_pad
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def probe_index(index, name_pad:)
|
15
|
+
print Rainbow(index.name.to_s.rjust(name_pad)).yellow
|
16
|
+
print Rainbow(" [").dimgray
|
17
|
+
index.columns.each_with_index do |column, index|
|
18
|
+
print Rainbow(", ").dimgray if index > 0
|
19
|
+
print Rainbow(column).magenta
|
20
|
+
end
|
21
|
+
print Rainbow("]").dimgray
|
22
|
+
print Rainbow(" UNIQUE").green.bright if index.unique
|
23
|
+
|
24
|
+
if index.where
|
25
|
+
print Rainbow(" where(#{index.where})").dimgray
|
26
|
+
end
|
27
|
+
|
28
|
+
if index.using
|
29
|
+
print Rainbow(" using(#{index.using})").dimgray
|
30
|
+
end
|
31
|
+
puts
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelProbe::Probes::Metadata
|
4
|
+
def probe_metadata
|
5
|
+
puts Rainbow(name).green + Rainbow(" < ").dimgray.faint + Rainbow(superclass.name).green.faint
|
6
|
+
puts Rainbow(" Database engine ".ljust(24, ".")).darkgray + " " + Rainbow(connection.adapter_name).skyblue.bright + " " + Rainbow(connection.database_version).skyblue.faint
|
7
|
+
puts Rainbow(" Database name ".ljust(24, ".")).darkgray + " " + Rainbow(connection_db_config.database).skyblue
|
8
|
+
puts Rainbow(" Table name ".ljust(24, ".")).darkgray + " " + Rainbow(table_name).skyblue
|
9
|
+
puts Rainbow(" Default role".ljust(24, ".")).darkgray + " " + Rainbow(default_role).skyblue
|
10
|
+
puts Rainbow(" Connection config ".ljust(24, ".")).darkgray
|
11
|
+
connection_db_config.configuration_hash.to_yaml.split("\n")[1..].each { |line| puts " " + Rainbow(line).skyblue.faint }
|
12
|
+
puts
|
13
|
+
puts Rainbow(" DDL ".ljust(24, ".")).darkgray
|
14
|
+
if /create table/i.match?(ddl)
|
15
|
+
ddl.split("\n").each do |line|
|
16
|
+
line = line.squish
|
17
|
+
next if line.blank?
|
18
|
+
next if line.start_with?("--")
|
19
|
+
next if line.start_with?("/*")
|
20
|
+
next if /error|warning|Couldn't execute/i.match?(line)
|
21
|
+
puts Rainbow(" #{line}").skyblue.faint
|
22
|
+
end
|
23
|
+
else
|
24
|
+
puts Rainbow(" Failed to generate DDL string! #{ddl}").indianred
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def ddl
|
31
|
+
config = connection_db_config.configuration_hash
|
32
|
+
@ddl ||= begin
|
33
|
+
case connection.adapter_name
|
34
|
+
when /sqlite/i
|
35
|
+
`sqlite3 #{config[:database]} '.schema #{table_name}' 2>&1`
|
36
|
+
when /postgresql/i
|
37
|
+
`PGPASSWORD=#{config[:password]} pg_dump --host=#{config[:host]} --port=#{config[:port]} --username=#{config[:username]} --schema-only --table=#{table_name} #{config[:database]} 2>&1`
|
38
|
+
when /mysql/i
|
39
|
+
`mysqldump --host=#{config[:host]} --port=#{config[:port]} --user=#{config[:username]} --password=#{config[:password]} --skip-lock-tables --no-data --compact #{config[:database]} #{table_name} 2>&1`
|
40
|
+
else
|
41
|
+
"DDL output is not yet supported for #{connection.adapter_name}!"
|
42
|
+
end
|
43
|
+
rescue => e
|
44
|
+
"Failed to generate DDL string! #{e.message}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelProbe::Probes::Subclasses
|
4
|
+
def probe_subclasses
|
5
|
+
@count = 0
|
6
|
+
@max_name_size = 0
|
7
|
+
puts Rainbow(name).green + Rainbow(" < ").dimgray.faint + Rainbow(superclass.name).green.faint
|
8
|
+
grouped = subclasses.each_with_object({}) do |model, memo|
|
9
|
+
@max_name_size = model.name.size if model.name.size > @max_name_size
|
10
|
+
location = Object.const_source_location(model.name)
|
11
|
+
case location
|
12
|
+
when Array
|
13
|
+
path = location.first
|
14
|
+
type = "First party" if first_party?(path)
|
15
|
+
type = "Third party" if third_party?(path)
|
16
|
+
type ||= "Unknown"
|
17
|
+
memo[type] ||= []
|
18
|
+
memo[type] << {name: model.name, path: path}
|
19
|
+
when NilClass
|
20
|
+
memo["Dynamic"] ||= []
|
21
|
+
memo["Dynamic"] << {name: model.name, path: "defined dynamically at runtime"}
|
22
|
+
else
|
23
|
+
memo["Unknown"] ||= []
|
24
|
+
memo["Unknown"] << {name: model.name, path: nil}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
keys = [
|
29
|
+
"First party",
|
30
|
+
"Dynamic",
|
31
|
+
"Third party",
|
32
|
+
"Unknown"
|
33
|
+
]
|
34
|
+
|
35
|
+
keys.each do |key|
|
36
|
+
next unless grouped[key]&.any?
|
37
|
+
puts Rainbow(" #{key} subclasses ".ljust(35, ".")).dimgray
|
38
|
+
grouped[key].sort_by { |entry| entry[:name] }.each do |entry|
|
39
|
+
probe_subclass entry[:name], entry[:path]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def probe_subclass(name, path)
|
47
|
+
path = path.split(/\/(?=app\/models\/)/i).last if path.include?("/app/models/") && !path.include?("/ruby/gems/")
|
48
|
+
path = path.split(/\/(?=ruby\/gems\/)/i).last if path.include?("/ruby/gems/")
|
49
|
+
prefix = (@count += 1).to_s.rjust(8) + " ..."
|
50
|
+
puts [
|
51
|
+
Rainbow(prefix.to_s.ljust(prefix.size + @max_name_size - name.size, ".")).dimgray.faint,
|
52
|
+
Rainbow(name).mediumslateblue,
|
53
|
+
Rainbow("<").faint,
|
54
|
+
Rainbow(self.name).dimgray.faint,
|
55
|
+
Rainbow(path.to_s).faint
|
56
|
+
].join(" ")
|
57
|
+
end
|
58
|
+
|
59
|
+
def third_party?(path)
|
60
|
+
path.include? "/ruby/gems/"
|
61
|
+
end
|
62
|
+
|
63
|
+
def first_party?(path)
|
64
|
+
return false if third_party?(path)
|
65
|
+
path.include? "/app/models/"
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModelProbe::Probes; end
|
4
|
+
|
5
|
+
require_relative "probes/metadata"
|
6
|
+
require_relative "probes/columns"
|
7
|
+
require_relative "probes/indexes"
|
8
|
+
require_relative "probes/subclasses"
|
9
|
+
|
10
|
+
module ModelProbe::Probes
|
11
|
+
include Metadata
|
12
|
+
include Columns
|
13
|
+
include Indexes
|
14
|
+
include Subclasses
|
15
|
+
|
16
|
+
def probe
|
17
|
+
if name == "ActiveRecord::Base" || abstract_class?
|
18
|
+
probe_subclasses
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
|
22
|
+
probe_metadata
|
23
|
+
puts
|
24
|
+
|
25
|
+
puts Rainbow(" Columns ".ljust(24, ".")).darkgray
|
26
|
+
probe_columns
|
27
|
+
puts
|
28
|
+
|
29
|
+
puts Rainbow(" Indexes ".ljust(24, ".")).darkgray
|
30
|
+
probe_indexes
|
31
|
+
puts
|
32
|
+
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
data/lib/model_probe/version.rb
CHANGED
data/lib/model_probe.rb
CHANGED
@@ -1,22 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "erb"
|
4
|
+
require "rainbow"
|
4
5
|
require_relative "model_probe/version"
|
5
|
-
require_relative "model_probe/color"
|
6
6
|
require_relative "model_probe/railtie" if defined?(Rails)
|
7
|
+
require_relative "model_probe/probes"
|
7
8
|
|
8
9
|
module ModelProbe
|
9
|
-
include
|
10
|
-
|
11
|
-
# Pretty prints column meta data for an ActiveModel
|
12
|
-
def probe
|
13
|
-
probe_header
|
14
|
-
probe_ddl
|
15
|
-
probe_columns
|
16
|
-
probe_indexes
|
17
|
-
probe_footer
|
18
|
-
nil
|
19
|
-
end
|
10
|
+
include Probes
|
20
11
|
|
21
12
|
# Prints a stub that can be used for a test fixture
|
22
13
|
def print_fixture
|
@@ -49,168 +40,4 @@ module ModelProbe
|
|
49
40
|
# trim_mode doesn't seem to work regardless of how it's passed with Ruby 2.7.5
|
50
41
|
ERB.new template_text, trim_mode: "-"
|
51
42
|
end
|
52
|
-
|
53
|
-
def primary_key_column?(column)
|
54
|
-
column.name == primary_key
|
55
|
-
end
|
56
|
-
|
57
|
-
def foreign_key_column?(column)
|
58
|
-
return false if primary_key_column?(column)
|
59
|
-
column.name.end_with? "_id"
|
60
|
-
end
|
61
|
-
|
62
|
-
def timestamp_column?(column)
|
63
|
-
column.type == :datetime && column.name =~ /(created|updated|modified)/
|
64
|
-
end
|
65
|
-
|
66
|
-
def required_column?(column)
|
67
|
-
return false if primary_key_column?(column)
|
68
|
-
return false if foreign_key_column?(column)
|
69
|
-
return false if timestamp_column?(column)
|
70
|
-
!column.null
|
71
|
-
end
|
72
|
-
|
73
|
-
def limit_column?(column)
|
74
|
-
return false if primary_key_column?(column)
|
75
|
-
return false if foreign_key_column?(column)
|
76
|
-
return false if timestamp_column?(column)
|
77
|
-
%i[text string].include?(column.type) && column.limit.to_i > 0
|
78
|
-
end
|
79
|
-
|
80
|
-
def primary_key_columns
|
81
|
-
columns.select { |column| primary_key_column? column }.sort_by(&:name)
|
82
|
-
end
|
83
|
-
|
84
|
-
def foreign_key_columns
|
85
|
-
columns.select { |column| foreign_key_column? column }.sort_by(&:name)
|
86
|
-
end
|
87
|
-
|
88
|
-
def relation_columns
|
89
|
-
columns.select { |column| relation_column? column }.sort_by(&:name)
|
90
|
-
end
|
91
|
-
|
92
|
-
def required_columns
|
93
|
-
columns.select { |column| required_column? column }.sort_by(&:name)
|
94
|
-
end
|
95
|
-
|
96
|
-
def limit_columns
|
97
|
-
columns.select { |column| limit_column? column }.sort_by(&:name)
|
98
|
-
end
|
99
|
-
|
100
|
-
def validation_columns
|
101
|
-
(required_columns + limit_columns).uniq.sort_by(&:name)
|
102
|
-
end
|
103
|
-
|
104
|
-
def relation_column?(column)
|
105
|
-
return false if column.name == primary_key
|
106
|
-
column.name.end_with?("_id")
|
107
|
-
end
|
108
|
-
|
109
|
-
def fixture_columns
|
110
|
-
columns.sort_by(&:name).select do |column|
|
111
|
-
!primary_key_column?(column) && !timestamp_column?(column)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def ddl
|
116
|
-
config = connection_db_config.configuration_hash
|
117
|
-
@ddl ||= begin
|
118
|
-
case connection.adapter_name
|
119
|
-
when /sqlite/i
|
120
|
-
`sqlite3 #{config[:database]} '.schema #{table_name}'`
|
121
|
-
when /postgresql/i
|
122
|
-
`PGPASSWORD=#{config[:password]} pg_dump --host=#{config[:host]} --username=#{config[:username]} --schema-only --table=#{table_name} #{config[:database]}`
|
123
|
-
when /mysql/i
|
124
|
-
`mysqldump --host=#{config[:host]} --user=#{config[:username]} --password=#{config[:password]} --no-data --compact #{config[:database]} #{table_name}`
|
125
|
-
else
|
126
|
-
"DDL output is not yet supported for #{connection.adapter_name}!"
|
127
|
-
end
|
128
|
-
rescue => e
|
129
|
-
Color.red "Failed to generate DDL string! #{e.message}"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def probe_header
|
134
|
-
puts Color.gray "".ljust(110, "=")
|
135
|
-
print connection.adapter_name
|
136
|
-
print Color.gray(" (#{connection.database_version}) - ")
|
137
|
-
puts Color.green(table_name)
|
138
|
-
puts Color.gray "".ljust(110, "=")
|
139
|
-
puts
|
140
|
-
end
|
141
|
-
|
142
|
-
def probe_ddl(pad: 2)
|
143
|
-
return unless ddl
|
144
|
-
lines = ddl.split("\n")
|
145
|
-
lines.each do |line|
|
146
|
-
next if line.strip.blank?
|
147
|
-
next if line.strip.start_with?("--")
|
148
|
-
next if line.strip.start_with?("/*")
|
149
|
-
print " ".ljust(pad)
|
150
|
-
puts Color.gray(line)
|
151
|
-
end
|
152
|
-
puts
|
153
|
-
end
|
154
|
-
|
155
|
-
def probe_column(column, name_pad:, type_pad:, sql_type_pad:)
|
156
|
-
name = column.name
|
157
|
-
if primary_key_column?(column)
|
158
|
-
print Color.pink("*#{name}".rjust(name_pad))
|
159
|
-
else
|
160
|
-
print Color.magenta(name.to_s.rjust(name_pad))
|
161
|
-
end
|
162
|
-
print " "
|
163
|
-
print column.type.to_s.ljust(type_pad, ".")
|
164
|
-
print Color.gray(column.sql_type.to_s.ljust(sql_type_pad))
|
165
|
-
print Color.gray("NULLABLE ") if column.null
|
166
|
-
print Color.pink("REQUIRED ") unless column.null
|
167
|
-
print Color.gray("default=#{column.default} ") if column.default
|
168
|
-
print "- #{Color.gray column.comment}" if column.comment
|
169
|
-
puts
|
170
|
-
end
|
171
|
-
|
172
|
-
def probe_columns
|
173
|
-
name_pad = columns.map { |c| c.name.length }.max + 2
|
174
|
-
type_pad = columns.map { |c| c.type.length }.max + 2
|
175
|
-
sql_type_pad = columns.map { |c| c.sql_type.length }.max + 1
|
176
|
-
|
177
|
-
columns.sort_by(&:name).each do |column|
|
178
|
-
probe_column column, name_pad: name_pad, type_pad: type_pad, sql_type_pad: sql_type_pad
|
179
|
-
end
|
180
|
-
puts
|
181
|
-
end
|
182
|
-
|
183
|
-
def probe_index(index, name_pad:)
|
184
|
-
print Color.yellow_light(index.name.to_s.rjust(name_pad))
|
185
|
-
print Color.gray(" [")
|
186
|
-
index.columns.each_with_index do |column, index|
|
187
|
-
print Color.gray(", ") if index > 0
|
188
|
-
print Color.magenta(column)
|
189
|
-
end
|
190
|
-
print Color.gray("]")
|
191
|
-
print Color.green_light(" UNIQUE") if index.unique
|
192
|
-
|
193
|
-
if index.where
|
194
|
-
print Color.gray(" where(#{index.where})")
|
195
|
-
end
|
196
|
-
|
197
|
-
if index.using
|
198
|
-
print Color.gray(" using(#{index.using})")
|
199
|
-
end
|
200
|
-
puts
|
201
|
-
end
|
202
|
-
|
203
|
-
def probe_indexes
|
204
|
-
indexes = connection.indexes(table_name)
|
205
|
-
name_pad = indexes.map { |c| c.name.length }.max + 1
|
206
|
-
|
207
|
-
indexes.sort_by(&:name).each do |index|
|
208
|
-
probe_index index, name_pad: name_pad
|
209
|
-
end
|
210
|
-
puts
|
211
|
-
end
|
212
|
-
|
213
|
-
def probe_footer
|
214
|
-
puts Color.gray "".ljust(110, "=")
|
215
|
-
end
|
216
43
|
end
|
data/model_probe.gemspec
CHANGED
data/tags
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
!_TAG_PARSER_VERSION!Ruby 0.0 /current.age/
|
48
48
|
!_TAG_PARSER_VERSION!Sh 0.0 /current.age/
|
49
49
|
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
|
50
|
-
!_TAG_PROC_CWD /Users/
|
50
|
+
!_TAG_PROC_CWD /Users/nate.hopkins/work/hopsoft/model_probe/ //
|
51
51
|
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
|
52
52
|
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
|
53
53
|
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
|
@@ -60,47 +60,52 @@
|
|
60
60
|
!_TAG_ROLE_DESCRIPTION!Sh!heredoc endmarker /end marker/
|
61
61
|
!_TAG_ROLE_DESCRIPTION!Sh!script loaded /loaded/
|
62
62
|
ActiveRecord schema visualization and model organization made easy 🙌 README.md /^## ActiveRecord schema visualization and model organization made easy 🙌$/;" s chapter:ModelProbe
|
63
|
-
|
64
|
-
|
63
|
+
Columns lib/model_probe/probes/columns.rb /^module ModelProbe::Probes::Columns$/;" m module:ModelProbe.Probes
|
64
|
+
Indexes lib/model_probe/probes/indexes.rb /^module ModelProbe::Probes::Indexes$/;" m module:ModelProbe.Probes
|
65
|
+
Metadata lib/model_probe/probes/metadata.rb /^module ModelProbe::Probes::Metadata$/;" m module:ModelProbe.Probes
|
65
66
|
ModelProbe README.md /^# ModelProbe$/;" c
|
66
|
-
ModelProbe lib/model_probe.rb /^module ModelProbe$/;" m mixin:include:
|
67
|
-
ModelProbe lib/model_probe/color.rb /^module ModelProbe$/;" m
|
67
|
+
ModelProbe lib/model_probe.rb /^module ModelProbe$/;" m mixin:include:Probes
|
68
68
|
ModelProbe lib/model_probe/railtie.rb /^ module ModelProbe$/;" m
|
69
69
|
ModelProbe lib/model_probe/version.rb /^module ModelProbe$/;" m
|
70
|
+
Probes lib/model_probe/probes.rb /^module ModelProbe::Probes$/;" m module:ModelProbe mixin:include:Metadata,include:Columns,include:Indexes,include:Subclasses
|
71
|
+
Probes lib/model_probe/probes.rb /^module ModelProbe::Probes; end$/;" m module:ModelProbe
|
70
72
|
Quick Start README.md /^## Quick Start$/;" s chapter:ModelProbe
|
71
73
|
Railtie lib/model_probe/railtie.rb /^ class Railtie < Rails::Railtie$/;" c module:ModelProbe
|
72
74
|
Screenshots README.md /^## Screenshots$/;" s chapter:ModelProbe
|
75
|
+
Subclasses lib/model_probe/probes/subclasses.rb /^module ModelProbe::Probes::Subclasses$/;" m module:ModelProbe.Probes
|
73
76
|
Supported Databases README.md /^## Supported Databases$/;" s chapter:ModelProbe
|
74
77
|
Table of Contents README.md /^## Table of Contents$/;" s chapter:ModelProbe
|
75
|
-
VERSION lib/model_probe/version.rb /^ VERSION = "1.1.
|
78
|
+
VERSION lib/model_probe/version.rb /^ VERSION = "1.1.1"$/;" C module:ModelProbe
|
76
79
|
Videos README.md /^## Videos$/;" s chapter:ModelProbe
|
77
|
-
ddl lib/model_probe.rb /^ def ddl$/;" f module:
|
80
|
+
ddl lib/model_probe/probes/metadata.rb /^ def ddl$/;" f module:Metadata
|
78
81
|
erb_template lib/model_probe.rb /^ def erb_template(relative_path)$/;" f module:ModelProbe
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
first_party? lib/model_probe/probes/subclasses.rb /^ def first_party?(path)$/;" f module:Subclasses
|
83
|
+
fixture_columns lib/model_probe/probes/columns.rb /^ def fixture_columns$/;" f module:Columns
|
84
|
+
foreign_key_column? lib/model_probe/probes/columns.rb /^ def foreign_key_column?(column)$/;" f module:Columns
|
85
|
+
foreign_key_columns lib/model_probe/probes/columns.rb /^ def foreign_key_columns$/;" f module:Columns
|
86
|
+
limit_column? lib/model_probe/probes/columns.rb /^ def limit_column?(column)$/;" f module:Columns
|
87
|
+
limit_columns lib/model_probe/probes/columns.rb /^ def limit_columns$/;" f module:Columns
|
84
88
|
model_probe lib/tasks/model_probe.rake /^namespace :model_probe do$/;" n
|
85
89
|
model_probe model_probe.gemspec /^ s.name = "model_probe"$/;" g
|
86
|
-
primary_key_column? lib/model_probe.rb /^ def primary_key_column?(column)$/;" f module:
|
87
|
-
primary_key_columns lib/model_probe.rb /^ def primary_key_columns$/;" f module:
|
90
|
+
primary_key_column? lib/model_probe/probes/columns.rb /^ def primary_key_column?(column)$/;" f module:Columns
|
91
|
+
primary_key_columns lib/model_probe/probes/columns.rb /^ def primary_key_columns$/;" f module:Columns
|
88
92
|
print_fixture lib/model_probe.rb /^ def print_fixture$/;" f module:ModelProbe
|
89
93
|
print_fixture lib/tasks/model_probe.rake /^ task :print_fixture, [:klass] => :environment do |task, args|$/;" t namespace:model_probe
|
90
94
|
print_model lib/model_probe.rb /^ def print_model$/;" f module:ModelProbe
|
91
95
|
print_model lib/tasks/model_probe.rake /^ task :print_model, [:klass] => :environment do |task, args|$/;" t namespace:model_probe
|
92
|
-
probe lib/model_probe.rb /^ def probe$/;" f module:
|
96
|
+
probe lib/model_probe/probes.rb /^ def probe$/;" f module:Probes
|
93
97
|
probe lib/tasks/model_probe.rake /^ task :probe, [:klass] => :environment do |task, args|$/;" t namespace:model_probe
|
94
|
-
probe_column lib/model_probe.rb /^ def probe_column(column, name_pad:, type_pad:, sql_type_pad:)$/;" f module:
|
95
|
-
probe_columns lib/model_probe.rb /^ def probe_columns$/;" f module:
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
relation_column? lib/model_probe.rb /^ def relation_column?(column)$/;" f module:
|
102
|
-
relation_columns lib/model_probe.rb /^ def relation_columns$/;" f module:
|
103
|
-
required_column? lib/model_probe.rb /^ def required_column?(column)$/;" f module:
|
104
|
-
required_columns lib/model_probe.rb /^ def required_columns$/;" f module:
|
105
|
-
|
106
|
-
|
98
|
+
probe_column lib/model_probe/probes/columns.rb /^ def probe_column(column, name_pad:, type_pad:, sql_type_pad:)$/;" f module:Columns
|
99
|
+
probe_columns lib/model_probe/probes/columns.rb /^ def probe_columns$/;" f module:Columns
|
100
|
+
probe_index lib/model_probe/probes/indexes.rb /^ def probe_index(index, name_pad:)$/;" f module:Indexes
|
101
|
+
probe_indexes lib/model_probe/probes/indexes.rb /^ def probe_indexes$/;" f module:Indexes
|
102
|
+
probe_metadata lib/model_probe/probes/metadata.rb /^ def probe_metadata$/;" f module:Metadata
|
103
|
+
probe_subclass lib/model_probe/probes/subclasses.rb /^ def probe_subclass(name, path)$/;" f module:Subclasses
|
104
|
+
probe_subclasses lib/model_probe/probes/subclasses.rb /^ def probe_subclasses$/;" f module:Subclasses
|
105
|
+
relation_column? lib/model_probe/probes/columns.rb /^ def relation_column?(column)$/;" f module:Columns
|
106
|
+
relation_columns lib/model_probe/probes/columns.rb /^ def relation_columns$/;" f module:Columns
|
107
|
+
required_column? lib/model_probe/probes/columns.rb /^ def required_column?(column)$/;" f module:Columns
|
108
|
+
required_columns lib/model_probe/probes/columns.rb /^ def required_columns$/;" f module:Columns
|
109
|
+
third_party? lib/model_probe/probes/subclasses.rb /^ def third_party?(path)$/;" f module:Subclasses
|
110
|
+
timestamp_column? lib/model_probe/probes/columns.rb /^ def timestamp_column?(column)$/;" f module:Columns
|
111
|
+
validation_columns lib/model_probe/probes/columns.rb /^ def validation_columns$/;" f module:Columns
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_probe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rainbow
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: magic_frozen_string_literal
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,7 +52,7 @@ dependencies:
|
|
38
52
|
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
|
-
description:
|
55
|
+
description:
|
42
56
|
email:
|
43
57
|
- natehop@gmail.com
|
44
58
|
executables: []
|
@@ -51,7 +65,11 @@ files:
|
|
51
65
|
- README.md
|
52
66
|
- Rakefile
|
53
67
|
- lib/model_probe.rb
|
54
|
-
- lib/model_probe/
|
68
|
+
- lib/model_probe/probes.rb
|
69
|
+
- lib/model_probe/probes/columns.rb
|
70
|
+
- lib/model_probe/probes/indexes.rb
|
71
|
+
- lib/model_probe/probes/metadata.rb
|
72
|
+
- lib/model_probe/probes/subclasses.rb
|
55
73
|
- lib/model_probe/railtie.rb
|
56
74
|
- lib/model_probe/templates/fixture.yml.erb
|
57
75
|
- lib/model_probe/templates/model.rb.erb
|
@@ -62,7 +80,7 @@ files:
|
|
62
80
|
homepage: http://hopsoft.github.com/model_probe/
|
63
81
|
licenses: []
|
64
82
|
metadata: {}
|
65
|
-
post_install_message:
|
83
|
+
post_install_message:
|
66
84
|
rdoc_options: []
|
67
85
|
require_paths:
|
68
86
|
- lib
|
@@ -77,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
95
|
- !ruby/object:Gem::Version
|
78
96
|
version: '0'
|
79
97
|
requirements: []
|
80
|
-
rubygems_version: 3.
|
81
|
-
signing_key:
|
98
|
+
rubygems_version: 3.1.6
|
99
|
+
signing_key:
|
82
100
|
specification_version: 4
|
83
101
|
summary: ActiveRecord schema visualization and model organization made easy
|
84
102
|
test_files: []
|
data/lib/model_probe/color.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ModelProbe
|
4
|
-
module Color
|
5
|
-
extend self
|
6
|
-
|
7
|
-
COLORS = {
|
8
|
-
blue: 34,
|
9
|
-
cyan: 36,
|
10
|
-
gray: "1;30",
|
11
|
-
green: 32,
|
12
|
-
green_light: 92,
|
13
|
-
magenta: 35,
|
14
|
-
magenta_light: 95,
|
15
|
-
pink: "1;91",
|
16
|
-
red: 31,
|
17
|
-
red_light: 91,
|
18
|
-
white: 37,
|
19
|
-
yellow: 33,
|
20
|
-
yellow_light: 93
|
21
|
-
}
|
22
|
-
|
23
|
-
COLORS.each do |name, code|
|
24
|
-
define_method name do |text|
|
25
|
-
"\e[#{code}m#{text}\e[0m"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|