require 'redis' class Redmiso end require 'redmiso/type' class Redmiso class << self attr_accessor :default def redis # use Redis default by default @redis ||= Redis.new(default || {}) @redis end def string(name) t = type(Type::String,name) define_method("#{name}=") do |value| t.set(value) end end def instance_field end def class_field end def type(type,name) t = type.new(redis,"#{self}.#{name}") self.class_eval do define_method(name) do |&block| if block t.instance_eval(block) else t.value end end end t end def exist?(id) r = redis.sismember(id_set,id) r end def create(id=nil) id ||= redis.incr(auto_increment) unless redis.sadd(id_set,id) raise "can't create with existing id: #{id}" end self.new(id) end def delete(id) if redis.srem(id_set,id) == 0 raise "can't delete id: #{id}" end end def ids redis.smembers(id_set).map(&:to_i) end def all ids.map { |id| self.new(id) } end def count redis.scard(id_set) end def [](id) self.new(id) if exist?(id) end def vacuum # clean up everything not in root set raise "abstract" redis.keys("#{self}.*") # then extrat ids of fields, and check existence in rootset end def garbage # return attributes of objects not in rootset end private # this is the ROOT for this class def id_set @id_set ||= "#{self}#ids" @id_set end def auto_increment @auto_increment ||= "#{self}#auto_increment" @auto_increment end end def redis self.class.redis end attr_reader :id def initialize(id) @id = id end def delete self.class.delete(id) end def exist? self.class.exist?(id) end def ==(obj) obj.class == self.class && obj.id == self.id end end