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
         |