Class: RedisModel
- Inherits:
-
Object
- Object
- RedisModel
- Defined in:
- lib/redismodel.rb
Defined Under Namespace
Modules: ArrayProxy, HashProxy Classes: PropertyTypeIncorrect, RecordNotFound
Constant Summary collapse
- VERSION =
'0.1.8'
- DEFAULT_CONFIG =
{ :atomic => true, :default_sort => "created_at" }
Instance Attribute Summary collapse
-
#_data ⇒ Object
Local cache of the data.
Class Method Summary collapse
-
.all ⇒ Object
Returns all records.
- .blank_record(hash = {}) ⇒ Object
-
.cast(klass, value) ⇒ Object
Casts a object type as a compatible type for redis, or reverses the process.
-
.config(hash = nil) ⇒ Object
Setter and getter for the config.
- .connection(klass) ⇒ Object
-
.count ⇒ Object
Returns the number of records for the model.
-
.destroy(*ids) ⇒ Object
Destroys all records with the ids passed.
-
.destroy_all ⇒ Object
Permamently deletes all records for the model.
-
.find(id) ⇒ Object
Finds a record from it’s id.
-
.property(name, type) ⇒ Object
Defines a new property.
-
.save! ⇒ Object
Saves the Redis database to disk.
-
.search(property, value) ⇒ Object
Returns all records where the value of ‘property` matches `str`.
- .version ⇒ Object
Instance Method Summary collapse
-
#destroy ⇒ Object
Permamently deletes all traces of the record, and decrements the model count.
- #generate_uniq_token ⇒ Object
- #id ⇒ Object
-
#initialize(hash = {}) ⇒ RedisModel
constructor
Creates a new object.
-
#inspect ⇒ Object
Custom model inspect in the format of: #<MyModel:8a80300a9b id: “8a80300a9b…”, created_at: “2010-08-01T01:32:11+01:00”>.
- #redis ⇒ Object
-
#reload ⇒ Object
Updates all keys from redis.
Constructor Details
#initialize(hash = {}) ⇒ RedisModel
Creates a new object. If ‘=> “…”` is passed, it’ll attempt to recover the record from the redis DB. If it can’t find such a record, it’ll raise RedisModel::RecordNotFound
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/redismodel.rb', line 112 def initialize(hash={}) @_data = {} if hash[:id].nil? hash = self.class.blank_record.merge(hash) self.send("id=", generate_uniq_token) if self.class.properties.include?(:created_at) set :created_at, DateTime.now end hash.to_a.each do |property| begin self.send("#{property[0]}=", property[1]) rescue end end redis.set "#{self.class}:#{id}:id", id redis.incr "#{self.class}:_meta:count" else self.send("id=", hash[:id]) if get(:id).nil? raise RedisModel::RecordNotFound else self.reload end end end |
Instance Attribute Details
#_data ⇒ Object
Local cache of the data
84 85 86 |
# File 'lib/redismodel.rb', line 84 def _data @_data end |
Class Method Details
.all ⇒ Object
Returns all records
235 236 237 238 239 240 241 |
# File 'lib/redismodel.rb', line 235 def self.all arr = [] redis.keys("#{klass}:*:id").each do |key| arr << klass.find( key.split(":")[1] ) end arr.sort_by{|m| m.send( DEFAULT_CONFIG[:default_sort] )} end |
.blank_record(hash = {}) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/redismodel.rb', line 96 def self.blank_record(hash={}) blanks = { String => "", Array => [], Hash => {} } self.properties.to_a.map do |c| blank = blanks[c[1]] hash[c[0]] = blank unless blank.nil? end hash.delete(:id) hash end |
.cast(klass, value) ⇒ Object
Casts a object type as a compatible type for redis, or reverses the process.
Examples:
#cast( Fixnum, "1" ) => 1
#cast( Array, [1,2,3] ) => "[1,2,3]"
#cast( Hash, {:a => 1, 'b' => "2", :c => ['c']} ) => "--- \nb: \"2\"\n:c: \n- c\n:a: 1\n"
#cast( Hash, "--- \nb: \"2\"\n:c: \n- c\n:a: 1\n" ) => {"b"=>"2", :c=>["c"], :a=>1}
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/redismodel.rb', line 62 def self.cast(klass, value) return value if value.nil? klass = klass.to_s v_class = value.class.to_s if klass == "Fixnum" && v_class == "String" value.to_i elsif (klass == "Array" || klass == "Hash") && v_class == "String" YAML.load(value) elsif (klass == "Array" || klass == "Hash") && (klass == v_class) value.to_yaml elsif klass == "DateTime" && v_class == "String" DateTime.parse(value) elsif klass == "DateTime" && v_class == "DateTime" value.to_s else value end end |
.config(hash = nil) ⇒ Object
Setter and getter for the config. Example:
class MyModel < RedisModel
config :host => "1.2.3.4",
:port => 5678
end
181 182 183 184 185 186 187 188 189 |
# File 'lib/redismodel.rb', line 181 def self.config(hash=nil) @_config ||= DEFAULT_CONFIG if hash.nil? return @_config else @_config = @_config.merge(hash) return true end end |
.connection(klass) ⇒ Object
42 43 44 45 46 47 |
# File 'lib/redismodel.rb', line 42 def self.connection(klass) hash = {} [:host, :port].each{|v| hash[v] = klass.config[v] unless klass.config[v].nil?} @connections ||= {} @connections[klass.to_s] ||= Redis.new(hash) end |
.count ⇒ Object
Returns the number of records for the model
280 281 282 |
# File 'lib/redismodel.rb', line 280 def self.count redis.get("#{klass}:_meta:count").to_i end |
.destroy(*ids) ⇒ Object
Destroys all records with the ids passed
272 273 274 275 276 |
# File 'lib/redismodel.rb', line 272 def self.destroy(*ids) ids.each do |id| klass.find(id).destroy end end |
.destroy_all ⇒ Object
Permamently deletes all records for the model
263 264 265 266 267 268 |
# File 'lib/redismodel.rb', line 263 def self.destroy_all redis.keys("#{klass}:*").each do |key| redis.del key end true end |
.find(id) ⇒ Object
Finds a record from it’s id
245 246 247 |
# File 'lib/redismodel.rb', line 245 def self.find(id) object = klass.new(:id => id) end |
.property(name, type) ⇒ Object
Defines a new property. Example:
class MyModel < RedisModel
property :name, String
property :age, Fixnum
end
199 200 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 |
# File 'lib/redismodel.rb', line 199 def self.property(name, type) properties[:id] = String unless properties[:id] properties[name] = type class_eval do define_method("#{name}=") do |str| set(name, str) end if type == Array || type == Hash case type.to_s when "Array" proxy = ArrayProxy when "Hash" proxy = HashProxy end define_method(name) do value = get(name) return value if value.is_a?(proxy) value.tap do |value| value.extend(proxy) value.instance_variable_set(:@__model__, self) value.instance_variable_set(:@__property__, name) end end else define_method(name) do get(name) end end eval "def self.find_by_#{name.to_s}(str); self.search('#{name.to_s}', str); end" end end |
.save! ⇒ Object
Saves the Redis database to disk
286 287 288 |
# File 'lib/redismodel.rb', line 286 def self.save! redis.bgsave == "Background saving started" end |
.search(property, value) ⇒ Object
Returns all records where the value of ‘property` matches `str`
251 252 253 254 255 256 257 258 259 |
# File 'lib/redismodel.rb', line 251 def self.search(property, value) arr = [] self.all.each do |record| if record.send(property) == value arr << record end end arr end |
.version ⇒ Object
49 50 51 |
# File 'lib/redismodel.rb', line 49 def self.version VERSION end |
Instance Method Details
#destroy ⇒ Object
Permamently deletes all traces of the record, and decrements the model count
161 162 163 164 165 166 |
# File 'lib/redismodel.rb', line 161 def destroy redis.keys("#{self.class}:#{id}:*").each do |key| redis.del key end redis.decr "#{self.class}:_meta:count" end |
#generate_uniq_token ⇒ Object
91 92 93 |
# File 'lib/redismodel.rb', line 91 def generate_uniq_token "#{MD5.hexdigest("#{self.class.to_s.downcase}-#{self.object_id}-#{rand**rand}-#{Time.now.to_f}")}" end |
#id ⇒ Object
169 170 171 |
# File 'lib/redismodel.rb', line 169 def id @_data['id'] end |
#inspect ⇒ Object
Custom model inspect in the format of:
#<MyModel:8a80300a9b id: "8a80300a9b...", created_at: "2010-08-01T01:32:11+01:00">
145 146 147 |
# File 'lib/redismodel.rb', line 145 def inspect "#<#{self.class}:#{self.id} #{self.class.properties.to_a.delete_if{|c| c[0] == :id}.map{|c| "#{c[0].to_s}: #{g=get(c[0]); v=g.inspect; g.class == String && v.size > 10 ? v[0..(v.size-2)]+'..."' : v}"}.join(", ")}>" end |
#redis ⇒ Object
86 87 88 |
# File 'lib/redismodel.rb', line 86 def redis self.class.redis end |
#reload ⇒ Object
Updates all keys from redis
151 152 153 154 155 156 |
# File 'lib/redismodel.rb', line 151 def reload self.class.properties.each do |property| self.get(property) end self end |