module Card::Query::CardQuery::Interpretation
Interpret CQL. Once interpreted, SQL can be generated.
Constants
- INTERPRET_METHOD
Public Instance Methods
bad_attribute!(attribute)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 69 def bad_attribute! attribute raise Error::BadQuery, "Invalid attribute: #{attribute}" end
deprecated_attribute(attribute)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 65 def deprecated_attribute attribute Rails.logger.info "Card queries no longer support #{attribute} attribute" end
interpret(clause)
click to toggle source
normalize and extract meaning from a clause @param clause [Hash, String, Integer] statement or chunk thereof
# File lib/card/query/card_query/interpretation.rb, line 14 def interpret clause normalize_clause(clause).each do |key, val| interpret_item key, val end end
interpret_as_content?(key)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 30 def interpret_as_content? key # eg "match" is both operator and attribute; # interpret as attribute when "match" is key OPERATORS.key?(key.to_s) && !Query.attributes[key] end
interpret_as_modifier?(key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 36 def interpret_as_modifier? key, val # eg when "sort" is hash, it can have subqueries # and must be interpreted like an attribute MODIFIERS.key?(key) && !val.is_a?(Hash) end
interpret_attributes(attribute, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 46 def interpret_attributes attribute, val attribute_type = Query.attributes[attribute] if (method = INTERPRET_METHOD[attribute_type]) send method, attribute, val else no_method_for_attribute_type attribute, attribute_type end end
interpret_item(key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 20 def interpret_item key, val if interpret_as_content? key interpret content: [key, val] elsif interpret_as_modifier? key, val interpret_modifier key, val else interpret_attributes key, val end end
interpret_modifier(key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 42 def interpret_modifier key, val @mods[key] = val.is_a?(Array) ? val : val.to_s end
no_method_for_attribute_type(attribute, type)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 55 def no_method_for_attribute_type attribute, type return if type == :ignore if type == :deprecated deprecated_attribute attribute else bad_attribute! attribute end end
relate(key, val, opts={})
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 80 def relate key, val, opts={} multiple = opts[:multiple].nil? ? val.is_a?(Array) : opts[:multiple] method = opts[:method] || :send if multiple relate_multi_value method, key, val else send method, key, val end end
relate_compound(key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 73 def relate_compound key, val has_multiple_values = val.is_a?(Array) && (val.first.is_a?(Array) || conjunction(val.first).present?) relate key, val, multiple: has_multiple_values end
Private Instance Methods
as_list_of_ids?(conj, key, val)
click to toggle source
the list_of_ids optimization is intended to avoid unnecessary joins and can probably be applied more broadly, but in the name of caution, we went with an initial implementation that would only apply to reference attributes (because reference_query can handle lists of values)
# File lib/card/query/card_query/interpretation.rb, line 117 def as_list_of_ids? conj, key, val (conj == :or) && key.to_s.start_with?(/refer|nest|include|link|member/) && list_of_ids?(val) end
relate_multi_value(method, key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 93 def relate_multi_value method, key, val conj = conjunction(val.first) ? conjunction(val.shift) : :and if as_list_of_ids?(conj, key, val) relate key, val, multiple: false elsif conj == current_conjunction # same conjunction as container, no need for subcondition relate_multi_value_without_subcondition method, key, val else relate_multi_value_with_subcondition key, conj, val end end
relate_multi_value_with_subcondition(key, conj, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 105 def relate_multi_value_with_subcondition key, conj, val send conj, (val.map { |v| { key => v } }) end
relate_multi_value_without_subcondition(method, key, val)
click to toggle source
# File lib/card/query/card_query/interpretation.rb, line 109 def relate_multi_value_without_subcondition method, key, val val.each { |v| send method, key, v } end