Sha256: c0b7dde28af3ae4479c71d2741cb07efbcb05bf0aaad1d2019c37c7201af9aec

Contents?: true

Size: 1.95 KB

Versions: 21

Compression:

Stored size: 1.95 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.new { |a, b| a.first <=> b.first }
    DESCENDING_SORT = Proc.new { |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

        if get_patterns.length > 0
          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

21 entries across 21 versions & 1 rubygems

Version Path
mock_redis-0.14.1 lib/mock_redis/sort_method.rb
mock_redis-0.14.0 lib/mock_redis/sort_method.rb
mock_redis-0.13.2 lib/mock_redis/sort_method.rb
mock_redis-0.13.1 lib/mock_redis/sort_method.rb
mock_redis-0.13.0 lib/mock_redis/sort_method.rb
mock_redis-0.12.1 lib/mock_redis/sort_method.rb
mock_redis-0.12.0 lib/mock_redis/sort_method.rb
mock_redis-0.11.0 lib/mock_redis/sort_method.rb
mock_redis-0.10.0 lib/mock_redis/sort_method.rb
mock_redis-0.9.0 lib/mock_redis/sort_method.rb
mock_redis-0.8.2 lib/mock_redis/sort_method.rb
mock_redis-0.8.1 lib/mock_redis/sort_method.rb
mock_redis-0.8.0 lib/mock_redis/sort_method.rb
mock_redis-0.7.0 lib/mock_redis/sort_method.rb
mock_redis-0.6.6 lib/mock_redis/sort_method.rb
mock_redis-0.6.5 lib/mock_redis/sort_method.rb
mock_redis-0.6.4 lib/mock_redis/sort_method.rb
mock_redis-0.6.3 lib/mock_redis/sort_method.rb
mock_redis-0.6.2 lib/mock_redis/sort_method.rb
mock_redis-0.6.1 lib/mock_redis/sort_method.rb