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, check = true) ⇒ Model

create a new instance of this model

Parameters:

  • id (String) (defaults to: nil)

    optional id to use for the entry if you leave this parameter out an id will be generated for you

  • check (Boolean) (defaults to: true)

    this flag is used for internal purposes. LEAVE IT AS TRUE



403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/easyredis.rb', line 403

def initialize(id=nil,check=true)
  if id
    @id = id.to_s
    if check
      raise "id #{id} is already in use" if EasyRedis.redis.zscore(prefix,id)
      EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
    end
  else
    @id = EasyRedis.redis.incr(prefix + ':next_id').to_s
    EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
  end
end

Instance Attribute Details

#idObject (readonly)

the id of this entry



395
396
397
# File 'lib/easyredis.rb', line 395

def id
  @id
end

Class Method Details

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

access entries of this model based on time

same as calling self.all.[]



312
313
314
# File 'lib/easyredis.rb', line 312

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



279
280
281
# File 'lib/easyredis.rb', line 279

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

.countObject

returns number of instances of this model



273
274
275
# File 'lib/easyredis.rb', line 273

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

.destroy_allObject

destroy all instances of this model



385
386
387
388
389
390
391
# File 'lib/easyredis.rb', line 385

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

Parameters:

  • name (Symbol)

    a symbol representing the name of the field



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/easyredis.rb', line 223

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 entry of this model based on its id

Parameters:

  • id (Integer)

    the id of the entry to retrive



301
302
303
304
305
306
307
# File 'lib/easyredis.rb', line 301

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

.find_by(field, val) ⇒ Object

get the first entry where field matches val



331
332
333
# File 'lib/easyredis.rb', line 331

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

.first(n = nil) ⇒ Object

same as calling self.all.first



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

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

.last(n = nil) ⇒ Object

same as calling self.all.last



289
290
291
# File 'lib/easyredis.rb', line 289

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.



368
369
370
371
372
# File 'lib/easyredis.rb', line 368

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| build(i)}
end

.matches(field, str) ⇒ Object

gives all values for the given field that begin with str

Parameters:

  • field (Symbol)

    a symbol representing a field indexed with text_search.

Raises:



357
358
359
360
361
362
# File 'lib/easyredis.rb', line 357

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



294
295
296
# File 'lib/easyredis.rb', line 294

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

.search(params) ⇒ Object

search the model based on multiple parameters

Parameters:

  • params (Hash)

    a hash of field => value pairs



338
339
340
341
342
343
344
345
346
347
# File 'lib/easyredis.rb', line 338

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|build(i)}
end

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

get all entries where field matches val

Parameters:

  • field (Symbol)

    a symbol representing the field to search on

  • val

    the value of field to search for

Raises:



320
321
322
323
324
325
326
# File 'lib/easyredis.rb', line 320

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| build(i) }
end

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

get all entries, sorted by the given field



350
351
352
# File 'lib/easyredis.rb', line 350

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



260
261
262
# File 'lib/easyredis.rb', line 260

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

.sortable?(field) ⇒ Boolean

indicates whether field has been indexed with sort_on

Returns:

  • (Boolean)


375
376
377
# File 'lib/easyredis.rb', line 375

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



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

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)


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

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



424
425
426
# File 'lib/easyredis.rb', line 424

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



431
432
433
434
435
436
437
# File 'lib/easyredis.rb', line 431

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



455
456
457
458
459
# File 'lib/easyredis.rb', line 455

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



417
418
419
# File 'lib/easyredis.rb', line 417

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

#destroyObject

remove the entry



440
441
442
443
# File 'lib/easyredis.rb', line 440

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

#inspectObject



450
451
452
# File 'lib/easyredis.rb', line 450

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

#key_nameObject

returns the key name of this entry’s redis hash



446
447
448
# File 'lib/easyredis.rb', line 446

def key_name
  "#{prefix}:#{@id}"
end