Class: SQLtorial::QueryToMD

Inherits:
Object
  • Object
show all
Defined in:
lib/sqltorial/query_to_md.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query, directives, row_limit = 10) ⇒ QueryToMD

Returns a new instance of QueryToMD.



7
8
9
10
11
12
13
14
# File 'lib/sqltorial/query_to_md.rb', line 7

def initialize(query, directives, row_limit = 10)
  @query = query
  @validation_directives, @other_directives = directives.partition { |d| d.respond_to?(:validate) }
  @row_limit = row_limit
  @other_directives.each do |directive|
    directive.alter(self)
  end
end

Instance Attribute Details

#queryObject

Returns the value of attribute query.



6
7
8
# File 'lib/sqltorial/query_to_md.rb', line 6

def query
  @query
end

#row_limitObject

Returns the value of attribute row_limit.



6
7
8
# File 'lib/sqltorial/query_to_md.rb', line 6

def row_limit
  @row_limit
end

#validation_directivesObject (readonly)

Returns the value of attribute validation_directives.



5
6
7
# File 'lib/sqltorial/query_to_md.rb', line 5

def validation_directives
  @validation_directives
end

Instance Method Details

#additional_headersObject



52
53
54
# File 'lib/sqltorial/query_to_md.rb', line 52

def additional_headers
  validation_directives.empty? ? [] : [:valid_row]
end

#allObject



44
45
46
47
48
49
50
# File 'lib/sqltorial/query_to_md.rb', line 44

def all
  @all ||= begin
    q = query.from_self
    q = q.limit(row_limit)
    q.all
  end
end

#cacheObject



138
139
140
# File 'lib/sqltorial/query_to_md.rb', line 138

def cache
  @cache ||= QueryCache.new(self)
end

#commatize(str) ⇒ Object



133
134
135
136
# File 'lib/sqltorial/query_to_md.rb', line 133

def commatize(str)
  return str unless str =~ /^\d+$/
  str.reverse.chars.each_slice(3).map(&:join).join(',').reverse
end

#countObject



40
41
42
# File 'lib/sqltorial/query_to_md.rb', line 40

def count
  @count ||= query.from_self.count
end

#get_mdObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sqltorial/query_to_md.rb', line 24

def get_md
  return "**No results found.**" if all.empty?
  output = []
  output << "Found #{count} results."
  if count > row_limit
    output.last << "  Displaying first #{row_limit}."
  end
  output << ""
  output << tableize(all.first.keys + additional_headers)
  output << tableize(orientations_for(all))
  output_rows.each do |row|
    output << tableize(process(row.values))
  end
  output.join("\n") + "\n\n"
end

#make_processorsObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/sqltorial/query_to_md.rb', line 85

def make_processors
  output_rows.first.map do |name, column|
    if name.to_s.end_with?('_id')
      Proc.new do |column|
        column.to_s.chomp
      end
    else
      case column
      when Float, BigDecimal
        Proc.new do |column|
          sprintf("%.02f", column)
        end
      when Numeric, Fixnum
        Proc.new do |column|
          commatize(column.to_s)
        end
      else
        Proc.new do |column|
          column.to_s.chomp
        end
      end
    end
  end
end

#orientations_for(dataset) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/sqltorial/query_to_md.rb', line 110

def orientations_for(dataset)
  widths = widths_for(dataset)
  dataset.first.map.with_index do |(_, value), index|
    case value
    when Numeric, Fixnum, Float
      widths[index][-1] = ":"
    else
      widths[index][0] = ":"
    end
    widths[index]
  end
end

#output_rowsObject



56
57
58
59
60
61
62
63
64
# File 'lib/sqltorial/query_to_md.rb', line 56

def output_rows
  rows = all[0...row_limit]
  return rows if validation_directives.empty?

  rows.map do |row|
    row[:valid_row] = validation_directives.all? { |d| d.validate(row) } ? 'Y' : 'N'
    row
  end
end

#process(columns) ⇒ Object



74
75
76
77
78
79
80
81
82
83
# File 'lib/sqltorial/query_to_md.rb', line 74

def process(columns)
  processors.map.with_index do |processor, index|
    value = columns[index]
    if processor
      processor.call(value)
    else
      value
    end
  end
end

#processorsObject



70
71
72
# File 'lib/sqltorial/query_to_md.rb', line 70

def processors
  @processors ||= make_processors
end

#tableize(columns) ⇒ Object



66
67
68
# File 'lib/sqltorial/query_to_md.rb', line 66

def tableize(columns)
  "| #{columns.join(" | ")} |"
end

#to_mdObject



20
21
22
# File 'lib/sqltorial/query_to_md.rb', line 20

def to_md
  cache.to_md
end

#widths_for(dataset) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/sqltorial/query_to_md.rb', line 123

def widths_for(dataset)
  widths = [0] * dataset.first.length
  dataset.each do |row|
    widths = row.map.with_index do |value, index|
      [value.to_s.length, widths[index]].max
    end
  end
  widths.map { |width| '-' * width }
end