Module: Redrecord::Model

Defined in:
lib/redrecord.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(mod) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/redrecord.rb', line 79

def self.included(mod)
  mod.extend(ClassMethods)
  mod.send(:after_save,     :redrecord_update_queue_save)
  mod.send(:after_destroy,  :redrecord_update_queue_destroy)
  mod.send(:after_commit,   :redrecord_update_queue_commit)
  mod.send(:after_rollback, :redrecord_update_queue_rollback)
end

Instance Method Details

#add_to_cache!Object



131
132
133
134
135
136
137
138
139
# File 'lib/redrecord.rb', line 131

def add_to_cache!
  Redrecord.redis_op(:hmset, redrecord_key,
    *(self.class.redrecord_cached_fields.map {|f|
      aliased_target, punctuation = f.to_s.sub(/([?!=])$/, ''), $1
      val = send("#{aliased_target}_without_cache#{punctuation}")
      [f.to_s, Redrecord.marshal(val)]
    }.flatten)
  )
end

#attribs_with_cached_fieldsObject



174
175
176
# File 'lib/redrecord.rb', line 174

def attribs_with_cached_fields
  attributes.merge(cached_fields)
end

#cached_fieldsObject



178
179
180
# File 'lib/redrecord.rb', line 178

def cached_fields
  self.class.redrecord_cached_fields.inject({}) {|hsh,field| hsh[field] = send(field) ; hsh }
end

#cached_method(method_name) ⇒ Object



151
152
153
# File 'lib/redrecord.rb', line 151

def cached_method(method_name)
  redrecord_cached_attrib_hash[method_name.to_sym]
end

#invalidations_for_redrecord_update_queueObject



92
93
94
95
96
97
98
99
100
# File 'lib/redrecord.rb', line 92

def invalidations_for_redrecord_update_queue
  self.class.redrecord_invalidation_fields.each do |f|
    if((field_value = send(f)).kind_of?(Array))
      field_value.each {|item|  Redrecord.update_queue << [:save, item] } 
    else
      Redrecord.update_queue << [:save, field_value] if field_value
    end
  end
end

#redrecord_cached_attrib_hashObject



159
160
161
162
163
164
165
166
167
# File 'lib/redrecord.rb', line 159

def redrecord_cached_attrib_hash
  @redrecord_cached_attrib_hash ||= Hash.new do |h,k|
    h[k.to_sym] = if(cached = (redrecord_redis_cache && redrecord_redis_cache[k.to_s] unless new_record?))
      Redrecord.unmarshal(cached)
    else
      redrecord_uncached_value(k)
    end
  end
end

#redrecord_keyObject



123
124
125
# File 'lib/redrecord.rb', line 123

def redrecord_key
  "#{self.class.table_name}:#{self.id}"
end

#redrecord_redis_cacheObject



155
156
157
# File 'lib/redrecord.rb', line 155

def redrecord_redis_cache
  @redrecord_redis_cache ||= Redrecord.redis_op(:hgetall, redrecord_key) unless Redrecord.write_only
end

#redrecord_uncached_value(fieldname) ⇒ Object



169
170
171
172
# File 'lib/redrecord.rb', line 169

def redrecord_uncached_value(fieldname)
  aliased_target, punctuation = fieldname.to_s.sub(/([?!=])$/, ''), $1
  send("#{aliased_target}_without_cache#{punctuation}")
end

#redrecord_update_queue_commitObject



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/redrecord.rb', line 111

def redrecord_update_queue_commit
  Redrecord.update_queue.each do |command, record|
    if command == :destroy
      record.remove_from_cache!
    elsif command == :save
      record.add_to_cache!
      # possible todo: cascade invalidation (but avoid loops)
    end
  end
  Redrecord.update_queue.clear
end

#redrecord_update_queue_destroyObject



102
103
104
105
# File 'lib/redrecord.rb', line 102

def redrecord_update_queue_destroy
  Redrecord.update_queue << [:destroy, self] unless self.class.redrecord_cached_fields.empty?
  invalidations_for_redrecord_update_queue
end

#redrecord_update_queue_rollbackObject



107
108
109
# File 'lib/redrecord.rb', line 107

def redrecord_update_queue_rollback
  Redrecord.update_queue.clear
end

#redrecord_update_queue_saveObject



87
88
89
90
# File 'lib/redrecord.rb', line 87

def redrecord_update_queue_save
  Redrecord.update_queue << [:save, self] unless self.class.redrecord_cached_fields.empty?
  invalidations_for_redrecord_update_queue
end

#remove_from_cache!Object



127
128
129
# File 'lib/redrecord.rb', line 127

def remove_from_cache!
  Redrecord.redis_op :del, redrecord_key
end

#verify_cache!Object



141
142
143
144
145
146
147
148
149
# File 'lib/redrecord.rb', line 141

def verify_cache!
  (redis_cached_keys = Redrecord.redis_op(:hkeys, redrecord_key)) && redis_cached_keys.each do |key|
    calculated = redrecord_uncached_value(key)
    cachedval = Redrecord.unmarshal(Redrecord.redis_op(:hget, redrecord_key, key))
    if(calculated != cachedval)
      raise "#{redrecord_key}.#{key}: expected <#{calculated}> but got <#{cachedval}> from redis cache"
    end
  end
end