module Familia::ClassMethods

Auto-extended into a class that includes Familia

Attributes

parent[RW]

Public Instance Methods

all(suffix=:object) click to toggle source
# File lib/familia/object.rb, line 167
def all(suffix=:object)
  # objects that could not be parsed will be nil
  keys(suffix).collect { |k| from_key(k) }.compact 
end
any?(filter='*') click to toggle source
# File lib/familia/object.rb, line 171
def any?(filter='*')
  size(filter) > 0
end
class_redis_objects() click to toggle source
# File lib/familia/object.rb, line 199
def class_redis_objects
  @class_redis_objects ||= {}
  @class_redis_objects
end
class_redis_objects?(name) click to toggle source
# File lib/familia/object.rb, line 203
def class_redis_objects? name
  class_redis_objects.has_key? name.to_s.to_sym
end
class_redis_objects_order() click to toggle source
# File lib/familia/object.rb, line 195
def class_redis_objects_order
  @class_redis_objects_order ||= []
  @class_redis_objects_order
end
create(*args) click to toggle source
# File lib/familia/object.rb, line 217
def create *args
  me = from_array *args
  raise "#{self} exists: #{me.rediskey}" if me.exists?
  me.save
  me
end
db(v=nil) click to toggle source
# File lib/familia/object.rb, line 138
def db v=nil
  @db = v unless v.nil?
  @db || (parent ? parent.db : nil)
end
db=(db) click to toggle source
# File lib/familia/object.rb, line 142
def db=(db) @db = db end
destroy!(idx, suffix=:object) click to toggle source
# File lib/familia/object.rb, line 272
def destroy! idx, suffix=:object
  ret = Familia.redis(self.uri).del rediskey(idx, suffix)
  Familia.trace :DELETED, Familia.redis(self.uri), "#{rediskey(idx, suffix)}: #{ret}", caller if Familia.debug?
  ret
end
exists?(idx, suffix=:object) click to toggle source
# File lib/familia/object.rb, line 265
def exists? idx, suffix=:object
  return false if idx.to_s.empty?
  objkey = rediskey idx, suffix
  ret = Familia.redis(self.uri).exists objkey
  Familia.trace :EXISTS, Familia.redis(self.uri), "#{rediskey(idx, suffix)} #{ret}", caller if Familia.debug?
  ret
end
expand(short_idx, suffix=self.suffix) click to toggle source
# File lib/familia/object.rb, line 289
def expand(short_idx, suffix=self.suffix)
  expand_key = Familia.rediskey(self.prefix, "#{short_idx}*", suffix)
  Familia.trace :EXPAND, Familia.redis(self.uri), expand_key, caller.first if Familia.debug?
  list = Familia.redis(self.uri).keys expand_key
  case list.size
  when 0
    nil
  when 1 
    matches = list.first.match(/\A#{Familia.rediskey(prefix)}\:(.+?)\:#{suffix}/) || []
    matches[1]
  else
    raise Familia::NonUniqueKey, "Short key returned more than 1 match" 
  end
end
extended(obj) click to toggle source
# File lib/familia/object.rb, line 64
def extended(obj)
  obj.db = self.db
  obj.ttl = self.ttl
  obj.uri = self.uri
  obj.parent = self
  obj.class_zset :instances, :class => obj, :reference => true
  Familia.classes << obj
end
find(suffix='*') click to toggle source
# File lib/familia/object.rb, line 277
def find suffix='*'
  list = Familia.redis(self.uri).keys(rediskey('*', suffix)) || []
end
flushdb() click to toggle source
# File lib/familia/object.rb, line 160
def flushdb
  Familia.info "flushing #{uri}"
  redis.flushdb
end
from_index(idx) click to toggle source

Note idx needs to be an appropriate index for the given class. If the index is multi-value it must be passed as an Array in the proper order. Does not call save.

# File lib/familia/object.rb, line 247
def from_index idx
  obj = new 
  obj.index = idx
  obj
end
from_key(objkey) click to toggle source
# File lib/familia/object.rb, line 252
def from_key objkey
  raise ArgumentError, "Empty key" if objkey.to_s.empty?    
  Familia.trace :LOAD, Familia.redis(self.uri), objkey, caller if Familia.debug?
  obj = Familia::String.new objkey, :class => self
  obj.value
end
from_redis(idx, suffix=:object) click to toggle source
# File lib/familia/object.rb, line 258
def from_redis idx, suffix=:object
  return nil if idx.to_s.empty?
  objkey = rediskey idx, suffix
  #Familia.trace :FROMREDIS, Familia.redis(self.uri), objkey, caller.first if Familia.debug?
  me = from_key objkey
  me
end
from_redisdump(dump) click to toggle source
# File lib/familia/object.rb, line 129
def from_redisdump dump
  dump # todo
end
host(host=nil) click to toggle source
# File lib/familia/object.rb, line 143
def host(host=nil) @host = host if host; @host end
host=(host) click to toggle source
# File lib/familia/object.rb, line 144
def host=(host) @host = host end
index(i=nil, &blk) click to toggle source
TODO: grab db, ttl, uri from parent

def parent=(a) @parent = a end def parent(a=nil) @parent = a if a; @parent end

# File lib/familia/object.rb, line 187
def index(i=nil, &blk) 
  @index = i || blk if i || !blk.nil?
  @index ||= Familia.index
  @index
end
inherited(obj) click to toggle source
Calls superclass method
# File lib/familia/object.rb, line 55
def inherited(obj)
  obj.db = self.db
  obj.uri = self.uri
  obj.ttl = self.ttl
  obj.parent = self
  obj.class_zset :instances, :class => obj, :reference => true
  Familia.classes << obj
  super(obj)
end
install_class_redis_object(name, klass, opts) click to toggle source

Creates a class method called name that returns an instance of the RedisObject klass

# File lib/familia/object.rb, line 103
def install_class_redis_object name, klass, opts
  raise ArgumentError, "Name is blank" if name.to_s.empty?
  name = name.to_s.to_sym
  opts = opts.nil? ? {} : opts.clone
  opts[:parent] = self unless opts.has_key?(:parent)
  # TODO: investigate using metaclass.redis_objects
  class_redis_objects_order << name
  class_redis_objects[name] = OpenStruct.new
  class_redis_objects[name].name = name
  class_redis_objects[name].klass = klass
  class_redis_objects[name].opts = opts 
  # An accessor method created in the metclass will
  # access the instance variables for this class. 
  metaclass.send :attr_reader, name
  metaclass.send :define_method, "#{name}=" do |v|
    send(name).replace v
  end
  metaclass.send :define_method, "#{name}?" do
    !send(name).empty?
  end
  redis_object = klass.new name, opts
  redis_object.freeze
  self.instance_variable_set("@#{name}", redis_object)
  class_redis_objects[name]
end
install_redis_object(name, klass, opts) click to toggle source

Creates an instance method called name that returns an instance of the RedisObject klass

# File lib/familia/object.rb, line 75
def install_redis_object name, klass, opts
  raise ArgumentError, "Name is blank" if name.to_s.empty?
  name = name.to_s.to_sym
  opts ||= {}
  redis_objects_order << name
  redis_objects[name] = OpenStruct.new
  redis_objects[name].name = name
  redis_objects[name].klass = klass
  redis_objects[name].opts = opts
  self.send :attr_reader, name
  define_method "#{name}=" do |v|
    self.send(name).replace v
  end
  define_method "#{name}?" do
    !self.send(name).empty?
  end
  redis_objects[name]
end
keys(suffix=nil) click to toggle source
# File lib/familia/object.rb, line 164
def keys(suffix=nil)
  self.redis.keys(rediskey('*',suffix)) || []
end
load_or_create(idx) click to toggle source

Returns an instance based on idx otherwise it creates and saves a new instance base on idx. See #from_index

# File lib/familia/object.rb, line 237
def load_or_create idx
  return from_redis(idx) if exists?(idx)
  obj = from_index idx
  obj.save
  obj
end
multiget(*ids) click to toggle source
# File lib/familia/object.rb, line 223
def multiget(*ids)
  ids = rawmultiget(*ids)
  ids.compact.collect { |json| self.from_json(json) }.compact
end
port(port=nil) click to toggle source
# File lib/familia/object.rb, line 145
def port(port=nil) @port = port if port; @port end
port=(port) click to toggle source
# File lib/familia/object.rb, line 146
def port=(port) @port = port end
prefix(a=nil) click to toggle source
# File lib/familia/object.rb, line 183
def prefix(a=nil) @prefix = a if a; @prefix || self.name.downcase.gsub('::', Familia.delim).to_sym end
prefix=(a) click to toggle source
# File lib/familia/object.rb, line 182
def prefix=(a) @prefix = a end
qstamp(quantum=nil, pattern=nil, now=Familia.now) click to toggle source
# File lib/familia/object.rb, line 94
def qstamp quantum=nil, pattern=nil, now=Familia.now
  quantum ||= ttl || 10.minutes
  pattern ||= '%H%M'
  rounded = now - (now % quantum)
  Time.at(rounded).utc.strftime(pattern)
end
rawmultiget(*ids) click to toggle source
# File lib/familia/object.rb, line 227
def rawmultiget(*ids)
  ids.collect! { |objid| rediskey(objid) }
  return [] if ids.compact.empty?
  Familia.trace :MULTIGET, self.redis, "#{ids.size}: #{ids}", caller if Familia.debug?
  ids = self.redis.mget *ids
end
redis() click to toggle source
# File lib/familia/object.rb, line 157
def redis
  Familia.redis uri
end
redis_object?(name) click to toggle source
# File lib/familia/object.rb, line 206
def redis_object? name
  redis_objects.has_key? name.to_s.to_sym
end
redis_objects() click to toggle source
# File lib/familia/object.rb, line 213
def redis_objects
  @redis_objects ||= {}
  @redis_objects
end
redis_objects_order() click to toggle source
# File lib/familia/object.rb, line 209
def redis_objects_order
  @redis_objects_order ||= []
  @redis_objects_order
end
rediskey(idx, suffix=self.suffix) click to toggle source

idx can be a value or an Array of values used to create the index. We don't enforce a default suffix; that's left up to the instance. A nil suffix will not be included in the key.

# File lib/familia/object.rb, line 283
def rediskey idx, suffix=self.suffix
  raise RuntimeError, "No index for #{self}" if idx.to_s.empty?
  idx = Familia.join *idx if Array === idx
  idx &&= idx.to_s
  Familia.rediskey(prefix, idx, suffix)
end
size(filter='*') click to toggle source
# File lib/familia/object.rb, line 174
def size(filter='*')
  self.redis.keys(rediskey(filter)).compact.size
end
suffix(a=nil, &blk) click to toggle source
# File lib/familia/object.rb, line 177
def suffix(a=nil, &blk) 
  @suffix = a || blk if a || !blk.nil?
  val = @suffix || Familia.default_suffix
  val
end
suffixes() click to toggle source
# File lib/familia/object.rb, line 192
def suffixes
  redis_objects.keys.uniq
end
ttl(v=nil) click to toggle source
# File lib/familia/object.rb, line 133
def ttl v=nil
  @ttl = v unless v.nil?
  @ttl || (parent ? parent.ttl : nil)
end
ttl=(v) click to toggle source
# File lib/familia/object.rb, line 137
def ttl=(v) @ttl = v end
uri(uri=nil) click to toggle source
# File lib/familia/object.rb, line 151
def uri(uri=nil) 
  self.uri = uri if !uri.to_s.empty?
  @uri ||= (parent ? parent.uri : Familia.uri)
  @uri.db = @db if @db && @uri.db.to_s != @db.to_s
  @uri
end
uri=(uri) click to toggle source
# File lib/familia/object.rb, line 147
def uri=(uri)
  uri = URI.parse uri if String === uri
  @uri = uri 
end