Module: Motor::Queries::RenderSqlTemplate

Defined in:
lib/motor/queries/render_sql_template.rb

Constant Summary collapse

SECTION_OPEN_REGEXP =
/{{([#^])\s*(\w+)}}.*\z/m.freeze
VARIABLE_REGEXP =
/{{\s*(\w+)\s*}}/m.freeze

Class Method Summary collapse

Class Method Details

.build_section_close_regexp(variable_name) ⇒ Object


56
57
58
# File 'lib/motor/queries/render_sql_template.rb', line 56

def build_section_close_regexp(variable_name)
  %r{{{[#^/]s*#{Regexp.escape(variable_name)}\s*}}}m
end

.call(sql, variables) ⇒ Object


11
12
13
14
15
# File 'lib/motor/queries/render_sql_template.rb', line 11

def call(sql, variables)
  result = render_sections(sql, variables)

  interpolate_variables(result, variables)
end

.interpolate_variables(sql, variables) ⇒ Object


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/motor/queries/render_sql_template.rb', line 17

def interpolate_variables(sql, variables)
  selected_variables = []

  rendered =
    sql.gsub(VARIABLE_REGEXP) do
      variable_name = Regexp.last_match[1]

      index = selected_variables.index { |name, _| name == variable_name }
      variable_values = variables[variable_name]

      if variable_values.is_a?(Array)
        first_variable_index = selected_variables.size + 1

        variable_values.each { |value| selected_variables << [variable_name, value] } unless index

        (first_variable_index..selected_variables.size).map { |i| "$#{i}" }.join(', ')
      else
        selected_variables << [variable_name, variables[variable_name]] unless index

        "$#{selected_variables.size}"
      end
    end

  [rendered, selected_variables]
end

.render_sections(sql, variables) ⇒ Object


43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/motor/queries/render_sql_template.rb', line 43

def render_sections(sql, variables)
  sql.sub(SECTION_OPEN_REGEXP) do |e|
    variable_name = Regexp.last_match[2]
    is_negative = Regexp.last_match[1] == '^'

    _, content, rest = e.split(build_section_close_regexp(variable_name), 3)

    is_present = variables[variable_name].present?

    render_sections(is_present ^ is_negative ? content + rest.to_s : rest, variables)
  end
end