class Cuprum::Collections::Basic::Query

Concrete implementation of a Query for an in-memory collection.

Attributes

data[R]
filters[R]

Public Class Methods

new(data) click to toggle source

@param data [Array<Hash>] The current data in the collection. Should be an

Array of Hashes, each of which represents one item in the collection.
Calls superclass method Cuprum::Collections::Query::new
# File lib/cuprum/collections/basic/query.rb, line 14
def initialize(data)
  super()

  @data    = data
  @filters = []
  @limit   = nil
  @offset  = nil
  @order   = {}
end

Public Instance Methods

each(&block) click to toggle source

Iterates through the collection, yielding each item matching the query.

If the query has criteria, only items matching each criterion will be processed; these are the matching items. If the query does not have any criteria, all items in the collection will be processed.

If the query has an ordering, the matching items are then sorted in the specified order. If the query does not have an order, the matching items will be processed in the order they appear in the collection.

Finally, the limit and/or offset will be applied to the sorted matching items. Each sorted, matching item starting at the offset and up to the given limit of items will be yielded to the block.

@overload each

@return [Enumerator] an enumerator that iterates over the sorted,
  matching items within the given offset and limit.

@overload each(&block)

@yield [Object] Each sorted, matching item within the given offset and
  limit is yielded to the block.

@see limit @see offset @see order @see to_a @see where

# File lib/cuprum/collections/basic/query.rb, line 51
def each(&block)
  return enum_for(:each) unless block_given?

  filtered_data.each(&block)
end
exists?() click to toggle source

Checks for the presence of collection items matching the query.

If the query has criteria, then only items matching each criterion will be processed; these are the matching items. If there is at least one matching item, exists will return true; otherwise, it will return false.

@return [Boolean] true if any items match the query; otherwise false.

# File lib/cuprum/collections/basic/query.rb, line 64
def exists?
  data.any? do |item|
    @filters.all? { |filter| filter.call(item) }
  end
end
to_a() click to toggle source

Returns an array containing each collection item matching the query.

If the query has criteria, only items matching each criterion will be processed; these are the matching items. If the query does not have any criteria, all items in the collection will be processed.

If the query has an ordering, the matching items are then sorted in the specified order. If the query does not have an order, the matching items will be processed in the order they appear in the collection.

Finally, the limit and/or offset will be applied to the sorted matching items. Each sorted, matching item starting at the offset and up to the given limit of items will be returned in the array.

@return [Array] The sorted, matching items within the given offset and

limit.

@see each @see limit @see offset @see order @see where

# File lib/cuprum/collections/basic/query.rb, line 92
def to_a
  filtered_data
end

Protected Instance Methods

query_builder() click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 98
def query_builder
  Cuprum::Collections::Basic::QueryBuilder.new(self)
end
reset!() click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 102
def reset!
  @filtered_data = nil

  self
end
with_filters(filters) click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 108
def with_filters(filters)
  @filters += filters

  self
end

Private Instance Methods

apply_filters(data) click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 120
def apply_filters(data)
  data.select do |item|
    @filters.all? { |filter| filter.call(item) }
  end
end
apply_limit_offset(data) click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 126
def apply_limit_offset(data)
  return data[@offset...(@offset + @limit)] || [] if @limit && @offset
  return data[0...@limit] if @limit

  return data[@offset..] || [] if @offset

  data
end
apply_order(data) click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 135
def apply_order(data)
  return data if @order.empty?

  data.sort do |u, v|
    @order.reduce(0) do |memo, (attribute, direction)|
      next memo unless memo.zero?

      attr_name = attribute.to_s

      cmp = u[attr_name] <=> v[attr_name]

      direction == :asc ? cmp : -cmp
    end
  end
end
filtered_data() click to toggle source
# File lib/cuprum/collections/basic/query.rb, line 151
def filtered_data
  @filtered_data ||=
    data
      .yield_self { |ary| apply_filters(ary) }
      .yield_self { |ary| apply_order(ary) }
      .yield_self { |ary| apply_limit_offset(ary) }
      .map(&:dup)
end