Class: CacheBack::ConditionsParser

Inherits:
Object
  • Object
show all
Defined in:
lib/cache_back/conditions_parser.rb

Constant Summary collapse

AND =
/\s+AND\s+/i
TABLE_AND_COLUMN =

Matches: ‘users`.id, `users`.`id`, users.id, id

/(?:(?:`|")?(\w+)(?:`|")?\.)?(?:`|")?(\w+)(?:`|")?/
VALUE =

Matches: 123, ?, ‘123’, ‘12”3’

/'?(\d+|\?|(?:(?:[^']|'')*))'?/
KEY_EQ_VALUE =

Matches: KEY = VALUE, (KEY = VALUE), ()(KEY = VALUE))

/^[\(\s]*#{TABLE_AND_COLUMN}\s+=\s+#{VALUE}[\)\s]*$/

Instance Method Summary collapse

Constructor Details

#initialize(model_class) ⇒ ConditionsParser

Returns a new instance of ConditionsParser.



3
4
5
# File 'lib/cache_back/conditions_parser.rb', line 3

def initialize(model_class)
  @model_class = model_class
end

Instance Method Details

#attribute_value_pairs(options) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/cache_back/conditions_parser.rb', line 7

def attribute_value_pairs(options)
  #pulls out the conditions from each hash
  condition_fragments = [options[:conditions]]

  #add the scope to the mix
  if scope = @model_class.send(:scope, :find)
    condition_fragments << scope[:conditions]
  end

  #add the type if we are on STI
  condition_fragments << {:type => @model_class.name} if @model_class.finder_needs_type_condition?

  condition_fragments.compact!

  #parses each conditions fragment but bails if one of the did not parse
  attributes_fragments = condition_fragments.map do |condition_fragment|
    attributes_fragment = attributes_for_conditions(condition_fragment)
    return nil unless attributes_fragment
    attributes_fragment
  end

  #merges the hashes but bails if there is an overlap
  attributes = attributes_fragments.inject({}) do |memo, attributes_fragment|
    attributes_fragment.each do |attribute, value|
      return nil if memo.has_key?(attribute)
      memo[attribute] = value
    end
    memo
  end

  attributes.keys.sort.map { |attribute| [attribute.to_sym, attributes[attribute]] }
end

#attributes_for_conditions(conditions) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cache_back/conditions_parser.rb', line 40

def attributes_for_conditions(conditions)
  pairs = case conditions
    when Hash
      return conditions.stringify_keys
    when String
      parse_indices_from_condition(conditions)
    when Array
      parse_indices_from_condition(*conditions)
    when NilClass
      []
  end

  return nil unless pairs

  pairs.inject({}) do |memo, pair|
    return nil if memo.has_key?(pair[0])
    memo[pair[0]] = pair[1]
    memo
  end
end

#parse_indices_from_condition(conditions = '', *values) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/cache_back/conditions_parser.rb', line 66

def parse_indices_from_condition(conditions = '', *values)
  values = values.dup
  conditions.split(AND).inject([]) do |indices, condition|
    matched, table_name, column_name, sql_value = *(KEY_EQ_VALUE.match(condition))
    if matched
      value = sql_value == '?' ? values.shift : @model_class.columns_hash[column_name].type_cast(sql_value)
      indices << [column_name, value]
    else
      return nil
    end
  end
end