Class: Queris::Model
Constant Summary
Constants included
from Queris
VERSION
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
included
#get_cached_attribute, included
Methods included from Queris
add_redis, all_redises, build_missing_indices!, clear!, clear_cache!, clear_queries!, debug?, digest, disconnect, duplicate_redis_client, from_redis_float, import_lua_script, included, info, load_lua_script, #log_stats_per_request!, #log_stats_per_request?, model, rebuild!, reconnect, redis_prefix, redis_role, redises, register_model, run_script, script, script_hash, #stats, to_redis_float, #track_stats!, #track_stats?
Constructor Details
#initialize(id = nil, arg = {}) ⇒ Model
Returns a new instance of Model.
205
206
207
208
209
210
211
212
|
# File 'lib/queris/model.rb', line 205
def initialize(id=nil, arg={})
@attributes = {}
@attributes_to_save = {}
@attributes_to_incr = {}
@attributes_were = {}
@redis = (arg || {})[:redis]
set_id id unless id.nil?
end
|
Instance Attribute Details
#id ⇒ Object
Returns the value of attribute id.
5
6
7
|
# File 'lib/queris/model.rb', line 5
def id
@id
end
|
#query_score ⇒ Object
Returns the value of attribute query_score.
6
7
8
|
# File 'lib/queris/model.rb', line 6
def query_score
@query_score
end
|
Class Method Details
.attr_val_block ⇒ Object
12
13
14
|
# File 'lib/queris/model.rb', line 12
def self.attr_val_block
@attr_val_block ||= {}
end
|
.attribute(*arg) ⇒ Object
Also known as:
attr
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/queris/model.rb', line 50
def attribute(*arg)
if arg.first
attr_name = arg.first.to_sym
end
if arg.count == 2
if Hash===arg.last
opt=arg.last
else
raise "Invalid \"attribute\" params" unless arg.last.nil?
end
elsif arg.count > 2
raise "Too many arguments for \"attribute\""
end
@attributes ||= [] raise ArgumentError, "Attribute #{attr_name} already exists in Queris model #{self.name}." if @attributes.member? attr_name
if block_given?
bb=Proc.new
self.attr_val_block[attr_name]=bb
end
define_method "#{attr_name}" do |no_attr_load=false|
binding.pry if @attributes.nil?
1
if (val = @attributes[attr_name]).nil? && !@loaded && !no_attr_load && !noload?
load
send attr_name, true
else
val
end
end
define_method "#{attr_name}=" do |val| if opt
type = opt[:type]
unless val.nil?
if type == Float
val=Float(val)
elsif type == String
val=val.to_s
elsif type == Fixnum
val = val.to_s if Symbol === val
val=val.to_i
elsif type == Symbol
val = val.to_s if Numeric > val.class val=val.to_sym
elsif type == :boolean || type == :bool
if val=="1" || val==1 || val=="true"
val=true
elsif val=="0" || val==0 || val=="false"
val=false
else
val=val ? true : false
end
elsif type == :flag
val=val ? true : nil
elsif type.nil?
else
raise "Unknown attribute type #{opt[:type]}"
end
end
end
if self.class.attr_val_block[attr_name]
val = self.class.attr_val_block[attr_name].call(val, self)
end
if !@loading
if @attributes_were[attr_name].nil?
@attributes_were[attr_name] = @attributes[attr_name]
end
@attributes_to_save[attr_name]=val
end
@attributes[attr_name]=val
end
define_method "#{attr_name}_was" do
@attributes_were[attr_name]
end
define_method "#{attr_name}_was=" do |val|
@attributes_were[attr_name]=val
end
private "#{attr_name}_was="
attributes << attr_name
end
|
.attributes(*arg) ⇒ Object
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/queris/model.rb', line 32
def attributes(*arg)
if Hash===arg.last
attributes = arg[0..-2]
opt=arg.last
else
attributes= arg
end
unless attributes.nil?
attributes.each do |attr|
attribute attr, opt
if block_given?
self.attr_val_block[attr.to_sym]=Proc.new
end
end
end
@attributes
end
|
.attrs ⇒ Object
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
# File 'lib/queris/model.rb', line 133
def attributes(*arg)
if Hash===arg.last
attributes = arg[0..-2]
opt=arg.last
else
attributes= arg
end
unless attributes.nil?
attributes.each do |attr|
attribute attr, opt
if block_given?
self.attr_val_block[attr.to_sym]=Proc.new
end
end
end
@attributes
end
|
.expire(seconds = nil) ⇒ Object
136
137
138
139
140
141
142
143
|
# File 'lib/queris/model.rb', line 136
def expire(seconds=nil)
unless seconds.nil?
@expire = seconds
else
@expire
end
end
|
.find(id, opt = {}) ⇒ Object
Also known as:
find_cached
145
146
147
148
|
# File 'lib/queris/model.rb', line 145
def find(id, opt={})
got= get id, opt
got.loaded? ? got : nil
end
|
.find_all ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
|
# File 'lib/queris/model.rb', line 162
def find_all keys = redis.keys "#{prefix}*"
objs = []
keys.map! do |key|
begin
found = self.find key[prefix.length..-1]
objs << found if found
rescue Exception => e
nil
end
end
objs
end
|
.get(id, opt = nil) ⇒ Object
151
152
153
154
155
156
157
158
159
160
|
# File 'lib/queris/model.rb', line 151
def get(id, opt=nil)
ret=new(id)
opt ||= {}
if opt[:redis]
ret.load(nil, redis: opt[:redis])
else
ret.load
end
ret
end
|
.keyf ⇒ Object
27
28
29
|
# File 'lib/queris/model.rb', line 27
def keyf
"#{prefix}%s"
end
|
.prefix ⇒ Object
24
25
26
|
# File 'lib/queris/model.rb', line 24
def prefix
@prefix ||= "#{Queris.redis_prefix}#{self.superclass.name.split('::').last}:#{self.name}:"
end
|
.redis(redis_client = nil) ⇒ Object
17
18
19
20
21
22
|
# File 'lib/queris/model.rb', line 17
def redis(redis_client=nil)
if redis_client.kind_of? Redis
@redis = redis_client
end
@redis || Queris.redis
end
|
.restore(hash, id) ⇒ Object
176
177
178
|
# File 'lib/queris/model.rb', line 176
def restore(hash, id)
new(id).load(hash)
end
|
Instance Method Details
#as_json(*arg) ⇒ Object
414
415
416
417
418
|
# File 'lib/queris/model.rb', line 414
def as_json(*arg)
rest={id: self.id}
rest[:query_score]= self.query_score if query_score
@attributes.merge(rest)
end
|
#attribute_diff(attr) ⇒ Object
292
293
294
|
# File 'lib/queris/model.rb', line 292
def attribute_diff(attr)
@attributes_to_incr[attr.to_sym]
end
|
#changed ⇒ Object
list of changed attributes
296
297
298
299
300
|
# File 'lib/queris/model.rb', line 296
def changed
delta = (@attributes_to_save.keys + @attributes_to_incr.keys)
delta.uniq!
delta
end
|
#changed? ⇒ Boolean
302
303
304
|
# File 'lib/queris/model.rb', line 302
def changed?
@attributes_to_save.empty? && @attributes_to_incr.empty?
end
|
#delete ⇒ Object
314
315
316
317
318
319
320
321
322
323
324
|
# File 'lib/queris/model.rb', line 314
def delete
noload do
key = hash_key
redis.multi do
redis.del key
delete_redis_indices if defined? :delete_redis_indices
end
end
@deleted= true
self
end
|
#deleted? ⇒ Boolean
310
311
312
|
# File 'lib/queris/model.rb', line 310
def deleted?
@deleted && self
end
|
#hash_key(custom_id = nil) ⇒ Object
Also known as:
key
402
403
404
405
406
407
|
# File 'lib/queris/model.rb', line 402
def hash_key(custom_id=nil)
if custom_id.nil? && id.nil?
@id = new_id
end
@hash_key ||= "#{prefix}#{custom_id || id}"
end
|
#import(attrs = {}) ⇒ Object
382
383
384
385
386
387
388
|
# File 'lib/queris/model.rb', line 382
def import(attrs={})
attrs.each do |attr_name, val|
send "#{attr_name}=", val
@attributes_were[attr_name] = val
end
self
end
|
#increment(attr_name, delta_val) ⇒ Object
280
281
282
283
284
285
286
287
288
289
|
# File 'lib/queris/model.rb', line 280
def increment(attr_name, delta_val)
raise ArgumentError, "Can't increment attribute #{attr_name} because it is used by at least one non-incrementable index." unless self.class.can_increment_attribute? attr_name
raise ArgumentError, "Can't increment attribute #{attr_name} by non-numeric value <#{delta_val}>. Increment only by numbers, please." unless delta_val.kind_of? Numeric
@attributes_to_incr[attr_name.to_sym]=delta_val
unless (val = send(attr_name, true)).nil?
send "#{attr_name}=", val + delta_val
end
self
end
|
#load(hash = nil, opt = {}) ⇒ Object
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
|
# File 'lib/queris/model.rb', line 326
def load(hash=nil, opt={})
raise SchemaError, "Can't load #{self.class.name} with id #{id} -- model was specified index_only, so it was never saved." if index_only
unless hash
hash_future, hash_exists = nil, nil
hash_key
(opt[:redis] || redis).multi do |r|
hash_future = r.hgetall hash_key
hash_exists = r.exists hash_key
end
if hash_exists.value
hash = hash_future.value
elsif not hash
return nil
end
end
case hash
when Array
attr_name= nil
hash.each_with_index do |v, i|
if i % 2 == 0
attr_name = v
next
else
raw_load_attr(attr_name, v, !opt[:nil_only])
end
end
@loaded = true
when Hash
hash.each do |k, v|
raw_load_attr(k, v, !opt[:nil_only])
end
@loaded = true
else
raise Queris::ArgumentError, "Invalid thing to load"
end
self
end
|
#load_missing ⇒ Object
load only missing attributes
365
366
367
|
# File 'lib/queris/model.rb', line 365
def load_missing load nil, nil_only: true
end
|
#loaded? ⇒ Boolean
306
307
308
|
# File 'lib/queris/model.rb', line 306
def loaded?
@loaded && self
end
|
#noload ⇒ Object
420
421
422
423
424
425
426
|
# File 'lib/queris/model.rb', line 420
def noload
@noload||=0
@noload+=1
ret = yield
@noload-=1
ret
end
|
#noload? ⇒ Boolean
427
428
429
|
# File 'lib/queris/model.rb', line 427
def noload?
(@noload ||0) > 0
end
|
#redis(no_fallback = false) ⇒ Object
394
395
396
397
398
399
400
|
# File 'lib/queris/model.rb', line 394
def redis(no_fallback=false)
if no_fallback
@redis || self.class.redis
else
@redis || self.class.redis || Queris.redis
end
end
|
#redis=(r) ⇒ Object
391
392
393
|
# File 'lib/queris/model.rb', line 391
def redis=(r)
@redis=r
end
|
#save ⇒ Object
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
# File 'lib/queris/model.rb', line 227
def save
key = hash_key noload do
run_callbacks :before_save
begin
if @attributes_to_save.length > 0
attrs_to_save = @attributes_to_save.keys
bulk_response = redis.pipelined do
redis.watch key
redis.hmget key, *attrs_to_save
end
current_saved_attr_vals = bulk_response.last
attrs_to_save.each_with_index do |attr,i| val=current_saved_attr_vals[i]
@attributes_were[attr]=val
end
run_callbacks :during_save
bulk_response = redis.multi do |r|
unless index_only
@attributes_to_incr.each do |attr, incr_by_val|
r.hincrbyfloat key, attr, incr_by_val unless (val = send(attr, true)).nil?
@attributes_were[attr]=val
end
end
r.mapped_hmset key, @attributes_to_save
@attributes_to_save.each do |attr, val|
r.hdel(key, attr) if val.nil?
end
expire_sec = self.class.expire
end
update_redis_indices if defined? :update_redis_indices
@attributes_to_save.each {|attr, val| @attributes_were[attr]=val }
r.expire key, expire_sec unless expire_sec.nil?
run_callbacks :during_save_multi, r
end
end
end while @attributes_to_save.length > 0 && bulk_response.nil?
@attributes_to_save.clear
@attributes_to_incr.clear
ret= self
run_callbacks :after_save, redis
ret
end
end
|
#set_id(nid, overwrite = false) ⇒ Object
214
215
216
217
218
219
220
221
222
|
# File 'lib/queris/model.rb', line 214
def set_id(nid, overwrite=false)
noload do
raise Error, "id cannot be a Hash" if Hash === nid
raise Error, "id cannot be an Array" if Array === nid
raise Error, "id already exists and is #{self.id}" unless overwrite || self.id.nil?
end
@id= nid
self
end
|
#to_json(*arg) ⇒ Object
410
411
412
|
# File 'lib/queris/model.rb', line 410
def to_json(*arg)
as_json.to_json(*arg)
end
|
#while_loading ⇒ Object
193
194
195
196
197
198
|
# File 'lib/queris/model.rb', line 193
def while_loading
loading_was=@loading
@loading=true
yield
@loading=loading_was
end
|