module Sequoyah

Constants

VERSION

Public Class Methods

annotate(klass, file) click to toggle source
# File lib/sequoyah.rb, line 121
def annotate(klass, file)
  begin
    model_file_name = File.join(model_dir, file)
    annotate_one_file model_file_name, schema_info(klass)
  rescue Exception => e
    puts "Unable to annotate #{file}: #{e.message}"
  end
end
annotate_model_file(annotated, file) click to toggle source
# File lib/sequoyah.rb, line 92
def annotate_model_file(annotated, file)
  begin
    klass = get_model_class(file)
    if klass && annotate(klass, file)
      annotated << klass.to_s.demodulize
    end
  rescue Exception => e
    puts "Unable to annotate #{file}: #{e.message}"
    puts "\t" + e.backtrace.join("\n\t")
  end
end
annotate_one_file(file_name, info_block) click to toggle source
# File lib/sequoyah.rb, line 104
def annotate_one_file(file_name, info_block)
  if File.exist?(file_name)
    current = File.read(file_name)
    pattern = /^#\s[\+\|].+[\+\|]\n*/

    return false if current.scan(pattern).join == info_block

    File.open(file_name, "wb") do |f|
      f.puts info_block + current.gsub(pattern, '')
    end

    true
  else
    false
  end
end
get_loaded_model(model_path) click to toggle source
# File lib/sequoyah.rb, line 82
def get_loaded_model(model_path)
  ObjectSpace.each_object(::Class).
    select do |c|
      Class === c and
      c.ancestors.respond_to?(:include?) and
      c.ancestors.include?(Sequel::Model)
    end.
    detect { |c| c.name.demodulize.underscore == model_path }
end
get_model_class(file) click to toggle source
# File lib/sequoyah.rb, line 76
def get_model_class(file)
  require File.expand_path("#{model_dir}/#{file}")
  model_path = file.gsub(/\.rb$/, '')
  get_loaded_model(model_path) || get_loaded_model(model_path.split("/").last)
end
get_model_files() click to toggle source
# File lib/sequoyah.rb, line 63
def get_model_files
  models = []
  begin
    Dir.chdir(model_dir) do
      models = Dir["**/*.rb"]
    end
  rescue SystemCallError
    puts "No models found in directory '#{model_dir}'."
    exit 1
  end
  models
end
model_dir() click to toggle source
# File lib/sequoyah.rb, line 18
def model_dir
  @model_dir || "app/models"
end
model_dir=(dir) click to toggle source
# File lib/sequoyah.rb, line 22
def model_dir=(dir)
  @model_dir = dir
end
process_fks(model) click to toggle source
# File lib/sequoyah.rb, line 57
def process_fks(model)
  model.db.foreign_key_list(model.table_name).map do |x|
    x[:columns]
  end.flatten
end
run() click to toggle source
# File lib/sequoyah.rb, line 6
def run
  annotated = []

  get_model_files.each do |file|
    annotate_model_file(annotated, file)
  end

  puts annotated.empty? ?
    "Nothing annotated" :
    "Annotated (#{annotated.length}): #{annotated.join(', ')}"
end
schema_info(klass) click to toggle source
# File lib/sequoyah.rb, line 26
def schema_info(klass)
  fks = process_fks(klass)

  table = Terminal::Table.new
  table.title = klass.table_name
  table.headings = ["Column", "Ruby Type", "DB Type", "Default", "Null?", "PK?", "FK?"]

  table.rows = klass.db_schema.map do |key, value|
    [ key,
      value[:type],
      value[:db_type],
      value[:ruby_default].nil? ? '-' : value[:ruby_default],
      value[:allow_null]  ? 'Y' : 'N',
      value[:primary_key] ? 'Y' : 'N',
      fks.include?(key)   ? 'Y' : 'N'
    ]
  end

  # Align to the center the columns:
  # Default, Null?, PK? and FK?
  for i in 3..6
    table.align_column(i, :center)
  end

  # Comment the table
  output = String.new
  table.to_s.each_line { |line| output << "# #{line}" }

  output << "\n\n"
end