module Blendris class << self attr_accessor :host, :port, :database # Specify the host to connect to for the Redis connection. def host=(host) @host = host || "localhost" $_redis_connection = nil end # Specify the port to connect to for the Redis connection. def port=(port) @port = port.to_i @port = 6379 unless (1 .. 65535).include? @port $_redis_connection = nil end # Specify the database number to use in the Redis database. def database=(index) @database = index.to_i $_redis_connection = nil end # Retrieve the connection to the current Redis database. def redis parms = { :host => @host, :port => @port, :db => @database } $_redis_connection ||= Redis.new(parms) end # This will delete all keys in the current database. Dangerous! def flushdb redis.flushdb end end # This module serves as a gateway to the Redis library. Any object # that needs to access Redis directly should include it. module RedisAccessor include Utils def redis Blendris.redis end def self.redis Blendris.redis end # Generate a key for the given model class with the given values list. # This is used to determine a new object's key in the Model.create method. def generate_key(klass, values) value_index = 0 klass.local_parameters.map do |symbol| case symbol when String then symbol when Symbol value = values[value_index] value_index += 1 raise ArgumentError.new("#{self.name} created without #{symbol}") unless value options = klass.redis_symbols[symbol.to_s] raise ArgumentError.new("#{self.name} is missing its #{symbol}") unless options subklass = options[:type] raise ArgumentError.new("#{symbol} (#{subklass.name}) cannot be used in the key") unless subklass.respond_to? :cast_to_redis subklass.cast_to_redis value, options else raise TypeError.new("only strings and symbols allowed in key definition for #{klass.name} (#{symbol.class.name})") end end.map do |segment| sanitize_key segment end.compact.join(":") end # Build a new temporary set with the given contents, yielding it to # the passed block. After the block exits, destroy the temporary set. def in_temporary_set(*contents) index = RedisInteger.new("blendris:temporary:index").increment temporary_set = RedisSet.new("blendris:temporary:set:#{index}") temporary_set << contents begin yield temporary_set ensure temporary_set.clear end self end end end