familia 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +15 -0
- data/Rakefile +3 -3
- data/VERSION.yml +1 -1
- data/familia.gemspec +11 -11
- data/lib/familia/core_ext.rb +85 -84
- data/lib/familia/object.rb +123 -83
- data/lib/familia/redisobject.rb +224 -53
- data/lib/familia/test_helpers.rb +0 -2
- data/lib/familia.rb +38 -43
- data/try/21_redis_object_zset_try.rb +1 -1
- data/try/24_redis_object_string_try.rb +1 -1
- data/try/30_familia_object_try.rb +2 -2
- metadata +13 -13
data/lib/familia/redisobject.rb
CHANGED
@@ -47,7 +47,7 @@ module Familia
|
|
47
47
|
end
|
48
48
|
|
49
49
|
attr_reader :name, :parent
|
50
|
-
|
50
|
+
attr_writer :redis
|
51
51
|
|
52
52
|
# +name+: If parent is set, this will be used as the suffix
|
53
53
|
# for rediskey. Otherwise this becomes the value of the key.
|
@@ -55,7 +55,20 @@ module Familia
|
|
55
55
|
#
|
56
56
|
# Options:
|
57
57
|
#
|
58
|
-
# :
|
58
|
+
# :class => A class that responds to Familia.load_method and
|
59
|
+
# Familia.dump_method. These will be used when loading and
|
60
|
+
# saving data from/to redis to unmarshal/marshal the class.
|
61
|
+
#
|
62
|
+
# :reference => When true the index of the given value will be
|
63
|
+
# stored rather than the marshaled value. This assumes that
|
64
|
+
# the marshaled object is stored at a separate key. When read,
|
65
|
+
# from_redis looks for that separate key and returns the
|
66
|
+
# unmarshaled object. :class must be specified. Default: false.
|
67
|
+
#
|
68
|
+
# :extend => Extend this instance with the functionality in an
|
69
|
+
# other module. Literally: "self.extend opts[:extend]".
|
70
|
+
#
|
71
|
+
# :parent => The Familia object that this redis object belongs
|
59
72
|
# to. This can be a class that includes Familia or an instance.
|
60
73
|
#
|
61
74
|
# :ttl => the time to live in seconds. When not nil, this will
|
@@ -64,10 +77,6 @@ module Familia
|
|
64
77
|
#
|
65
78
|
# :default => the default value (String-only)
|
66
79
|
#
|
67
|
-
# :class => A class that responds to Familia.load_method and
|
68
|
-
# Familia.dump_method. These will be used when loading and
|
69
|
-
# saving data from/to redis to unmarshal/marshal the class.
|
70
|
-
#
|
71
80
|
# :db => the redis database to use (ignored if :redis is used).
|
72
81
|
#
|
73
82
|
# :redis => an instance of Redis.
|
@@ -77,28 +86,60 @@ module Familia
|
|
77
86
|
def initialize name, opts={}
|
78
87
|
@name, @opts = name, opts
|
79
88
|
@name = @name.join(Familia.delim) if Array === @name
|
80
|
-
|
81
|
-
@opts[:
|
89
|
+
Familia.ld [name, opts, caller[0]].inspect
|
90
|
+
self.extend @opts[:extend] if Module === @opts[:extend]
|
91
|
+
@db = @opts.delete(:db)
|
92
|
+
@ttl = @opts.delete(:ttl)
|
82
93
|
@parent = @opts.delete(:parent)
|
83
|
-
@redis
|
84
|
-
@redis ||= @opts.delete(:redis) || Familia.redis(@opts[:db])
|
94
|
+
@redis ||= @opts.delete(:redis)
|
85
95
|
init if respond_to? :init
|
86
96
|
end
|
87
97
|
|
98
|
+
def redis
|
99
|
+
return @redis if @redis
|
100
|
+
parent? ? parent.redis : Familia.redis(db)
|
101
|
+
end
|
102
|
+
|
103
|
+
def ttl
|
104
|
+
@ttl || self.class.ttl
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the most likely value for db, checking (in this order):
|
108
|
+
# * the value from :class if it's a Familia object
|
109
|
+
# * the value from :parent
|
110
|
+
# * the value self.class.db
|
111
|
+
# * assumes the db is 0
|
112
|
+
#
|
113
|
+
# After this is called once, this method will always return the
|
114
|
+
# same value.
|
115
|
+
def db
|
116
|
+
return @db if @db
|
117
|
+
# Note it's important that we select this value at the last
|
118
|
+
# possible moment rather than in initialize b/c the value
|
119
|
+
# could be modified after that but before this is called.
|
120
|
+
if @opts[:class] && @opts[:class].ancestors.member?(Familia)
|
121
|
+
@db = @opts[:class].db
|
122
|
+
else
|
123
|
+
@db = parent? ? parent.db : self.class.db
|
124
|
+
end
|
125
|
+
@db ||= 0
|
126
|
+
@db
|
127
|
+
end
|
128
|
+
|
88
129
|
# returns a redis key based on the parent
|
89
130
|
# object so it will include the proper index.
|
90
131
|
def rediskey
|
91
|
-
parent? ? parent.rediskey(name) : Familia.
|
132
|
+
parent? ? parent.rediskey(name) : [name].flatten.compact.join(Familia.delim)
|
92
133
|
end
|
93
134
|
|
94
135
|
def parent?
|
95
|
-
Class === parent || parent.kind_of?(Familia)
|
136
|
+
Class === parent || Module === parent || parent.kind_of?(Familia)
|
96
137
|
end
|
97
138
|
|
98
139
|
def update_expiration(ttl=nil)
|
99
|
-
ttl ||= @opts[:ttl]
|
140
|
+
ttl ||= @opts[:ttl] || self.class.ttl
|
100
141
|
return unless ttl && ttl.to_i > 0
|
101
|
-
|
142
|
+
Familia.info "#{rediskey} to #{ttl}"
|
102
143
|
expire ttl.to_i
|
103
144
|
end
|
104
145
|
|
@@ -124,10 +165,10 @@ module Familia
|
|
124
165
|
#end
|
125
166
|
|
126
167
|
def exists?
|
127
|
-
!size.zero?
|
168
|
+
redis.exists(rediskey) && !size.zero?
|
128
169
|
end
|
129
170
|
|
130
|
-
def
|
171
|
+
def realttl
|
131
172
|
redis.ttl rediskey
|
132
173
|
end
|
133
174
|
|
@@ -139,17 +180,38 @@ module Familia
|
|
139
180
|
redis.expireat rediskey, unixtime
|
140
181
|
end
|
141
182
|
|
183
|
+
def dump_method
|
184
|
+
@opts[:dump_method] || Familia.dump_method
|
185
|
+
end
|
186
|
+
|
187
|
+
def load_method
|
188
|
+
@opts[:load_method] || Familia.load_method
|
189
|
+
end
|
190
|
+
|
142
191
|
def to_redis v
|
143
192
|
return v unless @opts[:class]
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
Familia.ld "No such method: #{v.class}.#{Familia.dump_method}"
|
193
|
+
case @opts[:class]
|
194
|
+
when String, Fixnum, Float, Gibbler::Digest
|
148
195
|
v
|
196
|
+
else
|
197
|
+
if @opts[:reference] == true
|
198
|
+
unless v.respond_to? :index
|
199
|
+
raise Familia::Problem, "#{v.class} does not have an index method"
|
200
|
+
end
|
201
|
+
unless v.kind_of?(Familia)
|
202
|
+
raise Familia::Problem, "#{v.class} is not Familia (#{name})"
|
203
|
+
end
|
204
|
+
v.index
|
205
|
+
elsif v.respond_to? dump_method
|
206
|
+
v.send dump_method
|
207
|
+
else
|
208
|
+
raise Familia::Problem, "No such method: #{v.class}.#{dump_method}"
|
209
|
+
end
|
149
210
|
end
|
150
211
|
end
|
151
212
|
|
152
213
|
def from_redis v
|
214
|
+
return @opts[:default] if v.nil?
|
153
215
|
return v unless @opts[:class]
|
154
216
|
case @opts[:class]
|
155
217
|
when String
|
@@ -157,13 +219,21 @@ module Familia
|
|
157
219
|
when Fixnum, Float
|
158
220
|
@opts[:class].induced_from v
|
159
221
|
else
|
160
|
-
if @opts[:
|
161
|
-
@opts[:class].
|
222
|
+
if @opts[:reference] == true
|
223
|
+
@opts[:class].from_redis v
|
162
224
|
else
|
163
|
-
|
164
|
-
|
225
|
+
if @opts[:class].respond_to? load_method
|
226
|
+
@opts[:class].send load_method, v
|
227
|
+
else
|
228
|
+
raise Familia::Problem, "No such method: #{@opts[:class]}##{load_method}"
|
229
|
+
end
|
165
230
|
end
|
166
231
|
end
|
232
|
+
rescue => ex
|
233
|
+
Familia.info v
|
234
|
+
Familia.info "Parse error for #{rediskey} (#{load_method}): #{ex.message}"
|
235
|
+
Familia.info ex.backtrace
|
236
|
+
nil
|
167
237
|
end
|
168
238
|
|
169
239
|
end
|
@@ -176,15 +246,22 @@ module Familia
|
|
176
246
|
end
|
177
247
|
alias_method :length, :size
|
178
248
|
|
179
|
-
def
|
180
|
-
|
249
|
+
def empty?
|
250
|
+
size == 0
|
251
|
+
end
|
252
|
+
|
253
|
+
def push *values
|
254
|
+
values.flatten.compact.each { |v| redis.rpush rediskey, to_redis(v) }
|
181
255
|
redis.ltrim rediskey, -@opts[:maxlength], -1 if @opts[:maxlength]
|
182
256
|
self
|
183
257
|
end
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
258
|
+
|
259
|
+
def << v
|
260
|
+
push v
|
261
|
+
end
|
262
|
+
|
263
|
+
def unshift *values
|
264
|
+
values.flatten.compact.each { |v| redis.lpush rediskey, to_redis(v) }
|
188
265
|
# TODO: test maxlength
|
189
266
|
redis.ltrim rediskey, 0, @opts[:maxlength] - 1 if @opts[:maxlength]
|
190
267
|
self
|
@@ -195,7 +272,7 @@ module Familia
|
|
195
272
|
end
|
196
273
|
|
197
274
|
def shift
|
198
|
-
from_redis redis.lpop(
|
275
|
+
from_redis redis.lpop(rediskey)
|
199
276
|
end
|
200
277
|
|
201
278
|
def [] idx, count=nil
|
@@ -217,12 +294,40 @@ module Familia
|
|
217
294
|
redis.lrem rediskey, count, to_redis(v)
|
218
295
|
end
|
219
296
|
alias_method :remove, :delete
|
297
|
+
alias_method :rem, :delete
|
298
|
+
alias_method :del, :delete
|
220
299
|
|
221
300
|
def range sidx=0, eidx=-1
|
222
|
-
|
223
|
-
|
301
|
+
redis.lrange(rediskey, sidx, eidx).collect do |v|
|
302
|
+
from_redis v
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def members count=-1
|
307
|
+
range 0, count
|
308
|
+
end
|
309
|
+
alias_method :all, :members
|
310
|
+
alias_method :to_a, :members
|
311
|
+
|
312
|
+
#def revmembers count=1 #TODO
|
313
|
+
# range -count, 0
|
314
|
+
#end
|
315
|
+
|
316
|
+
def each &blk
|
317
|
+
range.each &blk
|
318
|
+
end
|
319
|
+
|
320
|
+
def each_with_index &blk
|
321
|
+
range.each_with_index &blk
|
322
|
+
end
|
323
|
+
|
324
|
+
def collect &blk
|
325
|
+
range.collect &blk
|
326
|
+
end
|
327
|
+
|
328
|
+
def select &blk
|
329
|
+
range.select &blk
|
224
330
|
end
|
225
|
-
alias_method :to_a, :range
|
226
331
|
|
227
332
|
def at idx
|
228
333
|
from_redis redis.lindex(rediskey, idx)
|
@@ -272,19 +377,39 @@ module Familia
|
|
272
377
|
size == 0
|
273
378
|
end
|
274
379
|
|
275
|
-
def
|
276
|
-
redis.sadd rediskey, to_redis(v)
|
380
|
+
def add *values
|
381
|
+
values.flatten.compact.each { |v| redis.sadd rediskey, to_redis(v) }
|
277
382
|
self
|
278
383
|
end
|
279
|
-
|
384
|
+
|
385
|
+
def << v
|
386
|
+
add v
|
387
|
+
end
|
280
388
|
|
281
389
|
def members
|
282
|
-
|
283
|
-
|
390
|
+
redis.smembers(rediskey).collect do |v|
|
391
|
+
from_redis v
|
392
|
+
end
|
284
393
|
end
|
285
394
|
alias_method :all, :members
|
286
395
|
alias_method :to_a, :members
|
287
396
|
|
397
|
+
def each &blk
|
398
|
+
members.each &blk
|
399
|
+
end
|
400
|
+
|
401
|
+
def each_with_index &blk
|
402
|
+
members.each_with_index &blk
|
403
|
+
end
|
404
|
+
|
405
|
+
def collect &blk
|
406
|
+
members.collect &blk
|
407
|
+
end
|
408
|
+
|
409
|
+
def select &blk
|
410
|
+
members.select &blk
|
411
|
+
end
|
412
|
+
|
288
413
|
def member? v
|
289
414
|
redis.sismember rediskey, to_redis(v)
|
290
415
|
end
|
@@ -309,7 +434,7 @@ module Familia
|
|
309
434
|
end
|
310
435
|
|
311
436
|
def random
|
312
|
-
redis.srandmember
|
437
|
+
from_redis redis.srandmember(rediskey)
|
313
438
|
end
|
314
439
|
|
315
440
|
## Make the value stored at KEY identical to the given list
|
@@ -343,6 +468,10 @@ module Familia
|
|
343
468
|
end
|
344
469
|
alias_method :length, :size
|
345
470
|
|
471
|
+
def empty?
|
472
|
+
size == 0
|
473
|
+
end
|
474
|
+
|
346
475
|
# NOTE: The argument order is the reverse of #add
|
347
476
|
# e.g. obj.metrics[VALUE] = SCORE
|
348
477
|
def []= v, score
|
@@ -377,29 +506,52 @@ module Familia
|
|
377
506
|
ret.nil? ? nil : ret.to_i
|
378
507
|
end
|
379
508
|
|
380
|
-
def members opts={}
|
381
|
-
range 0,
|
509
|
+
def members count=-1, opts={}
|
510
|
+
range 0, count, opts
|
382
511
|
end
|
383
512
|
alias_method :to_a, :members
|
513
|
+
alias_method :all, :members
|
384
514
|
|
385
|
-
def
|
386
|
-
|
515
|
+
def revmembers count=-1, opts={}
|
516
|
+
revrange 0, count, opts
|
517
|
+
end
|
518
|
+
|
519
|
+
def each &blk
|
520
|
+
members.each &blk
|
521
|
+
end
|
522
|
+
|
523
|
+
def each_with_index &blk
|
524
|
+
members.each_with_index &blk
|
525
|
+
end
|
526
|
+
|
527
|
+
def collect &blk
|
528
|
+
members.collect &blk
|
529
|
+
end
|
530
|
+
|
531
|
+
def select &blk
|
532
|
+
members.select &blk
|
387
533
|
end
|
388
534
|
|
389
535
|
def range sidx, eidx, opts={}
|
390
536
|
opts[:with_scores] = true if opts[:withscores]
|
391
|
-
redis.zrange
|
537
|
+
redis.zrange(rediskey, sidx, eidx, opts).collect do |v|
|
538
|
+
from_redis v
|
539
|
+
end
|
392
540
|
end
|
393
541
|
|
394
|
-
def
|
542
|
+
def revrange sidx, eidx, opts={}
|
395
543
|
opts[:with_scores] = true if opts[:withscores]
|
396
|
-
redis.zrevrange
|
544
|
+
redis.zrevrange(rediskey, sidx, eidx, opts).collect do |v|
|
545
|
+
from_redis v
|
546
|
+
end
|
397
547
|
end
|
398
548
|
|
399
549
|
# e.g. obj.metrics.rangebyscore (now-12.hours), now, :limit => [0, 10]
|
400
550
|
def rangebyscore sscore, escore, opts={}
|
401
551
|
opts[:with_scores] = true if opts[:withscores]
|
402
|
-
redis.zrangebyscore
|
552
|
+
redis.zrangebyscore(rediskey, sscore, escore, opts).collect do |v|
|
553
|
+
from_redis v
|
554
|
+
end
|
403
555
|
end
|
404
556
|
|
405
557
|
def remrangebyrank srank, erank
|
@@ -426,7 +578,9 @@ module Familia
|
|
426
578
|
redis.zrem rediskey, to_redis(v)
|
427
579
|
end
|
428
580
|
alias_method :remove, :delete
|
429
|
-
|
581
|
+
alias_method :rem, :delete
|
582
|
+
alias_method :del, :delete
|
583
|
+
|
430
584
|
def at idx
|
431
585
|
range(idx, idx).first
|
432
586
|
end
|
@@ -451,14 +605,20 @@ module Familia
|
|
451
605
|
end
|
452
606
|
alias_method :length, :size
|
453
607
|
|
608
|
+
def empty?
|
609
|
+
size == 0
|
610
|
+
end
|
611
|
+
|
454
612
|
def []= n, v
|
455
613
|
redis.hset rediskey, n, to_redis(v)
|
456
614
|
end
|
615
|
+
alias_method :put, :[]=
|
457
616
|
alias_method :store, :[]=
|
458
617
|
|
459
618
|
def [] n
|
460
|
-
redis.hget
|
619
|
+
from_redis redis.hget(rediskey, n)
|
461
620
|
end
|
621
|
+
alias_method :get, :[]
|
462
622
|
|
463
623
|
def fetch n, default=nil
|
464
624
|
ret = self[n]
|
@@ -475,10 +635,13 @@ module Familia
|
|
475
635
|
end
|
476
636
|
|
477
637
|
def values
|
478
|
-
redis.hvals
|
638
|
+
redis.hvals(rediskey).collect do |v|
|
639
|
+
from_redis v
|
640
|
+
end
|
479
641
|
end
|
480
642
|
|
481
643
|
def all
|
644
|
+
# TODO: from_redis
|
482
645
|
redis.hgetall rediskey
|
483
646
|
end
|
484
647
|
alias_method :to_hash, :all
|
@@ -516,7 +679,9 @@ module Familia
|
|
516
679
|
alias_method :merge!, :update
|
517
680
|
|
518
681
|
def values_at *names
|
519
|
-
redis.hmget
|
682
|
+
redis.hmget(rediskey, *names.flatten.compact).collect do |v|
|
683
|
+
from_redis v
|
684
|
+
end
|
520
685
|
end
|
521
686
|
|
522
687
|
Familia::RedisObject.register self, :hash
|
@@ -532,10 +697,15 @@ module Familia
|
|
532
697
|
end
|
533
698
|
alias_method :length, :size
|
534
699
|
|
700
|
+
def empty?
|
701
|
+
size == 0
|
702
|
+
end
|
703
|
+
|
535
704
|
def value
|
536
705
|
redis.setnx rediskey, @opts[:default] if @opts[:default]
|
537
|
-
redis.get
|
706
|
+
from_redis redis.get(rediskey)
|
538
707
|
end
|
708
|
+
alias_method :content, :value
|
539
709
|
alias_method :get, :value
|
540
710
|
|
541
711
|
def to_s
|
@@ -605,3 +775,4 @@ module Familia
|
|
605
775
|
end
|
606
776
|
|
607
777
|
end
|
778
|
+
|
data/lib/familia/test_helpers.rb
CHANGED
@@ -12,7 +12,6 @@ class Bone < Storable
|
|
12
12
|
string :value, :default => "GREAT!"
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
15
|
class Session < Storable
|
17
16
|
include Familia
|
18
17
|
index :sessid
|
@@ -22,7 +21,6 @@ class Session < Storable
|
|
22
21
|
ttl 60 # seconds to live
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
24
|
class Customer < Storable
|
27
25
|
include Familia
|
28
26
|
index :custid
|
data/lib/familia.rb
CHANGED
@@ -22,20 +22,19 @@ module Familia
|
|
22
22
|
include Gibbler::Complex
|
23
23
|
@secret = '1-800-AWESOME' # Should be modified via Familia.secret = ''
|
24
24
|
@apiversion = nil
|
25
|
-
@uri = URI.parse 'redis://
|
25
|
+
@uri = URI.parse 'redis://127.0.0.1'
|
26
26
|
@delim = ':'
|
27
27
|
@clients = {}
|
28
28
|
@classes = []
|
29
|
-
@conf = {}
|
30
29
|
@suffix = :object.freeze
|
31
30
|
@index = :id.freeze
|
32
31
|
@debug = false.freeze
|
33
32
|
@dump_method = :to_json
|
34
33
|
@load_method = :from_json
|
35
34
|
class << self
|
36
|
-
attr_reader :
|
35
|
+
attr_reader :classes, :clients, :uri
|
37
36
|
attr_accessor :debug, :secret, :delim, :dump_method, :load_method
|
38
|
-
attr_writer :apiversion
|
37
|
+
attr_writer :apiversion
|
39
38
|
def debug?() @debug == true end
|
40
39
|
def info *msg
|
41
40
|
STDERR.puts *msg
|
@@ -48,49 +47,34 @@ module Familia
|
|
48
47
|
info "%s (%d:%s): %s" % [label, Thread.current.object_id, redis_client.object_id, ident]
|
49
48
|
info " +-> %s" % [context].flatten[0..3].join("\n ") if context
|
50
49
|
end
|
51
|
-
def uri
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
uri = URI.parse @uri.to_s
|
56
|
-
uri.db = db
|
57
|
-
uri
|
58
|
-
end
|
59
|
-
end
|
60
|
-
def apiversion(r=nil, &blk)
|
61
|
-
if blk.nil?
|
62
|
-
@apiversion = r if r;
|
63
|
-
else
|
64
|
-
tmp = @apiversion
|
65
|
-
@apiversion = r
|
66
|
-
blk.call
|
67
|
-
@apiversion = tmp
|
68
|
-
end
|
69
|
-
@apiversion
|
70
|
-
end
|
71
|
-
def conf=(conf={})
|
72
|
-
@conf = conf
|
73
|
-
@uri = Redis.uri(@conf).freeze
|
74
|
-
connect @uri
|
75
|
-
@conf
|
50
|
+
def uri= v
|
51
|
+
v = URI.parse v unless URI === v
|
52
|
+
@uri = v
|
76
53
|
end
|
54
|
+
# A convenience method for returning the appropriate Redis
|
55
|
+
# connection. If +uri+ is an Integer, we'll treat it as a
|
56
|
+
# database number. If it's a String, we'll treat it as a
|
57
|
+
# full URI (e.g. redis://1.2.3.4/15).
|
58
|
+
# Otherwise we'll return the default connection.
|
77
59
|
def redis(uri=nil)
|
78
60
|
if Integer === uri
|
79
|
-
|
80
|
-
|
81
|
-
uri
|
61
|
+
tmp = Familia.uri
|
62
|
+
tmp.db = uri
|
63
|
+
uri = tmp
|
64
|
+
elsif String === uri
|
65
|
+
uri &&= URI.parse uri
|
82
66
|
end
|
83
67
|
uri ||= Familia.uri
|
84
68
|
connect(uri) unless @clients[uri.serverid]
|
85
|
-
#STDERR.puts "REDIS: #{uri} #{caller[0]}" if Familia.debug?
|
86
69
|
@clients[uri.serverid]
|
87
70
|
end
|
88
|
-
def connect(uri=nil
|
71
|
+
def connect(uri=nil)
|
89
72
|
uri &&= URI.parse uri if String === uri
|
90
73
|
uri ||= Familia.uri
|
91
|
-
|
92
|
-
|
93
|
-
|
74
|
+
conf = uri.conf
|
75
|
+
conf[:thread_safe] = true
|
76
|
+
client = Redis.new conf
|
77
|
+
Familia.trace :CONNECT, client, conf.inspect, caller[0..3] if Familia.debug
|
94
78
|
@clients[uri.serverid] = client
|
95
79
|
end
|
96
80
|
def reconnect_all!
|
@@ -107,17 +91,23 @@ module Familia
|
|
107
91
|
def default_suffix=(a) @suffix = a end
|
108
92
|
def index(r=nil) @index = r if r; @index end
|
109
93
|
def index=(r) @index = r; r end
|
94
|
+
def join(*r) r.join(Familia.delim) end
|
110
95
|
def split(r) r.split(Familia.delim) end
|
111
96
|
def rediskey *args
|
112
97
|
el = args.flatten.compact
|
113
98
|
el.unshift @apiversion unless @apiversion.nil?
|
114
99
|
el.join(Familia.delim)
|
115
100
|
end
|
116
|
-
def
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
101
|
+
def apiversion(r=nil, &blk)
|
102
|
+
if blk.nil?
|
103
|
+
@apiversion = r if r;
|
104
|
+
else
|
105
|
+
tmp = @apiversion
|
106
|
+
@apiversion = r
|
107
|
+
blk.call
|
108
|
+
@apiversion = tmp
|
109
|
+
end
|
110
|
+
@apiversion
|
121
111
|
end
|
122
112
|
end
|
123
113
|
|
@@ -138,7 +128,12 @@ module Familia
|
|
138
128
|
obj.send :include, Familia::InstanceMethods
|
139
129
|
obj.send :include, Gibbler::Complex
|
140
130
|
obj.extend Familia::ClassMethods
|
141
|
-
obj.
|
131
|
+
obj.class_zset :instances, :class => obj, :reference => true
|
132
|
+
# :object is a special redis object because its reserved
|
133
|
+
# for storing the marshaled instance data (e.g. to_json).
|
134
|
+
# When it isn't defined explicitly we define it here b/c
|
135
|
+
# it's assumed to exist in other places (see #save).
|
136
|
+
obj.string :object, :class => obj unless obj.redis_object? :object
|
142
137
|
Familia.classes << obj
|
143
138
|
end
|
144
139
|
|
@@ -16,7 +16,7 @@ require 'familia/test_helpers'
|
|
16
16
|
#=> ['metric0', 'metric1', 'metric2', 'metric3', 'metric4']
|
17
17
|
|
18
18
|
## Familia::SortedSet#members
|
19
|
-
@a.metrics.
|
19
|
+
@a.metrics.revmembers
|
20
20
|
#=> ['metric4', 'metric3', 'metric2', 'metric1', 'metric0']
|
21
21
|
|
22
22
|
## Familia::SortedSet#rank
|