Module: AnnotateSequel::Model

Defined in:
lib/annotate_sequel/model.rb

Class Method Summary collapse

Class Method Details

.annotate(klass, file) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/annotate_sequel/model.rb', line 108

def annotate(klass, file)
  begin
    info = schema_info(klass)
    did_annotate = false
    model_file_name = File.join(model_dir, file)
    
    if annotate_one_file(model_file_name, info)
      did_annotate = true
    end

    return did_annotate
  rescue Exception => e
    puts "Unable to annotate #{file}: #{e.message}"
  end
end

.annotate_model_file(annotated, file) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/annotate_sequel/model.rb', line 57

def annotate_model_file(annotated, file)
  begin
    klass = get_model_class(file)
    if klass && klass < Sequel::Model
      if annotate(klass, file)
        annotated << klass
      end
    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) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/annotate_sequel/model.rb', line 83

def annotate_one_file(file_name, info_block)
  if File.exist?(file_name)
    old_content = File.read(file_name)

    header_pattern = /(^# Table name:.*?\n(#.*[\r]?\n)*[\r]?)/
    old_header = old_content.match(header_pattern).to_s
    new_header = info_block.match(header_pattern).to_s

    column_pattern = /^#[\t ]+\w+[\t ]+.+$/
    old_columns = old_header && old_header.scan(column_pattern).sort
    new_columns = new_header && new_header.scan(column_pattern).sort
    if old_columns == new_columns
      return false
    end

    old_content.sub!(PATTERN, '')
    new_content = info_block + "\n" + old_content

    File.open(file_name, "wb") { |f| f.puts new_content }
    return true
  else
    return false
  end
end

.do_annotationsObject



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/annotate_sequel/model.rb', line 71

def do_annotations
  annotated = []
  get_model_files.each do |file|
    annotate_model_file(annotated, file)
  end
  if annotated.empty?
    puts "Nothing annotated"
  else
    puts "Annotated (#{annotated.length}): #{annotated.join(', ')}"
  end
end

.get_loaded_model(model_path) ⇒ Object



47
48
49
50
51
52
53
54
55
# File 'lib/annotate_sequel/model.rb', line 47

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| underscore(c.name) == model_path }
end

.get_model_class(file) ⇒ Object



41
42
43
44
45
# File 'lib/annotate_sequel/model.rb', line 41

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_filesObject



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/annotate_sequel/model.rb', line 28

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_dirObject



6
7
8
# File 'lib/annotate_sequel/model.rb', line 6

def model_dir
  @model_dir || "app/models"
end

.model_dir=(dir) ⇒ Object



10
11
12
# File 'lib/annotate_sequel/model.rb', line 10

def model_dir=(dir)
  @model_dir = dir
end

.schema_info(klass) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/annotate_sequel/model.rb', line 14

def schema_info(klass)

  info = "# Schema Info\n"
  info << "# \n"
  info << "# Table name: #{klass.table_name}\n"
  info << "# \n"

  klass.db_schema.each do |key, value|
    type = value.delete(:type)
    info << "#  #{key} :#{type}, #{value}\n"
  end
  info << "# \n"
end