lib/arql/commands/models.rb in arql-0.3.31 vs lib/arql/commands/models.rb in arql-0.4.0

- old
+ new

@@ -1,86 +1,131 @@ require 'terminal-table' module Arql::Commands module Models class << self - def models - t = [] - t << ['Table Name', 'Model Class', 'Abbr', 'Comment'] - t << nil - Arql::Definition.models.each do |definition| - t << [definition[:table], definition[:model].name, definition[:abbr] || '', definition[:comment] || ''] - end - t - end - - def models_table(table_regexp=nil, column_regexp=nil) - if column_regexp.nil? - Terminal::Table.new do |t| - models.each_with_index { |row, idx| t << (row || :separator) if row.nil? || - table_regexp.nil? || - idx.zero? || - row.any? { |e| e =~ table_regexp } - } + def filter_tables(env_name, definition, format, table_regexp=nil) + result = '' + result << '-- ' if format == 'sql' + result << "Environment: #{env_name}\n" + result << "------------------------------\n\n" + if format == 'sql' + definition.models.each do |model| + if table_regexp? || ( model[:table] =~ table_regexp || model[:comment] =~ table_regexp ) + result << "-- Table: #{table_name}\n\n" + result << definition.connection.exec_query("show create table `#{table_name}`").rows.last.last + ';' + end end else - connection = ::ActiveRecord::Base.connection - table = Terminal::Table.new do |t| - t << ['PK', 'Table', 'Model', 'Name', 'SQL Type', 'Ruby Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment'] + Terminal::Table.new do |t| + t.style = table_style_for_format(format) + t << ['Table Name', 'Model Class', 'Abbr', 'Comment'] t << :separator - Arql::Definition.models.each do |definition| - model_class = definition[:model] - matched_columns = model_class.columns.select { |column| column.name =~ column_regexp || column.comment =~ column_regexp } - next if matched_columns.empty? - matched_columns.each do |column| - pk = if [connection.primary_key(definition[:table])].flatten.include?(column.name) - 'Y' - else - '' - end - t << [pk, definition[:table], model_class.name, column.name, column.sql_type, - column.sql_type_metadata.type, column.sql_type_metadata.limit || '', - column.sql_type_metadata.precision || '', column.sql_type_metadata.scale || '', column.default || '', - column.null, "#{definition[:comment]} - #{column.comment}"] + definition.models.each do |model| + if table_regexp.nil? || ( model[:table] =~ table_regexp || model[:comment] =~ table_regexp ) + t << [model[:table], model[:model].name, model[:abbr] || '', model[:comment] || ''] end end + end.try { |e| + case format + when 'md' + result << e.to_s.lines.map { |l| ' ' + l }.join + when 'org' + result << e.to_s.lines.map { |l| ' ' + l.gsub(/^\+|\+$/, '|') }.join + else + result << e.to_s + end + } + end + result + end + + def filter_columns(env_name, definition, format, column_regexp=nil) + result = '' + result << '-- ' if format == 'sql' + result << "Environment: #{env_name}\n" + result << "------------------------------\n\n" + Terminal::Table.new do |t| + t.style = table_style_for_format(format) + t << ['Table', 'Model', 'Name', 'SQL Type', 'Ruby Type', 'Limit', 'Precision', 'Scale', 'Default', 'Nullable', 'Comment'] + t << :separator + definition.models.each do |model_def| + model_class = model_def[:model] + matched_columns = model_class.columns.select { |column| column.name =~ column_regexp || column.comment =~ column_regexp } + next if matched_columns.empty? + matched_columns.each do |column| + t << [model_def[:table], model_class.name, column.name, column.sql_type, + column.sql_type_metadata.type, column.sql_type_metadata.limit || '', + column.sql_type_metadata.precision || '', column.sql_type_metadata.scale || '', column.default || '', + column.null, "#{model_def[:comment]} - #{column.comment}"] + end end - puts table + end.try { |e| + case format + when 'md' + result << e.to_s.lines.map { |l| ' ' + l }.join + when 'org' + result << e.to_s.lines.map { |l| ' ' + l.gsub(/^\+|\+$/, '|') }.join + else + result << e.to_s + end + } + result + end + + def table_style_for_format(format) + case format + when 'md' + { + border_top: false, + border_bottom: false, + border_i: '|' + } + when 'org' + { + border_top: false, + border_bottom: false, + } + else + {} end end end end - Pry.commands.block_command 'm' do |arg| - puts - if arg.start_with?('c=') or arg.start_with?('column=') - column_regexp = arg.sub(/^c(olumn)?=/, '') - Models::models_table(nil, column_regexp.try { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) }) - else - puts Models::models_table(arg.try { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) }, nil) + Pry.commands.create_command 'm' do + description 'List models or columns (specified by `-c`): m [-e env_name_regexp] -c [column_regexp] [table_regexp]' + + def options(opt) + opt.on '-e', '--env', 'Environment name regexp', argument: true, as: String, required: false, default: nil + opt.on '-f', '--format', 'Table format, available: terminal(default), md, org, sql', argument: true, as: String, required: false, default: 'terminal' + opt.on '-c', '--column', 'Column name regexp', argument: true, as: String, required: false, default: nil end - end - Pry.commands.alias_command 'l', 'm' -end + def process -module Kernel - def models - Arql::Commands::Models::models - end + if opts[:format] == 'sql' && opts[:column] + output.puts 'SQL format is not supported for column listing' + return + end - def tables - models - end + env_names = opts[:env].try {|e| [e]}.presence || Arql::App.environments + env_names = env_names.map { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) } - def model_classes - ::ArqlModel.subclasses - end + Arql::App.instance.definitions.each do |env_name, definition| + next unless env_names.any? { |e| env_name =~ e } - def table_names - models[2..-1].map(&:first) - end + output.puts + if opts[:column] + column_regexp = opts[:column] + output.puts Models::filter_columns(env_name, definition, opts[:format], column_regexp.try { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) }) + else + table_regexp = args&.first + output.puts Models::filter_tables(env_name, definition, opts[:format], table_regexp.try { |e| e.start_with?('/') ? eval(e) : Regexp.new(e) }) + end + end + end - def model_names - models[2..-1].map(&:second) end + + Pry.commands.alias_command 'l', 'm' end