Module: Familia::ClassMethods

Defined in:
lib/familia/object.rb

Overview

Auto-extended into a class that includes Familia

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



131
132
133
# File 'lib/familia/object.rb', line 131

def parent
  @parent
end

Instance Method Details

#all(suffix = :object) ⇒ Object



166
167
168
169
# File 'lib/familia/object.rb', line 166

def all(suffix=:object)
  # objects that could not be parsed will be nil
  keys(suffix).collect { |k| from_key(k) }.compact 
end

#any?(filter = '*') ⇒ Boolean

Returns:

  • (Boolean)


170
171
172
# File 'lib/familia/object.rb', line 170

def any?(filter='*')
  size(filter) > 0
end

#class_redis_objectsObject



198
199
200
201
# File 'lib/familia/object.rb', line 198

def class_redis_objects
  @class_redis_objects ||= {}
  @class_redis_objects
end

#class_redis_objects?(name) ⇒ Boolean

Returns:

  • (Boolean)


202
203
204
# File 'lib/familia/object.rb', line 202

def class_redis_objects? name
  class_redis_objects.has_key? name.to_s.to_sym
end

#class_redis_objects_orderObject



194
195
196
197
# File 'lib/familia/object.rb', line 194

def class_redis_objects_order
  @class_redis_objects_order ||= []
  @class_redis_objects_order
end

#create(*args) ⇒ Object



216
217
218
219
220
221
# File 'lib/familia/object.rb', line 216

def create *args
  me = from_array *args
  raise "#{self} exists: #{me.rediskey}" if me.exists?
  me.save
  me
end

#db(v = nil) ⇒ Object



137
138
139
140
# File 'lib/familia/object.rb', line 137

def db v=nil
  @db = v unless v.nil?
  @db || (parent ? parent.db : nil)
end

#db=(db) ⇒ Object



141
# File 'lib/familia/object.rb', line 141

def db=(db) @db = db end

#destroy!(idx, suffix = :object) ⇒ Object



271
272
273
274
275
# File 'lib/familia/object.rb', line 271

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.first
  ret
end

#exists?(idx, suffix = :object) ⇒ Boolean

Returns:

  • (Boolean)


264
265
266
267
268
269
270
# File 'lib/familia/object.rb', line 264

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.first
  ret
end

#expand(short_idx, suffix = self.suffix) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/familia/object.rb', line 288

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
  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) ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/familia/object.rb', line 70

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 = '*') ⇒ Object



276
277
278
# File 'lib/familia/object.rb', line 276

def find suffix='*'
  list = Familia.redis(self.uri).keys(rediskey('*', suffix)) || []
end

#flushdbObject



159
160
161
162
# File 'lib/familia/object.rb', line 159

def flushdb
  Familia.info "flushing #{uri}"
  redis.flushdb
end

#from_index(idx) ⇒ Object

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.



246
247
248
249
250
# File 'lib/familia/object.rb', line 246

def from_index idx
  obj = new 
  obj.index = idx
  obj
end

#from_key(objkey) ⇒ Object

Raises:

  • (ArgumentError)


251
252
253
254
255
256
# File 'lib/familia/object.rb', line 251

def from_key objkey
  raise ArgumentError, "Null key" if objkey.to_s.empty?    
  Familia.trace :LOAD, redis, "#{self.uri}/#{objkey}", caller if Familia.debug?
  obj = Familia::String.new objkey, :class => self
  obj.exists? ? obj.value : nil
end

#from_redis(idx, suffix = :object) ⇒ Object



257
258
259
260
261
262
263
# File 'lib/familia/object.rb', line 257

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
  me = from_key objkey
  me
end

#from_redisdump(dump) ⇒ Object



128
129
130
# File 'lib/familia/object.rb', line 128

def from_redisdump dump
  dump # todo
end

#host(host = nil) ⇒ Object



142
# File 'lib/familia/object.rb', line 142

def host(host=nil) @host = host if host; @host end

#host=(host) ⇒ Object



143
# File 'lib/familia/object.rb', line 143

def host=(host) @host = host end

#index(i = nil, &blk) ⇒ Object

TODO: grab db, ttl, uri from parent def parent=(a) @parent = a end def parent(a=nil) @parent = a if a; @parent end



186
187
188
189
190
# File 'lib/familia/object.rb', line 186

def index(i=nil, &blk) 
  @index = i || blk if i || !blk.nil?
  @index ||= Familia.index
  @index
end

#inherited(obj) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/familia/object.rb', line 56

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
  # :object is a special redis object because its reserved
  # for storing the marshaled instance data (e.g. to_json).
  # When it isn't defined explicitly we define it here b/c
  # it's assumed to exist in other places (see #save).
  obj.string :object, :class => obj unless obj.redis_object? :object
  Familia.classes << obj
  super(obj)
end

#install_class_redis_object(name, klass, opts) ⇒ Object

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

Raises:

  • (ArgumentError)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/familia/object.rb', line 102

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[:parent] ||= self
  # 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) ⇒ Object

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

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/familia/object.rb', line 81

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) ⇒ Object



163
164
165
# File 'lib/familia/object.rb', line 163

def keys(suffix=nil)
  self.redis.keys(rediskey('*',suffix)) || []
end

#load_or_create(idx) ⇒ Object

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



236
237
238
239
240
241
# File 'lib/familia/object.rb', line 236

def load_or_create idx
  return from_redis(idx) if exists?(idx)
  obj = from_index idx
  obj.save
  obj
end

#multiget(*ids) ⇒ Object



222
223
224
225
# File 'lib/familia/object.rb', line 222

def multiget(*ids)
  ids = rawmultiget(*ids)
  ids.compact.collect { |json| self.from_json(json) }.compact
end

#port(port = nil) ⇒ Object



144
# File 'lib/familia/object.rb', line 144

def port(port=nil) @port = port if port; @port end

#port=(port) ⇒ Object



145
# File 'lib/familia/object.rb', line 145

def port=(port) @port = port end

#prefix(a = nil) ⇒ Object



182
# File 'lib/familia/object.rb', line 182

def prefix(a=nil) @prefix = a if a; @prefix || self.name.downcase.to_sym end

#prefix=(a) ⇒ Object



181
# File 'lib/familia/object.rb', line 181

def prefix=(a) @prefix = a end

#rawmultiget(*ids) ⇒ Object



226
227
228
229
230
231
# File 'lib/familia/object.rb', line 226

def rawmultiget(*ids)
  ids.collect! { |objid| rediskey(objid) }
  return [] if ids.compact.empty?
  Familia.trace :MULTIGET, self.redis, "#{ids.size}: #{ids}", caller
  ids = self.redis.mget *ids
end

#redisObject



156
157
158
# File 'lib/familia/object.rb', line 156

def redis
  Familia.redis uri
end

#redis_object?(name) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/familia/object.rb', line 205

def redis_object? name
  redis_objects.has_key? name.to_s.to_sym
end

#redis_objectsObject



212
213
214
215
# File 'lib/familia/object.rb', line 212

def redis_objects
  @redis_objects ||= {}
  @redis_objects
end

#redis_objects_orderObject



208
209
210
211
# File 'lib/familia/object.rb', line 208

def redis_objects_order
  @redis_objects_order ||= []
  @redis_objects_order
end

#rediskey(idx, suffix = self.suffix) ⇒ Object

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.

Raises:

  • (RuntimeError)


282
283
284
285
286
287
# File 'lib/familia/object.rb', line 282

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 = '*') ⇒ Object



173
174
175
# File 'lib/familia/object.rb', line 173

def size(filter='*')
  self.redis.keys(rediskey(filter)).compact.size
end

#suffix(a = nil, &blk) ⇒ Object



176
177
178
179
180
# File 'lib/familia/object.rb', line 176

def suffix(a=nil, &blk) 
  @suffix = a || blk if a || !blk.nil?
  val = @suffix || Familia.default_suffix
  val
end

#suffixesObject



191
192
193
# File 'lib/familia/object.rb', line 191

def suffixes
  redis_objects.keys.uniq
end

#ttl(v = nil) ⇒ Object



132
133
134
135
# File 'lib/familia/object.rb', line 132

def ttl v=nil
  @ttl = v unless v.nil?
  @ttl || (parent ? parent.ttl : nil)
end

#ttl=(v) ⇒ Object



136
# File 'lib/familia/object.rb', line 136

def ttl=(v) @ttl = v end

#uri(uri = nil) ⇒ Object



150
151
152
153
154
155
# File 'lib/familia/object.rb', line 150

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) ⇒ Object



146
147
148
149
# File 'lib/familia/object.rb', line 146

def uri=(uri)
  uri = URI.parse uri if String === uri
  @uri = uri 
end