Class: ActiveRedis::Base

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Dirty, ActiveModel::Naming, ActiveModel::Serialization, ActiveModel::Serializers::JSON, ActiveModel::Validations
Defined in:
lib/activeredis.rb

Constant Summary collapse

QUEUED =
"QUEUED"

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}, id = nil) ⇒ Base

INSTANCE METHODS



68
69
70
71
72
73
# File 'lib/activeredis.rb', line 68

def initialize(attributes = {}, id = nil)
  @id = id if id
  @attributes = {}
  initialize_attributes(attributes)
  frozen = false
end

Class Attribute Details

._fieldsObject

Returns the value of attribute _fields.



64
65
66
# File 'lib/activeredis.rb', line 64

def _fields
  @_fields
end

Instance Attribute Details

#attributesObject (readonly)

RAILSISM Returns a hash of all the attributes with their names as keys and the values of the attributes as values

--> means: Strings as keys!
--> initialize stringifies

called by to_json for_example


60
61
62
# File 'lib/activeredis.rb', line 60

def attributes
  @attributes
end

#frozenObject (readonly)

Returns the value of attribute frozen.



62
63
64
# File 'lib/activeredis.rb', line 62

def frozen
  @frozen
end

#idObject (readonly)

Returns the value of attribute id.



61
62
63
# File 'lib/activeredis.rb', line 61

def id
  @id
end

Class Method Details

.allObject



261
262
263
# File 'lib/activeredis.rb', line 261

def self.all
  find_all
end

.connectionObject



223
224
225
# File 'lib/activeredis.rb', line 223

def self.connection
  @@redis
end

.countObject



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/activeredis.rb', line 227

def self.count
  begin
    size = connection.zcard "#{key_namespace}:all"
    while size == QUEUED
      sleep(0.1)
      size = connection.zcard "#{key_namespace}:all"
    end
    return size
  rescue RuntimeError => e
    return 0
  end
end

.create(attributes) ⇒ Object

CLASS METHODS



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

def self.create(attributes)
  self.new(attributes).save
end

.define_field(field) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/activeredis.rb', line 177

def self.define_field(field)
  define_method field.to_sym do
    if field.to_sym == :updated_at
      Time.parse(@attributes["#{field}"])
    else
      @attributes["#{field}"]  
    end
  end

  define_method "#{field}=".to_sym do |new_value|
    @attributes["#{field}"] = new_value.to_s
  end
end

.delete_allObject



265
266
267
268
269
270
# File 'lib/activeredis.rb', line 265

def self.delete_all
  records = find_all
  records.each do |record|
    record.destroy
  end
end

.delete_unused_fieldObject



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/activeredis.rb', line 307

def self.delete_unused_field
  ids = connection.zrange "#{key_namespace}:all", 0, count
  if ids.size > 0
    attributes = connection.hgetall "#{key_namespace}:#{ids[0]}:attributes"
    now_keys   = self.get_fields
    array = []
    now_keys.each do |key|
      array << key.to_s
    end
    attributes.reject! {|key| array.include? key }
    attributes.keys.each do |delete_key|
      ids.each do |id|
        connection.hdel "#{key_namespace}:#{id}:attributes", delete_key
      end
    end
  end
end

.fetch_new_identifierObject



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

def self.fetch_new_identifier
  self.connection.incr self.identifier_sequencer
end

.fields(*fields) ⇒ Object

Run this method to declare the fields of your model.



192
193
194
195
# File 'lib/activeredis.rb', line 192

def self.fields(*fields)
  self._fields ||= []
  self._fields = fields
end

.find(id) ⇒ Object

Raises:



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

def self.find(id)
  return find_all if id == :all
  exists = connection.zscore "#{key_namespace}:all", id
  raise RecordNotFound.new("Couldn't find #{self.name} with ID=#{id}") unless exists
  attributes = connection.hgetall "#{key_namespace}:#{id}:attributes"
  obj = self.new attributes, id
  return obj
end

.find_allObject



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/activeredis.rb', line 240

def self.find_all()
  record = []
  # TODO Interim fix, "QUEUED" is find(id) rescue
  while true
    ids = connection.zrange "#{key_namespace}:all", 0, count
    while ids == QUEUED 
      sleep(0.1)
      ids = connection.zrange "#{key_namespace}:all", 0, count
    end
    begin
      ids.each do |id|
        record << find(id)
      end
    rescue
      redo
    end
    break
  end
  record
end

.find_all_by_param(field, value) ⇒ Object



281
282
283
284
285
286
287
288
289
290
# File 'lib/activeredis.rb', line 281

def self.find_all_by_param(field, value)
  finded = []
  records = find_all
  records.each do |record|
    if record.attributes[field.to_s] == value.to_s
      finded << record
    end
  end
  return finded
end

.find_by_param(field, value) ⇒ Object



292
293
294
295
296
297
298
299
# File 'lib/activeredis.rb', line 292

def self.find_by_param(field, value)
  records = find_all_by_param(field, value)
  if records.size > 0
    return records[0]
  else
    nil
  end
end

.get_fieldsObject



197
198
199
# File 'lib/activeredis.rb', line 197

def self.get_fields
  self._fields
end

.identifier_sequencerObject



209
210
211
# File 'lib/activeredis.rb', line 209

def self.identifier_sequencer
  "#{key_namespace}:sequence"
end

.inherited(child) ⇒ Object



213
214
215
216
217
# File 'lib/activeredis.rb', line 213

def self.inherited(child)
  #puts "Redis.new(:host => #{ActiveRedis.host}, :port => #{ActiveRedis.port})"
  @@redis = Redis.new(:host => ActiveRedis.host, :port => ActiveRedis.port)
  @@class = child
end

.key_namespaceObject



201
202
203
# File 'lib/activeredis.rb', line 201

def self.key_namespace
  "#{self}"
end

.method_missing(name, *args) ⇒ Object



301
302
303
304
305
# File 'lib/activeredis.rb', line 301

def self.method_missing(name, *args)
  return find_by_param($1.to_sym, args[0]) if name.to_s =~ /^find_by_(.*)/
  return find_all_by_param($1.to_sym, args[0]) if name.to_s =~ /^find_all_by_(.*)/
  super
end

.redis_informationObject



219
220
221
# File 'lib/activeredis.rb', line 219

def self.redis_information
  connection.info # call_command [:info]
end

Instance Method Details

#[](field) ⇒ Object



161
162
163
# File 'lib/activeredis.rb', line 161

def [](field)
  send(field)
end

#[]=(field, value) ⇒ Object



165
166
167
# File 'lib/activeredis.rb', line 165

def []=(field, value)
  send(field+"=", value)
end

#add_attribute(name, value = nil) ⇒ Object



157
158
159
# File 'lib/activeredis.rb', line 157

def add_attribute(name, value=nil)
  initialize_attributes({name => value})
end

#class_namespaceObject



136
137
138
# File 'lib/activeredis.rb', line 136

def class_namespace
  "#{self.class.key_namespace}"
end

#connectionObject



140
141
142
# File 'lib/activeredis.rb', line 140

def connection
  self.class.connection
end

#destroyObject



144
145
146
147
148
149
150
151
# File 'lib/activeredis.rb', line 144

def destroy
  connection.multi do
    connection.del "#{key_namespace}:attributes"
    connection.zrem "#{class_namespace}:all", @id
    @frozen = true
  end
  return true     
end

#frozen?Boolean

Returns:

  • (Boolean)


153
154
155
# File 'lib/activeredis.rb', line 153

def frozen?
  @frozen
end

#initialize_attributes(attributes) ⇒ Object

Object’s attributes’ keys are converted to strings because of railsisms. Because of activeredisism, also values are converted to strings for consistency.



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/activeredis.rb', line 77

def initialize_attributes(attributes)
  fields = Hash[[self.class._fields, Array.new(self.class._fields.size)].transpose]
  fields.stringify_keys!   # NEEDS to be strings for railsisms
  attributes.stringify_keys!   # NEEDS to be strings for railsisms
  attributes.each_pair { |key, value| attributes[key] = value.to_s }
  fields.merge!(attributes)
  @attributes.merge!(fields)
  @attributes.each_pair do |key, value|
    self.class.define_field key
  end
end

#key_namespaceObject



132
133
134
# File 'lib/activeredis.rb', line 132

def key_namespace
  "#{self.class.key_namespace}:#{self.id}"
end

#new_record?Boolean

Returns:

  • (Boolean)


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

def new_record?
  @id == nil
end

#reloadObject



124
125
126
# File 'lib/activeredis.rb', line 124

def reload
  @attributes = connection.hgetall "#{key_namespace}:attributes"
end

#saveObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/activeredis.rb', line 89

def save
  creation = new_record?
  @id = self.class.fetch_new_identifier if creation
  while true
    begin
      connection.multi
    rescue
      sleep(0.1)
      redo
    end
    break
  end
  if @attributes.size > 0  
    @attributes.each_pair { |key, value|
      if key.to_sym == :updated_at
        value = Time.now.to_s
      end
      connection.hset("#{key_namespace}:attributes", key, value)
    }
  end
  connection.zadd("#{class_namespace}:all", @id, @id) 
  connection.exec
  return true
end

#update_attributes(attributes) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/activeredis.rb', line 114

def update_attributes(attributes)
  attributes.stringify_keys!   # NEEDS to be strings for railsisms
  attributes.each_pair { |key, value| attributes[key] = value.to_s }
  @attributes.merge!(attributes)
  attributes.each_pair do |key, value|
    self.class.define_field key
  end
  save
end