Class: EasyRedis::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/easyredis.rb

Overview

class representing a data model you want to store in redis

Constant Summary collapse

@@sorts =
[]
@@text_searches =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id = nil) ⇒ Model

create a new instance of this model

If no id is passed, one is generated for you. Otherwise, sets the id field to the passed id, but does not check to see if it is a valid id for this model. Users should use find when retiving models by id, as these check for valid ids.



369
370
371
372
373
374
375
376
377
# File 'lib/easyredis.rb', line 369

def initialize(id=nil)
  if id
    @id = id
  else
    @id = EasyRedis.redis.incr(prefix + ':next_id')
    EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
    @id
  end
end

Instance Attribute Details

#idObject (readonly)

the id of this entry



362
363
364
# File 'lib/easyredis.rb', line 362

def id
  @id
end

Class Method Details

.[](index, amt = nil) ⇒ Object

access entries of this model based on time

same as all.[]



284
285
286
# File 'lib/easyredis.rb', line 284

def self.[](index,amt=nil)
  self.all[index,amt]
end

.all(options = {:order => :asc}) ⇒ Object

get all instances of this model ordered by creation time



253
254
255
# File 'lib/easyredis.rb', line 253

def self.all(options = {:order => :asc})
  self.sort_by :created_at, options
end

.countObject

returns number of instances of this model



247
248
249
# File 'lib/easyredis.rb', line 247

def self.count
  EasyRedis.redis.zcard(prefix)
end

.destroy_allObject

destroy all instances of this model



352
353
354
355
356
357
358
# File 'lib/easyredis.rb', line 352

def self.destroy_all
  all.each {|x| x.destroy}
  @@sorts.each {|field| EasyRedis.redis.del(sort_key(field)) }
  @@text_searches.each {|field| EasyRedis.redis.del(terms_key(field)) }
  EasyRedis.redis.del(prefix)
  EasyRedis.redis.del(prefix + ":next_id")
end

.field(name) ⇒ Object

add a field to the model



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/easyredis.rb', line 201

def self.field(name)
  @@fields ||= []
  @@fields << name.to_sym
  name = name.to_s
  getter = name
  setter = name + "="
  instance_var = '@' + name

  define_method getter.to_sym do
    prev = instance_variable_get(instance_var)
    if prev
      prev
    else
      instance_variable_set(instance_var,Marshal.load(EasyRedis.redis.hget(key_name,name)))
    end
  end

  define_method setter.to_sym do |val|
    EasyRedis.redis.hset(key_name,name,Marshal.dump(val))
    instance_variable_set(instance_var,val)

    if self.class.sortable? name.to_sym
      EasyRedis.redis.zadd(sort_key(name),EasyRedis.score(val),@id)
    end

    if self.class.text_search? name.to_sym
      val.split.each do |term|
        EasyRedis.redis.zadd term_key(name,term), created_at.to_i, id
        EasyRedis.redis.zadd terms_key(name), EasyRedis.score(term), term
      end
    end
  end
end

.find(id) ⇒ Object

find an instance of this model based on its id



273
274
275
276
277
278
279
# File 'lib/easyredis.rb', line 273

def self.find(id)
  if EasyRedis.redis.zscore(prefix,id)
    new(id)
  else
    nil
  end
end

.find_by(field, val) ⇒ Object

get the first entry where field matches val



298
299
300
# File 'lib/easyredis.rb', line 298

def self.find_by(field,val)
  search_by(field,val,:limit => 1).first
end

.first(n = nil) ⇒ Object

same as all.first



258
259
260
# File 'lib/easyredis.rb', line 258

def self.first(n = nil)
  self.all.first(n)
end

.last(n = nil) ⇒ Object

same as all.last



263
264
265
# File 'lib/easyredis.rb', line 263

def self.last(n = nil)
  self.all.last(n)
end

.match(field, str, options = {}) ⇒ Object

searches for all entries where field contains the string str

The string must appear exactly as a term in field’s value. To search based on the beginning of a term, you can combine this method with matches. The field must have been indexed with text_search.



335
336
337
338
339
# File 'lib/easyredis.rb', line 335

def self.match(field,str, options = {})
  raise EasyRedis::FieldNotTextSearchable, filename unless text_search? field
  ids = EasyRedis.redis.zrange(term_key(field,str), 0, -1, proc_options(options))
  ids.map{|i| new(i)}
end

.matches(field, str) ⇒ Object

gives all values for the given field that begin with str

The field must have been indexed with text_search.



324
325
326
327
328
329
# File 'lib/easyredis.rb', line 324

def self.matches(field,str)
  raise FieldNotTextSearchable, field unless self.text_search? field
  scr = EasyRedis.score(str)
  a,b = scr, scr+1/(27.0**str.size)
  EasyRedis.redis.zrangebyscore(terms_key(field), "#{a}", "(#{b}")
end

.randObject

returns a random entry of this model



268
269
270
# File 'lib/easyredis.rb', line 268

def self.rand
  self[Kernel.rand(self.count)]
end

.search(params) ⇒ Object

search the model based on multiple parameters

takes a hash of field => value pairs



305
306
307
308
309
310
311
312
313
314
# File 'lib/easyredis.rb', line 305

def self.search(params)
  return search_by(*params.first) if params.size == 1  # comment out for benchmarking purposes
  result_set = nil
  params.each do |field,value|
    scr = EasyRedis.score(value)
    ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr)
    result_set = result_set ? (result_set & Set.new(ids)) : Set.new(ids)
  end
  result_set.map{|i|new(i)}
end

.search_by(field, val, options = {}) ⇒ Object

get all entries where field matches val



289
290
291
292
293
294
295
# File 'lib/easyredis.rb', line 289

def self.search_by(field, val, options = {})
  raise EasyRedis::FieldNotSortable, field unless @@sorts.member? field.to_sym
  scr = EasyRedis.score(val)
  # options[:limit] = [0,options[:limit]] if options[:limit]
  ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr,proc_options(options))
  ids.map{|i| new(i) }
end

.sort_by(field, options = {:order => :asc}) ⇒ Object

get all entries, sorted by the given field



317
318
319
# File 'lib/easyredis.rb', line 317

def self.sort_by(field,options = {:order => :asc})
  EasyRedis::Sort.new(field,options[:order],self)
end

.sort_on(field) ⇒ Object

index a field to be sorted/searched



236
237
238
# File 'lib/easyredis.rb', line 236

def self.sort_on(field)
  @@sorts << field.to_sym
end

.sortable?(field) ⇒ Boolean

indicates whether field has been indexed with sort_on

Returns:

  • (Boolean)


342
343
344
# File 'lib/easyredis.rb', line 342

def self.sortable?(field)
  @@sorts and (@@sorts.member? field or field.to_sym == :created_at)
end

.text_search(field) ⇒ Object

index a field for text searching



241
242
243
244
# File 'lib/easyredis.rb', line 241

def self.text_search(field)
  @@text_searches << field.to_sym
  sort_on(field) unless sortable? field
end

.text_search?(field) ⇒ Boolean

indicates whether field has been indexed with text_search

Returns:

  • (Boolean)


347
348
349
# File 'lib/easyredis.rb', line 347

def self.text_search?(field)
  @@text_searches and @@text_searches.member?(field)
end

Instance Method Details

#[](field) ⇒ Object

directly access a field of this entry’s redis hash

note that you cannot access created_at or id with these methods



387
388
389
# File 'lib/easyredis.rb', line 387

def [](field)
  EasyRedis.redis.hget(key_name,field)
end

#[]=(field, val) ⇒ Object

directly change a field of this entry’s redis hash

note that you cannot access created_at or id with these methods



394
395
396
397
398
399
400
# File 'lib/easyredis.rb', line 394

def []=(field,val)
  if val
    EasyRedis.redis.hset(key_name,field,val)
  else
    EasyRedis.redis.hdel(key_name,field)
  end
end

#clearObject

clears all fields, causing future gets to reretrive them from redis



418
419
420
421
422
# File 'lib/easyredis.rb', line 418

def clear
  @@fields.each do |field|
    self.instance_variable_set("@"+field.to_s,nil)
  end
end

#created_atObject

get the creation time of an entry



380
381
382
# File 'lib/easyredis.rb', line 380

def created_at
  Time.at(EasyRedis.redis.zscore(prefix,@id).to_i)
end

#destroyObject

remove the entry



403
404
405
406
# File 'lib/easyredis.rb', line 403

def destroy
  EasyRedis.redis.zrem(prefix,@id)
  EasyRedis.redis.del(key_name)
end

#inspectObject



413
414
415
# File 'lib/easyredis.rb', line 413

def inspect
  "#<#{self.class.name}:#{@id}>"
end

#key_nameObject

returns the key name of this entry’s redis hash



409
410
411
# File 'lib/easyredis.rb', line 409

def key_name
  prefix + ':' + @id.to_s
end