class RedisArray

Attributes

key[R]

Public Class Methods

get(key) click to toggle source
# File lib/redis_array.rb, line 17
def self.get(key)
  raise NoRedisConnectionError if !defined?(@@redis) || @@redis.nil?
  RedisArray.new(key)
end
namespace() click to toggle source
# File lib/redis_array.rb, line 26
def self.namespace
  (defined?(@@namespace) && !@@namespace.nil?) ? @@namespace : "redisarray"
end
namespace=(namespace) click to toggle source
# File lib/redis_array.rb, line 22
def self.namespace=(namespace)
  @@namespace = namespace
end
namespaced_key_for(key) click to toggle source

– Storage helpers

# File lib/redis_array.rb, line 151
def self.namespaced_key_for(key)
  "#{RedisArray.namespace}:#{key}"
end
new(key = nil) click to toggle source
# File lib/redis_array.rb, line 30
def initialize(key = nil)
  @key = key.nil? ? generated_key : key
end
redis() click to toggle source
# File lib/redis_array.rb, line 13
def self.redis
  @@redis
end
redis=(redis) click to toggle source
# File lib/redis_array.rb, line 8
def self.redis=(redis)
  raise InvalidRedisInstanceError unless redis.is_a?(Redis)
  @@redis = redis
end

Public Instance Methods

+(value) click to toggle source
# File lib/redis_array.rb, line 103
def +(value)
  if value.is_a?(Array)
    value.each do |item|
      push(item)
    end
  else
    push(value)
  end
end
<<(value) click to toggle source
# File lib/redis_array.rb, line 99
def <<(value)
  push(value)
end
==(comp) click to toggle source

– Comparison In the case where comp is another RedisArray object we just compare the key We don’t want to be comparing redis values because the results will be the same if the keys match

# File lib/redis_array.rb, line 68
def ==(comp)
  comp.is_a?(RedisArray) ? @key == comp.key : to_a == comp
end
[](index) click to toggle source
# File lib/redis_array.rb, line 45
def [](index)
  value = @@redis.lindex(namespaced_key, index)
  return nil if value.nil?
  sublist?(value) ? RedisArray.new(remove_namespace(value)) : value
end
[]=(index, value) click to toggle source

– Modification

# File lib/redis_array.rb, line 82
def []=(index, value)
  value = storable_value(value)

  if index > 0 && !@@redis.exists(namespaced_key)
    index.times { @@redis.rpush(namespaced_key, "") }
  end

  llen = @@redis.llen(namespaced_key)

  if index < llen
    @@redis.lset(namespaced_key, index, value)
  else
    (index - llen).times { @@redis.rpush(namespaced_key, "") }
    @@redis.rpush(namespaced_key, value)
  end
end
all() click to toggle source
# File lib/redis_array.rb, line 51
def all
  array = @@redis.lrange(namespaced_key, 0, @@redis.llen(namespaced_key))
  array.each_with_index do |value, i|
    array[i] = RedisArray.new(remove_namespace(value)) if sublist?(value)
  end

  array
end
clear() click to toggle source
# File lib/redis_array.rb, line 146
def clear
  @@redis.del(namespaced_key)
end
count() click to toggle source
# File lib/redis_array.rb, line 60
def count
  @@redis.llen(namespaced_key)
end
delete(value) click to toggle source
# File lib/redis_array.rb, line 141
def delete(value)
  value = value.is_a?(RedisArray) ? sublist_value(value) : value
  @@redis.lrem(namespaced_key, 0, value)
end
delete_at(index) click to toggle source

Redis doesn’t support delete at index, so we’re copying the values in redis, keeping all but the index we’re removing, deleting the list, and reloading it. Due to the complexity of this call it is recommended that you do not use it.

# File lib/redis_array.rb, line 124
def delete_at(index)
  len = count
  values = @@redis.lrange(namespaced_key, 0, len-1)
  @@redis.multi do
    new_values = []

    values.each_with_index do |value, i|
      new_values << value unless i == index
    end

    @@redis.del(namespaced_key)
    new_values.each do |value|
      @@redis.rpush(namespaced_key, value)
    end
  end
end
each() { |redis_array(remove_namespace(value))| ... } click to toggle source

– Selection / Iteration

# File lib/redis_array.rb, line 35
def each
  @@redis.lrange(namespaced_key, 0, @@redis.llen(namespaced_key)).each do |value|
    if sublist?(value)
      yield RedisArray.new(remove_namespace(value))
    else
      yield value
    end
  end
end
namespaced_key() click to toggle source
# File lib/redis_array.rb, line 155
def namespaced_key
  RedisArray.namespaced_key_for(@key)
end
pop() click to toggle source
# File lib/redis_array.rb, line 117
def pop
  @@redis.ltrim(namespaced_key, 0, -2)
end
push(value) click to toggle source
# File lib/redis_array.rb, line 113
def push(value)
  @@redis.rpush(namespaced_key, storable_value(value))
end
to_a() click to toggle source

– Conversion This returns a raw, deep array

# File lib/redis_array.rb, line 74
def to_a
  array = all
  array.each_with_index do |value, i|
    array[i] = value.to_a if value.is_a?(RedisArray)
  end
end

Protected Instance Methods

determine_stored_value(value) click to toggle source
# File lib/redis_array.rb, line 177
def determine_stored_value(value)
  if value.is_a?(RedisArray)
    sublist_value(value)
  elsif value.is_a?(Array)
    list = RedisArray.new
    value.each do |subvalue|
      list << subvalue
    end

    sublist_value(list)
  else
    value.to_s
  end
end
generated_key() click to toggle source
# File lib/redis_array.rb, line 192
def generated_key
  SecureRandom.hex
end
remove_namespace(key) click to toggle source
# File lib/redis_array.rb, line 161
def remove_namespace(key)
  @@_remove_namespace_regex ||= Regexp.new("#{RedisArray.namespace}:(~>)?(.+)")
  key.match(@@_remove_namespace_regex)[2]
end
storable_value(value) click to toggle source
# File lib/redis_array.rb, line 166
def storable_value(value)
  raise ArgumentError, "The value  #{value} does not represent a list, is not a string, and cannot be made a string" unless value_storable?(value)
  determine_stored_value(value)
end
sublist?(value) click to toggle source
# File lib/redis_array.rb, line 196
def sublist?(value)
  @@_sublist_matcher = Regexp.new("^#{RedisArray.namespace}:~>")
  value.match(@@_sublist_matcher)
end
sublist_value(list) click to toggle source
# File lib/redis_array.rb, line 201
def sublist_value(list)
  "#{RedisArray.namespace}:~>#{list.key}"
end
value_storable?(value) click to toggle source
# File lib/redis_array.rb, line 171
def value_storable?(value)
  return true if value.is_a?(RedisArray) || value.is_a?(Array)
  return true if value.respond_to? :to_s
  false
end