module ALD::API::Conditioned
Internal: used by Collection
classes to work with special conditions in where
.
Requires @conditions to be the instance’s condition Hash.
Constants
- RANGE_REGEX
Internal: A regex to determine if a range condition is specifying a range.
Public Instance Methods
Public: Filter the Collection’s data. See the documentation on the individual classes for more information.
# File lib/ALD/conditioned.rb, line 11 def where(conditions) return self if conditions.nil? || conditions.empty? new_conditions = merge_conditions(conditions) if initialized? && Collection::LocalFilter.can_apply?(conditions, self.class::LOCAL_CONDITIONS) self.class::new( @api, new_conditions, Collection::LocalFilter.apply_conditions(@data, conditions) ) else self.class::new(@api, new_conditions) end end
Private Instance Methods
Internal: The HTTP query conditions for queries for an array of values for the given conditions.
conds - an Array of Strings, containing the condition names to handle
Returns a Hash with the query parameters matching the instance’s values on the specified conditions, or an empty Hash.
# File lib/ALD/conditioned.rb, line 74 def array_queries(conds) Hash[ present_conditions(conds).map { |cond| [cond, @conditions[cond.to_sym].join(',')] } ] end
Internal: The HTTP query conditions for exact queries for a set of given conditions.
conds - an Array of Strings, containing the condition names to handle
Returns a Hash with the query parameters matching the instance’s values on the specified conditions, or an empty Hash, if there are none.
# File lib/ALD/conditioned.rb, line 61 def exact_queries(conds) Hash[ present_conditions(conds).map { |cond| [cond, @conditions[cond.to_sym]] } ] end
Internal: Merge new conditions with the current ones.
conditions - the new condition Hash to merge
Returns the merged Hash
Raises ArgumentError if the conditions are incompatible
# File lib/ALD/conditioned.rb, line 134 def merge_conditions(conditions) @conditions.merge(conditions) do |key, old_value, new_value| if self.class::RANGE_CONDITIONS.include?(key.to_s) merge_ranges(key, old_value, new_value) # handle merging for cases like 'downloads >= 5' and 'downloads <= 9' etc. elsif self.class::ARRAY_CONDITIONS.include?(key.to_s) old_value + new_value elsif key == :range # not a "range condition" in the sense used above range_offset(new_value) elsif key == :sort new_value # enable re-sorting else raise ArgumentError # for other overwrites fail! end end end
Internal: Handle condition conflicts for range conditions. Used by where
.
key - the Symbol key whose range is merged old - the old range condition value new - the new range condition value to be applied on top of the old one
Returns the value that should be used in the merged conditions.
Raises ArgumentError if the conflict cannot be resolved.
# File lib/ALD/conditioned.rb, line 162 def merge_ranges(key, old, new) constraints = [new, old] data = constraints.map do |c| match = RANGE_REGEX.match(c) if match.nil? [nil, c] elsif key == :version [match[1], Semantic::Version.new(match[2])] else [match[1], match[2]] end end ops, values = data.map(&:first), data.map(&:last) if ops[0] != ops[1] # one min, one max OR one min/max, one exact constraints # => keep both elsif ops.none?(&:'nil?') # two range constraints of same type ops[0] == '>=' ? ">= #{values.max.to_s}" : "<= #{values.min.to_s}" else # two exact values if constraints[0].strip == constraints[1].strip # if both are the same, just keep one constraints[0] else # otherwise this can't be good - throw an error raise ArgumentError end end end
Internal: Get the subset of conditions that are present on the instance
conds - an Array of Strings, containing the condition names to check
Returns an Array of Strings with a subset of the given conds, namely those that are present on @conditions.
# File lib/ALD/conditioned.rb, line 123 def present_conditions(conds) conds.select { |cond| @conditions.key?(cond.to_sym) } end
Internal: The HTTP query conditions for queries with conditions that allow specifying a range of values.
conds - an Array of Strings, containing the condition names to handle
Returns a Hash with the query parameters matching the instance’s values on the specified conditions, or an empty Hash.
# File lib/ALD/conditioned.rb, line 101 def range_condition_queries(conds) Hash[ present_conditions(conds).map { |cond| fields = @conditions[cond.to_sym].is_a?(Array) ? @conditions[cond.to_sym] : [@conditions[cond.to_sym]] fields.map do |field| match = RANGE_REGEX.match(field) if match.nil? # just a specific field [cond, field] else # min or max ["#{cond}-#{match[1] == '>=' ? 'min' : 'max'}", match[2]] end end }.flatten(1) ] end
Internal: Compute an absolute Range from a given relative Range. As ranges specified in where
are relative to this collection, they must be transformed to absolute ranges before being passed to ::new.
new_range - the relative Range to transform
Returns the absolute Range.
Raises ArgumentError if the relative Range does not fit into this collection’s Range.
# File lib/ALD/conditioned.rb, line 201 def range_offset(new_range) if @conditions[:range].nil? min, max = 0, Float::Infinity else min, max = @conditions[:range].min, @conditions[:range].max end new_min = min + new_range.min new_max = new_min + new_range.max - new_range.min # == new_min + new_range.size - 1 raise ArgumentError if new_min > max || new_max > max (new_min..new_max) end
Internal: The HTTP query conditions for the range specified in the instance’s conditions.
Returns a Hash, that contains the query parameters matching the range specified in the conditions, or an empty Hash if there is no range specified.
# File lib/ALD/conditioned.rb, line 34 def range_query data = {} if @conditions.key?(:range) data['start'] = @conditions[:range].min data['count'] = @conditions[:range].max - @conditions[:range].min + 1 end data end
Internal: The HTTP query conditions for the sorting specified in the instance’s conditions.
Returns a Hash containing the query parameters matching the specified sorting, or an empty Hash if there’s no sorting specified.
# File lib/ALD/conditioned.rb, line 48 def sort_query Hash[ present_conditions(%w[sort]).map { |cond| [cond, @conditions[cond.to_sym].map { |k, dir| "#{dir == :desc ? '-' : ''}#{k}" }.join(',')] } ] end
Internal: The HTTP query conditions for queries with conditions that can be switched on, off or indeterminate.
conds - an Array of Strings, containing the condition names to handle
Returns a Hash with the query parameters matching the instance’s values on the specified conditions, or an empty Hash.
# File lib/ALD/conditioned.rb, line 87 def switch_queries(conds) map = {true => 'true', false => 'false', nil => 'both'} Hash[ present_conditions(conds).map { |cond| [cond, map[@conditions[cond.to_sym]]] } ] end