Module: ActiveHouse::PreparedStatement

Defined in:
lib/active_house/prepared_statement.rb

Class Method Summary collapse

Class Method Details

.build_condition(condition) ⇒ Object

Parameters:

  • condition (Hash)


38
39
40
41
42
43
44
# File 'lib/active_house/prepared_statement.rb', line 38

def self.build_condition(condition)
  return [condition.to_s] unless condition.is_a?(Hash)

  condition.map do |field, value|
    "#{field} #{sign_for_condition(value)} #{format_value(value)}"
  end
end

.format_fields(model_class, fields) ⇒ Object

Raises:

  • (ArgumentError)


56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/active_house/prepared_statement.rb', line 56

def self.format_fields(model_class, fields)
  raise ArgumentError, 'wrong number of arguments' if fields.empty?

  fields.map do |field|
    if field.is_a?(Symbol) && model_class._attribute_opts.key?(field)
      opts = model_class._attribute_opts.fetch(field)
      opts.key?(:select) ? "#{opts[:select]} AS #{field}" : field.to_s
    else
      field.to_s
    end
  end
end

.format_value(value) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/active_house/prepared_statement.rb', line 13

def self.format_value(value)
  return 'NULL' if value.nil?
  if value.is_a?(Array)
    "(#{value.map { |val| format_value(val) }.join(', ')})"
  elsif value.is_a?(String)
    "'#{value.gsub("'", "\\'")}'"
  elsif value.is_a?(Time)
    if value.respond_to?(:zone)
      "toDateTime('#{value.strftime('%F %T')}', '#{value.zone}')"
    else
      "toDateTime('#{value.strftime('%F %T')}')"
    end
  else
    value.to_s
  end
end

.prepare_sql(sql, *bindings) ⇒ Object

Raises:

  • (ArgumentError)


3
4
5
6
7
8
9
10
11
# File 'lib/active_house/prepared_statement.rb', line 3

def self.prepare_sql(sql, *bindings)
  return sql if bindings.empty?
  parts = sql_parts(sql)
  raise ArgumentError, 'wrong number of bindings' if parts.size != bindings.size + 1
  parts.map.with_index do |part, idx|
    value = idx + 1 > bindings.size ? nil : format_value(bindings[idx])
    "#{part}#{value}"
  end.join
end

.sign_for_condition(value) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/active_house/prepared_statement.rb', line 46

def self.sign_for_condition(value)
  if value.is_a?(Array)
    'IN'
  elsif value.nil?
    'IS'
  else
    '='
  end
end

.sql_parts(sql) ⇒ Object



30
31
32
33
34
35
# File 'lib/active_house/prepared_statement.rb', line 30

def self.sql_parts(sql)
  # TODO: except prepended with backslash or inside brackets
  parts = sql.split('?')
  parts.push('') if sql.end_with?('?')
  parts
end