module ALD::API::Conditioned
used by Collection classes to work with special conditions in #where.
Requires @conditions to be the instance's condition Hash.
Public
↑ topPublic Instance Methods
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
Internal
↑ topConstants
- RANGE_REGEX
A regex to determine if a range condition is specifying a range.
Private Instance Methods
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¶ ↑
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
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¶ ↑
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
Merge new conditions with the current ones.
- conditions
-
the new condition Hash to merge
Returns¶ ↑
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
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¶ ↑
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
Get the subset of conditions that are present on the instance
- conds
-
an Array of Strings, containing the condition names to check
Returns¶ ↑
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
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¶ ↑
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
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¶ ↑
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
The HTTP query conditions for the range specified in the instance's conditions.
Returns¶ ↑
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
The HTTP query conditions for the sorting specified in the instance's conditions.
Returns¶ ↑
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
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¶ ↑
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