module Clearly::Query::Compose::Range
Methods for composing range queries.
Public Instance Methods
parse_interval(value)
click to toggle source
Parse an interval. @param [String] value @return [Array<String>] captures
# File lib/clearly/query/compose/range.rb, line 12 def parse_interval(value) range_regex = /(\[|\()(.*),(.*)(\)|\])/i matches = value.match(range_regex) fail Clearly::Query::QueryArgumentError.new( "range string must be in the form (|[.*,.*]|), got '#{value}'") unless matches captures = matches.captures { start_include: captures[0] == '[', start_value: captures[1], end_value: captures[2], end_include: captures[3] == ']' } end
parse_range(hash)
click to toggle source
Validate
a range. @param [Hash] hash @return [Hash]
# File lib/clearly/query/compose/range.rb, line 30 def parse_range(hash) unless hash.is_a?(Hash) fail Clearly::Query::QueryArgumentError.new( "range filter must be {'from': 'value', 'to': 'value'} " + "or {'interval': '(|[.*,.*]|)'} got '#{hash}'", {hash: hash}) end from = hash[:from] to = hash[:to] interval = hash[:interval] if !from.blank? && !to.blank? && !interval.blank? fail Clearly::Query::QueryArgumentError.new( "range filter must use either ('from' and 'to') or ('interval'), not both", {hash: hash}) elsif from.blank? && !to.blank? fail Clearly::Query::QueryArgumentError.new( "range filter missing 'from'", {hash: hash}) elsif !from.blank? && to.blank? fail Clearly::Query::QueryArgumentError.new( "range filter missing 'to'", {hash: hash}) elsif !from.blank? && !to.blank? parse_interval("[#{from},#{to})") elsif !interval.blank? parse_interval(interval) else fail Clearly::Query::QueryArgumentError.new( "range filter did not contain ('from' and 'to') or ('interval'), got '#{hash}'", {hash: hash}) end end
Private Instance Methods
compose_not_range_node(node, value)
click to toggle source
Create NOT IN condition using from (inclusive) and to (exclusive). @param [Arel::Nodes::Node, Arel::Attributes::Attribute, String] node @param [Object] value @return [Arel::Nodes::Node] condition
# File lib/clearly/query/compose/range.rb, line 91 def compose_not_range_node(node, value) validate_node_or_attribute(node) range_info = parse_range(value) # build using gt, lt, gteq, lteq if range_info[:start_include] start_condition = node.lt(range_info[:start_value]) else start_condition = node.lteq(range_info[:start_value]) end if range_info[:end_include] end_condition = node.gt(range_info[:end_value]) else end_condition = node.gteq(range_info[:end_value]) end start_condition.or(end_condition) end
compose_range_node(node, value)
click to toggle source
Create IN condition using from (inclusive) and to (exclusive). @param [Arel::Nodes::Node, Arel::Attributes::Attribute, String] node @param [Object] value @return [Arel::Nodes::Node] condition
# File lib/clearly/query/compose/range.rb, line 67 def compose_range_node(node, value) validate_node_or_attribute(node) range_info = parse_range(value) # build using gt, lt, gteq, lteq if range_info[:start_include] start_condition = node.gteq(range_info[:start_value]) else start_condition = node.gt(range_info[:start_value]) end if range_info[:end_include] end_condition = node.lteq(range_info[:end_value]) else end_condition = node.lt(range_info[:end_value]) end start_condition.and(end_condition) end