Sha256: 56bdea3783c1145b63802d7f3e4289ca994152451cceb862bd768318864ccc95

Contents?: true

Size: 1.93 KB

Versions: 37

Compression:

Stored size: 1.93 KB

Contents

require 'mock_redis/assertions'

class MockRedis
  module SortMethod
    include Assertions

    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

    ASCENDING_SORT  = proc { |a, b| a.first <=> b.first }
    DESCENDING_SORT = proc { |a, b| b.first <=> a.first }

    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

    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

    def slice(sorted, limit)
      skip = limit.first || 0
      take = limit.last || sorted.length

      sorted[skip...(skip + take)] || sorted
    end

    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
  end
end

Version data entries

37 entries across 37 versions & 1 rubygems

Version Path
mock_redis-0.46.0 lib/mock_redis/sort_method.rb
mock_redis-0.45.0 lib/mock_redis/sort_method.rb
mock_redis-0.44.0 lib/mock_redis/sort_method.rb
mock_redis-0.43.0 lib/mock_redis/sort_method.rb
mock_redis-0.42.0 lib/mock_redis/sort_method.rb
mock_redis-0.41.0 lib/mock_redis/sort_method.rb
mock_redis-0.40.0 lib/mock_redis/sort_method.rb
mock_redis-0.39.0 lib/mock_redis/sort_method.rb
mock_redis-0.38.0 lib/mock_redis/sort_method.rb
mock_redis-0.37.0 lib/mock_redis/sort_method.rb
mock_redis-0.36.0 lib/mock_redis/sort_method.rb
mock_redis-0.35.0 lib/mock_redis/sort_method.rb
mock_redis-0.34.0 lib/mock_redis/sort_method.rb
mock_redis-0.33.0 lib/mock_redis/sort_method.rb
mock_redis-0.32.0 lib/mock_redis/sort_method.rb
mock_redis-0.31.0 lib/mock_redis/sort_method.rb
mock_redis-0.30.0 lib/mock_redis/sort_method.rb
mock_redis-0.29.0 lib/mock_redis/sort_method.rb
mock_redis-0.28.0 lib/mock_redis/sort_method.rb
mock_redis-0.27.3 lib/mock_redis/sort_method.rb