module MockRedis::SortMethod

Constants

ASCENDING_SORT
DESCENDING_SORT

Public Instance Methods

sort(key, options = {}) click to toggle source
# File lib/mock_redis/sort_method.rb, line 7
def sort(key, options = {})
  return [] if key.nil?

  enumerable = data[key]

  return [] if enumerable.nil?

  by           = options[:by]
  limit        = options[:limit] || []
  store        = options[:store]
  get_patterns = Array(options[:get])
  order        = options[:order] || 'ASC'
  direction    = order.split.first

  projected = project(enumerable, by, get_patterns)
  sorted    = sort_by(projected, direction)
  sliced    = slice(sorted, limit)

  store ? rpush(store, sliced) : sliced
end

Private Instance Methods

lookup_from_pattern(pattern, element) click to toggle source
# File lib/mock_redis/sort_method.rb, line 71
def lookup_from_pattern(pattern, element)
  key = pattern.sub('*', element)

  if (hash_parts = key.split('->')).length > 1
    hget hash_parts.first, hash_parts.last
  else
    get key
  end
end
project(enumerable, by, get_patterns) click to toggle source
# File lib/mock_redis/sort_method.rb, line 33
def project(enumerable, by, get_patterns)
  enumerable.map do |*elements|
    element = elements.last
    weight  = by ? lookup_from_pattern(by, element) : element
    value   = element

    unless get_patterns.empty?
      value = get_patterns.map do |pattern|
        pattern == '#' ? element : lookup_from_pattern(pattern, element)
      end
      value = value.first if value.length == 1
    end

    [weight, value]
  end
end
slice(sorted, limit) click to toggle source
# File lib/mock_redis/sort_method.rb, line 64
def slice(sorted, limit)
  skip = limit.first || 0
  take = limit.last || sorted.length

  sorted[skip...(skip + take)] || sorted
end
sort_by(projected, direction) click to toggle source
# File lib/mock_redis/sort_method.rb, line 50
def sort_by(projected, direction)
  sorter =
    case direction.upcase
    when 'DESC'
      DESCENDING_SORT
    when 'ASC', 'ALPHA'
      ASCENDING_SORT
    else
      raise "Invalid direction '#{direction}'"
    end

  projected.sort(&sorter).map(&:last)
end