module ALD::API::Collection::LocalFilter

Used by ItemCollection/UserCollection#where to filter data locally if possible. All methods are module methods.

Internal

↑ top

Public Class Methods

apply_conditions(data, conditions) click to toggle source

Apply certain conditions on given data. This is a wrapper method that calls ::filter, ::sort (if necessary) and applies a :range condition (if specified).

data

an Array of Hashes representing the entries to apply conditions upon

conditions

the Hash of conditions to apply

Returns

Returns the modified data Array.

Raises ArgumentError if the conditions cannot be applied. This can be avoided by passing them to ::can_apply? beforehand.

# File lib/ALD/local_filter.rb, line 21
def self.apply_conditions(data, conditions)
  data = filter(data, conditions)
  data = sort(data, conditions[:sort])  if conditions.key?(:sort)
  data = data.slice(conditions[:range]) if conditions.key?(:range)
  data
end
can_apply?(conditions, local_keys) click to toggle source

Test if the given filter, sort and range conditions can be applied locally or need a request to the server.

conditions

a Hash of conditions to test

local_keys

an Array of Strings or Symbols, containing the key names that are available locally Related: ALD::API::CollectionEntry.initialized_attributes

Returns

Returns a Boolean; true if local application is possible, false otherwise

# File lib/ALD/local_filter.rb, line 38
def self.can_apply?(conditions, local_keys)
  local_keys.map!(&:to_sym) # symbolize keys

  conditions.all? do |key, value|
    if key == :sort
      sort_criteria(value).all? { |c| local_keys.include?(c) }
    else
      local_keys.include?(key) || key == :range # range is always supported
    end
  end
end
filter(data, conditions) click to toggle source

Filter the given data locally. This does not support range or switch conditions. Array conditions also only work if the values are exactly the same, i.e. the same entries in the same order.

data

an Array of Hashes representing the entries to filter

conditions

a Hash of conditions to filter for

Returns

Returns the filtered data array

Raises ArgumentError if a filter is detected that cannot be handled locally. This can be prevented by calling ::can_filter? first.

# File lib/ALD/local_filter.rb, line 61
def self.filter(data, conditions)
  data.select do |entry|
    conditions.all? do |key, value|
      if [:sort, :range].include?(key)
        true # must be done somewhere else
      elsif entry.key?(key.to_s) # should be a locally available key
        entry[key.to_s] == value
      else
        raise ArgumentError  # should be prevented by can_filter?
      end
    end
  end
end
sort(data, sort) click to toggle source

Sort the given data locally

data

the Array of Hashes representing entries

sort

either: a Hash, associating sorting criteria (symbols) to sorting direction (:asc ord :desc); or an Array of Symbols representing sorting criteria (direction defaults to :asc)

Returns

Returns the sorted data array

# File lib/ALD/local_filter.rb, line 83
def self.sort(data, sort)
  sort = to_sort_hash(sort)
  data.sort do |a, b|
    sortings(sort, a, b).find { |s| s != 0 } || 0 # use highest-priority (i.e. first) sorting info != 0
  end
end

Private Class Methods

sort_criteria(sort) click to toggle source

The inverse of ::to_sort_hash.

sort

an Array or Hash, in the format described in ::sort

Returns

Returns an Array, in the format described in ::sort.

# File lib/ALD/local_filter.rb, line 129
def self.sort_criteria(sort)
  sort.is_a?(Hash) ? sort.keys : sort
end
sortings(sort, a, b) click to toggle source

Get the sort order for given criteria.

sort

a Hash as described in ::sort a, b - the Hashes to compare

Returns

Returns an Array of Integers (-1, 0, +1), where each represents the sort order for one of the sort keys.

# File lib/ALD/local_filter.rb, line 97
def self.sortings(sort, a, b)
  sort.map do |key, dir|
    key = key.to_s
    if key == 'version'
      result = Semantic::Version.new(a[key]) <=> Semantic::Version.new(b[key])
    else
      result = a[key] <=> b[key]
    end
    dir == :asc ? result : -result
  end
end
to_sort_hash(sort) click to toggle source

Create a sorting Hash from an Array.

sort

a Hash or Array, in the format described in ::sort

Returns

Returns a Hash, in the format described in ::sort.

# File lib/ALD/local_filter.rb, line 115
def self.to_sort_hash(sort)
  if sort.is_a?(Hash)
    sort
  else
    Hash[sort.map { |c| [c, :asc] }]
  end
end