familia 0.10.2 → 1.0.0.pre.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.pre-commit-config.yaml +1 -1
- data/.rubocop.yml +75 -0
- data/.rubocop_todo.yml +63 -0
- data/Gemfile +6 -1
- data/Gemfile.lock +47 -15
- data/README.md +65 -13
- data/VERSION.yml +4 -3
- data/familia.gemspec +18 -13
- data/lib/familia/base.rb +33 -0
- data/lib/familia/connection.rb +87 -0
- data/lib/familia/core_ext.rb +119 -124
- data/lib/familia/errors.rb +33 -0
- data/lib/familia/features/api_version.rb +19 -0
- data/lib/familia/features/atomic_saves.rb +8 -0
- data/lib/familia/features/quantizer.rb +35 -0
- data/lib/familia/features/safe_dump.rb +194 -0
- data/lib/familia/features.rb +51 -0
- data/lib/familia/horreum/class_methods.rb +292 -0
- data/lib/familia/horreum/commands.rb +106 -0
- data/lib/familia/horreum/relations_management.rb +141 -0
- data/lib/familia/horreum/serialization.rb +193 -0
- data/lib/familia/horreum/settings.rb +63 -0
- data/lib/familia/horreum/utils.rb +44 -0
- data/lib/familia/horreum.rb +248 -0
- data/lib/familia/logging.rb +232 -0
- data/lib/familia/redistype/commands.rb +56 -0
- data/lib/familia/redistype/serialization.rb +110 -0
- data/lib/familia/redistype.rb +185 -0
- data/lib/familia/refinements.rb +88 -0
- data/lib/familia/settings.rb +38 -0
- data/lib/familia/types/hashkey.rb +107 -0
- data/lib/familia/types/list.rb +155 -0
- data/lib/familia/types/sorted_set.rb +234 -0
- data/lib/familia/types/string.rb +115 -0
- data/lib/familia/types/unsorted_set.rb +123 -0
- data/lib/familia/utils.rb +125 -0
- data/lib/familia/version.rb +25 -0
- data/lib/familia.rb +57 -161
- data/lib/redis_middleware.rb +109 -0
- data/try/00_familia_try.rb +5 -4
- data/try/10_familia_try.rb +21 -17
- data/try/20_redis_type_try.rb +67 -0
- data/try/{21_redis_object_zset_try.rb → 21_redis_type_zset_try.rb} +2 -2
- data/try/{22_redis_object_set_try.rb → 22_redis_type_set_try.rb} +2 -2
- data/try/{23_redis_object_list_try.rb → 23_redis_type_list_try.rb} +2 -2
- data/try/{24_redis_object_string_try.rb → 24_redis_type_string_try.rb} +6 -6
- data/try/{25_redis_object_hash_try.rb → 25_redis_type_hash_try.rb} +3 -3
- data/try/26_redis_bool_try.rb +10 -6
- data/try/27_redis_horreum_try.rb +93 -0
- data/try/30_familia_object_try.rb +21 -20
- data/try/35_feature_safedump_try.rb +83 -0
- data/try/40_customer_try.rb +140 -0
- data/try/41_customer_safedump_try.rb +86 -0
- data/try/test_helpers.rb +194 -0
- metadata +51 -47
- data/lib/familia/helpers.rb +0 -70
- data/lib/familia/object.rb +0 -533
- data/lib/familia/redisobject.rb +0 -1017
- data/lib/familia/test_helpers.rb +0 -40
- data/lib/familia/tools.rb +0 -67
- data/try/20_redis_object_try.rb +0 -44
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Familia
|
4
|
+
class HashKey < RedisType
|
5
|
+
def size
|
6
|
+
redis.hlen rediskey
|
7
|
+
end
|
8
|
+
alias length size
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
size.zero?
|
12
|
+
end
|
13
|
+
|
14
|
+
# +return+ [Integer] Returns 1 if the field is new and added, 0 if the
|
15
|
+
# field already existed and the value was updated.
|
16
|
+
def []=(field, val)
|
17
|
+
ret = redis.hset rediskey, field, to_redis(val)
|
18
|
+
update_expiration
|
19
|
+
ret
|
20
|
+
rescue TypeError => e
|
21
|
+
Familia.le "[hset]= #{e.message}"
|
22
|
+
Familia.ld "[hset]= #{rediskey} #{field}=#{val}" if Familia.debug
|
23
|
+
echo :hset, caller(1..1).first if Familia.debug # logs via echo to redis and back
|
24
|
+
klass = val.class
|
25
|
+
msg = "Cannot store #{field} => #{val.inspect} (#{klass}) in #{rediskey}"
|
26
|
+
raise e.class, msg
|
27
|
+
end
|
28
|
+
alias put []=
|
29
|
+
alias store []=
|
30
|
+
|
31
|
+
def [](field)
|
32
|
+
from_redis redis.hget(rediskey, field)
|
33
|
+
end
|
34
|
+
alias get []
|
35
|
+
|
36
|
+
def fetch(field, default = nil)
|
37
|
+
ret = self[field]
|
38
|
+
if ret.nil?
|
39
|
+
raise IndexError, "No such index for: #{field}" if default.nil?
|
40
|
+
|
41
|
+
default
|
42
|
+
else
|
43
|
+
ret
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def keys
|
48
|
+
redis.hkeys rediskey
|
49
|
+
end
|
50
|
+
|
51
|
+
def values
|
52
|
+
el = redis.hvals(rediskey)
|
53
|
+
multi_from_redis(*el)
|
54
|
+
end
|
55
|
+
|
56
|
+
def hgetall
|
57
|
+
# TODO: Use from_redis. Also name `all` is confusing with
|
58
|
+
# Onetime::Customer.all which returns all customers.
|
59
|
+
redis.hgetall rediskey
|
60
|
+
end
|
61
|
+
alias all hgetall
|
62
|
+
|
63
|
+
def has_key?(field)
|
64
|
+
redis.hexists rediskey, field
|
65
|
+
end
|
66
|
+
alias include? has_key?
|
67
|
+
alias member? has_key?
|
68
|
+
|
69
|
+
def delete(field)
|
70
|
+
redis.hdel rediskey, field
|
71
|
+
end
|
72
|
+
alias remove delete
|
73
|
+
alias rem delete
|
74
|
+
alias del delete
|
75
|
+
|
76
|
+
def increment(field, by = 1)
|
77
|
+
redis.hincrby(rediskey, field, by).to_i
|
78
|
+
end
|
79
|
+
alias incr increment
|
80
|
+
alias incrby increment
|
81
|
+
|
82
|
+
def decrement(field, by = 1)
|
83
|
+
increment field, -by
|
84
|
+
end
|
85
|
+
alias decr decrement
|
86
|
+
alias decrby decrement
|
87
|
+
|
88
|
+
def update(hsh = {})
|
89
|
+
raise ArgumentError, 'Argument to bulk_set must be a hash' unless hsh.is_a?(Hash)
|
90
|
+
|
91
|
+
data = hsh.inject([]) { |ret, pair| ret << [pair[0], to_redis(pair[1])] }.flatten
|
92
|
+
|
93
|
+
ret = redis.hmset(rediskey, *data)
|
94
|
+
update_expiration
|
95
|
+
ret
|
96
|
+
end
|
97
|
+
alias merge! update
|
98
|
+
|
99
|
+
def values_at *fields
|
100
|
+
el = redis.hmget(rediskey, *fields.flatten.compact)
|
101
|
+
multi_from_redis(*el)
|
102
|
+
end
|
103
|
+
|
104
|
+
Familia::RedisType.register self, :hash # legacy, deprecated
|
105
|
+
Familia::RedisType.register self, :hashkey
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Familia
|
4
|
+
class List < RedisType
|
5
|
+
def size
|
6
|
+
redis.llen rediskey
|
7
|
+
end
|
8
|
+
alias length size
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
size.zero?
|
12
|
+
end
|
13
|
+
|
14
|
+
def push *values
|
15
|
+
echo :push, caller(1..1).first if Familia.debug
|
16
|
+
values.flatten.compact.each { |v| redis.rpush rediskey, to_redis(v) }
|
17
|
+
redis.ltrim rediskey, -@opts[:maxlength], -1 if @opts[:maxlength]
|
18
|
+
update_expiration
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def <<(val)
|
23
|
+
push val
|
24
|
+
end
|
25
|
+
alias add <<
|
26
|
+
|
27
|
+
def unshift *values
|
28
|
+
values.flatten.compact.each { |v| redis.lpush rediskey, to_redis(v) }
|
29
|
+
# TODO: test maxlength
|
30
|
+
redis.ltrim rediskey, 0, @opts[:maxlength] - 1 if @opts[:maxlength]
|
31
|
+
update_expiration
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def pop
|
36
|
+
from_redis redis.rpop(rediskey)
|
37
|
+
end
|
38
|
+
|
39
|
+
def shift
|
40
|
+
from_redis redis.lpop(rediskey)
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](idx, count = nil)
|
44
|
+
if idx.is_a? Range
|
45
|
+
range idx.first, idx.last
|
46
|
+
elsif count
|
47
|
+
case count <=> 0
|
48
|
+
when 1 then range(idx, idx + count - 1)
|
49
|
+
when 0 then []
|
50
|
+
when -1 then nil
|
51
|
+
end
|
52
|
+
else
|
53
|
+
at idx
|
54
|
+
end
|
55
|
+
end
|
56
|
+
alias slice []
|
57
|
+
|
58
|
+
def delete(v, count = 0)
|
59
|
+
redis.lrem rediskey, count, to_redis(v)
|
60
|
+
end
|
61
|
+
alias remove delete
|
62
|
+
alias rem delete
|
63
|
+
alias del delete
|
64
|
+
|
65
|
+
def range(sidx = 0, eidx = -1)
|
66
|
+
el = rangeraw sidx, eidx
|
67
|
+
multi_from_redis(*el)
|
68
|
+
end
|
69
|
+
|
70
|
+
def rangeraw(sidx = 0, eidx = -1)
|
71
|
+
redis.lrange(rediskey, sidx, eidx)
|
72
|
+
end
|
73
|
+
|
74
|
+
def members(count = -1)
|
75
|
+
echo :members, caller(1..1).first if Familia.debug
|
76
|
+
count -= 1 if count.positive?
|
77
|
+
range 0, count
|
78
|
+
end
|
79
|
+
alias all members
|
80
|
+
alias to_a members
|
81
|
+
|
82
|
+
def membersraw(count = -1)
|
83
|
+
count -= 1 if count.positive?
|
84
|
+
rangeraw 0, count
|
85
|
+
end
|
86
|
+
|
87
|
+
def each(&blk)
|
88
|
+
range.each(&blk)
|
89
|
+
end
|
90
|
+
|
91
|
+
def each_with_index(&blk)
|
92
|
+
range.each_with_index(&blk)
|
93
|
+
end
|
94
|
+
|
95
|
+
def eachraw(&blk)
|
96
|
+
rangeraw.each(&blk)
|
97
|
+
end
|
98
|
+
|
99
|
+
def eachraw_with_index(&blk)
|
100
|
+
rangeraw.each_with_index(&blk)
|
101
|
+
end
|
102
|
+
|
103
|
+
def collect(&blk)
|
104
|
+
range.collect(&blk)
|
105
|
+
end
|
106
|
+
|
107
|
+
def select(&blk)
|
108
|
+
range.select(&blk)
|
109
|
+
end
|
110
|
+
|
111
|
+
def collectraw(&blk)
|
112
|
+
rangeraw.collect(&blk)
|
113
|
+
end
|
114
|
+
|
115
|
+
def selectraw(&blk)
|
116
|
+
rangeraw.select(&blk)
|
117
|
+
end
|
118
|
+
|
119
|
+
def at(idx)
|
120
|
+
from_redis redis.lindex(rediskey, idx)
|
121
|
+
end
|
122
|
+
|
123
|
+
def first
|
124
|
+
at 0
|
125
|
+
end
|
126
|
+
|
127
|
+
def last
|
128
|
+
at(-1)
|
129
|
+
end
|
130
|
+
|
131
|
+
# TODO: def replace
|
132
|
+
## Make the value stored at KEY identical to the given list
|
133
|
+
# define_method :"#{name}_sync" do |*latest|
|
134
|
+
# latest = latest.flatten.compact
|
135
|
+
# # Do nothing if we're given an empty Array.
|
136
|
+
# # Otherwise this would clear all current values
|
137
|
+
# if latest.empty?
|
138
|
+
# false
|
139
|
+
# else
|
140
|
+
# # Convert to a list of index values if we got the actual objects
|
141
|
+
# latest = latest.collect { |obj| obj.index } if klass === latest.first
|
142
|
+
# current = send("#{name_plural}raw")
|
143
|
+
# added = latest-current
|
144
|
+
# removed = current-latest
|
145
|
+
# #Familia.info "#{self.index}: adding: #{added}"
|
146
|
+
# added.each { |v| self.send("add_#{name_singular}", v) }
|
147
|
+
# #Familia.info "#{self.index}: removing: #{removed}"
|
148
|
+
# removed.each { |v| self.send("remove_#{name_singular}", v) }
|
149
|
+
# true
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
|
153
|
+
Familia::RedisType.register self, :list
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Familia
|
4
|
+
class SortedSet < RedisType
|
5
|
+
def size
|
6
|
+
redis.zcard rediskey
|
7
|
+
end
|
8
|
+
alias length size
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
size.zero?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Adds a new element to the sorted set with the current timestamp as the
|
15
|
+
# score.
|
16
|
+
#
|
17
|
+
# This method provides a convenient way to add elements to the sorted set
|
18
|
+
# without explicitly specifying a score. It uses the current Unix timestamp
|
19
|
+
# as the score, which effectively sorts elements by their insertion time.
|
20
|
+
#
|
21
|
+
# @param val [Object] The value to be added to the sorted set.
|
22
|
+
# @return [Integer] Returns 1 if the element is new and added, 0 if the
|
23
|
+
# element already existed and the score was updated.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# sorted_set << "new_element"
|
27
|
+
#
|
28
|
+
# @note This is a non-standard operation for sorted sets as it doesn't allow
|
29
|
+
# specifying a custom score. Use `add` or `[]=` for more control.
|
30
|
+
#
|
31
|
+
def <<(val)
|
32
|
+
add(Time.now.to_i, val)
|
33
|
+
end
|
34
|
+
|
35
|
+
# NOTE: The argument order is the reverse of #add. We do this to
|
36
|
+
# more naturally align with how the [] and []= methods are used.
|
37
|
+
#
|
38
|
+
# e.g.
|
39
|
+
# obj.metrics[VALUE] = SCORE
|
40
|
+
# obj.metrics[VALUE] # => SCORE
|
41
|
+
#
|
42
|
+
def []=(val, score)
|
43
|
+
add score, val
|
44
|
+
end
|
45
|
+
|
46
|
+
def add(score, val)
|
47
|
+
ret = redis.zadd rediskey, score, to_redis(val)
|
48
|
+
update_expiration
|
49
|
+
ret
|
50
|
+
end
|
51
|
+
|
52
|
+
def score(val)
|
53
|
+
ret = redis.zscore rediskey, to_redis(val, false)
|
54
|
+
ret&.to_f
|
55
|
+
end
|
56
|
+
alias [] score
|
57
|
+
|
58
|
+
def member?(val)
|
59
|
+
Familia.trace :MEMBER, redis, "#{val}<#{val.class}>", caller(1..1) if Familia.debug?
|
60
|
+
!rank(val).nil?
|
61
|
+
end
|
62
|
+
alias include? member?
|
63
|
+
|
64
|
+
# rank of member +v+ when ordered lowest to highest (starts at 0)
|
65
|
+
def rank(v)
|
66
|
+
ret = redis.zrank rediskey, to_redis(v, false)
|
67
|
+
ret&.to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
# rank of member +v+ when ordered highest to lowest (starts at 0)
|
71
|
+
def revrank(v)
|
72
|
+
ret = redis.zrevrank rediskey, to_redis(v, false)
|
73
|
+
ret&.to_i
|
74
|
+
end
|
75
|
+
|
76
|
+
def members(count = -1, opts = {})
|
77
|
+
count -= 1 if count.positive?
|
78
|
+
el = membersraw count, opts
|
79
|
+
multi_from_redis(*el)
|
80
|
+
end
|
81
|
+
alias to_a members
|
82
|
+
alias all members
|
83
|
+
|
84
|
+
def membersraw(count = -1, opts = {})
|
85
|
+
count -= 1 if count.positive?
|
86
|
+
rangeraw 0, count, opts
|
87
|
+
end
|
88
|
+
|
89
|
+
def revmembers(count = -1, opts = {})
|
90
|
+
count -= 1 if count.positive?
|
91
|
+
el = revmembersraw count, opts
|
92
|
+
multi_from_redis(*el)
|
93
|
+
end
|
94
|
+
|
95
|
+
def revmembersraw(count = -1, opts = {})
|
96
|
+
count -= 1 if count.positive?
|
97
|
+
revrangeraw 0, count, opts
|
98
|
+
end
|
99
|
+
|
100
|
+
def each(&blk)
|
101
|
+
members.each(&blk)
|
102
|
+
end
|
103
|
+
|
104
|
+
def each_with_index(&blk)
|
105
|
+
members.each_with_index(&blk)
|
106
|
+
end
|
107
|
+
|
108
|
+
def collect(&blk)
|
109
|
+
members.collect(&blk)
|
110
|
+
end
|
111
|
+
|
112
|
+
def select(&blk)
|
113
|
+
members.select(&blk)
|
114
|
+
end
|
115
|
+
|
116
|
+
def eachraw(&blk)
|
117
|
+
membersraw.each(&blk)
|
118
|
+
end
|
119
|
+
|
120
|
+
def eachraw_with_index(&blk)
|
121
|
+
membersraw.each_with_index(&blk)
|
122
|
+
end
|
123
|
+
|
124
|
+
def collectraw(&blk)
|
125
|
+
membersraw.collect(&blk)
|
126
|
+
end
|
127
|
+
|
128
|
+
def selectraw(&blk)
|
129
|
+
membersraw.select(&blk)
|
130
|
+
end
|
131
|
+
|
132
|
+
def range(sidx, eidx, opts = {})
|
133
|
+
echo :range, caller(1..1).first if Familia.debug
|
134
|
+
el = rangeraw(sidx, eidx, opts)
|
135
|
+
multi_from_redis(*el)
|
136
|
+
end
|
137
|
+
|
138
|
+
def rangeraw(sidx, eidx, opts = {})
|
139
|
+
# NOTE: :withscores (no underscore) is the correct naming for the
|
140
|
+
# redis-4.x gem. We pass :withscores through explicitly b/c
|
141
|
+
# redis.zrange et al only accept that one optional argument.
|
142
|
+
# Passing `opts`` through leads to an ArgumentError:
|
143
|
+
#
|
144
|
+
# sorted_sets.rb:374:in `zrevrange': wrong number of arguments (given 4, expected 3) (ArgumentError)
|
145
|
+
#
|
146
|
+
redis.zrange(rediskey, sidx, eidx, **opts)
|
147
|
+
end
|
148
|
+
|
149
|
+
def revrange(sidx, eidx, opts = {})
|
150
|
+
echo :revrange, caller(1..1).first if Familia.debug
|
151
|
+
el = revrangeraw(sidx, eidx, opts)
|
152
|
+
multi_from_redis(*el)
|
153
|
+
end
|
154
|
+
|
155
|
+
def revrangeraw(sidx, eidx, opts = {})
|
156
|
+
redis.zrevrange(rediskey, sidx, eidx, **opts)
|
157
|
+
end
|
158
|
+
|
159
|
+
# e.g. obj.metrics.rangebyscore (now-12.hours), now, :limit => [0, 10]
|
160
|
+
def rangebyscore(sscore, escore, opts = {})
|
161
|
+
echo :rangebyscore, caller(1..1).first if Familia.debug
|
162
|
+
el = rangebyscoreraw(sscore, escore, opts)
|
163
|
+
multi_from_redis(*el)
|
164
|
+
end
|
165
|
+
|
166
|
+
def rangebyscoreraw(sscore, escore, opts = {})
|
167
|
+
echo :rangebyscoreraw, caller(1..1).first if Familia.debug
|
168
|
+
redis.zrangebyscore(rediskey, sscore, escore, **opts)
|
169
|
+
end
|
170
|
+
|
171
|
+
# e.g. obj.metrics.revrangebyscore (now-12.hours), now, :limit => [0, 10]
|
172
|
+
def revrangebyscore(sscore, escore, opts = {})
|
173
|
+
echo :revrangebyscore, caller(1..1).first if Familia.debug
|
174
|
+
el = revrangebyscoreraw(sscore, escore, opts)
|
175
|
+
multi_from_redis(*el)
|
176
|
+
end
|
177
|
+
|
178
|
+
def revrangebyscoreraw(sscore, escore, opts = {})
|
179
|
+
echo :revrangebyscoreraw, caller(1..1).first if Familia.debug
|
180
|
+
opts[:with_scores] = true if opts[:withscores]
|
181
|
+
redis.zrevrangebyscore(rediskey, sscore, escore, opts)
|
182
|
+
end
|
183
|
+
|
184
|
+
def remrangebyrank(srank, erank)
|
185
|
+
redis.zremrangebyrank rediskey, srank, erank
|
186
|
+
end
|
187
|
+
|
188
|
+
def remrangebyscore(sscore, escore)
|
189
|
+
redis.zremrangebyscore rediskey, sscore, escore
|
190
|
+
end
|
191
|
+
|
192
|
+
def increment(val, by = 1)
|
193
|
+
redis.zincrby(rediskey, by, val).to_i
|
194
|
+
end
|
195
|
+
alias incr increment
|
196
|
+
alias incrby increment
|
197
|
+
|
198
|
+
def decrement(val, by = 1)
|
199
|
+
increment val, -by
|
200
|
+
end
|
201
|
+
alias decr decrement
|
202
|
+
alias decrby decrement
|
203
|
+
|
204
|
+
def delete(val)
|
205
|
+
Familia.trace :DELETE, redis, "#{val}<#{val.class}>", caller(1..1) if Familia.debug?
|
206
|
+
# We use `strict_values: false` here to allow for the deletion of values
|
207
|
+
# that are in the sorted set. If it's a horreum object, the value is
|
208
|
+
# the identifier and not a serialized version of the object. So either
|
209
|
+
# the value exists in the sorted set or it doesn't -- we don't need to
|
210
|
+
# raise an error if it's not found.
|
211
|
+
redis.zrem rediskey, to_redis(val, false)
|
212
|
+
end
|
213
|
+
alias remove delete
|
214
|
+
alias rem delete
|
215
|
+
alias del delete
|
216
|
+
|
217
|
+
def at(idx)
|
218
|
+
range(idx, idx).first
|
219
|
+
end
|
220
|
+
|
221
|
+
# Return the first element in the list. Redis: ZRANGE(0)
|
222
|
+
def first
|
223
|
+
at(0)
|
224
|
+
end
|
225
|
+
|
226
|
+
# Return the last element in the list. Redis: ZRANGE(-1)
|
227
|
+
def last
|
228
|
+
at(-1)
|
229
|
+
end
|
230
|
+
|
231
|
+
Familia::RedisType.register self, :sorted_set
|
232
|
+
Familia::RedisType.register self, :zset
|
233
|
+
end
|
234
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Familia
|
4
|
+
class String < RedisType
|
5
|
+
def init; end
|
6
|
+
|
7
|
+
def size
|
8
|
+
to_s.size
|
9
|
+
end
|
10
|
+
alias length size
|
11
|
+
|
12
|
+
def empty?
|
13
|
+
size.zero?
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
echo :value, caller[0..0] if Familia.debug
|
18
|
+
redis.setnx rediskey, @opts[:default] if @opts[:default]
|
19
|
+
from_redis redis.get(rediskey)
|
20
|
+
end
|
21
|
+
alias content value
|
22
|
+
alias get value
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
value.to_s # value can return nil which to_s should not
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_i
|
29
|
+
value.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
def value=(val)
|
33
|
+
ret = redis.set(rediskey, to_redis(val))
|
34
|
+
update_expiration
|
35
|
+
ret
|
36
|
+
end
|
37
|
+
alias replace value=
|
38
|
+
alias set value=
|
39
|
+
|
40
|
+
def setnx(val)
|
41
|
+
ret = redis.setnx(rediskey, to_redis(val))
|
42
|
+
update_expiration
|
43
|
+
ret
|
44
|
+
end
|
45
|
+
|
46
|
+
def increment
|
47
|
+
ret = redis.incr(rediskey)
|
48
|
+
update_expiration
|
49
|
+
ret
|
50
|
+
end
|
51
|
+
alias incr increment
|
52
|
+
|
53
|
+
def incrementby(val)
|
54
|
+
ret = redis.incrby(rediskey, val.to_i)
|
55
|
+
update_expiration
|
56
|
+
ret
|
57
|
+
end
|
58
|
+
alias incrby incrementby
|
59
|
+
|
60
|
+
def decrement
|
61
|
+
ret = redis.decr rediskey
|
62
|
+
update_expiration
|
63
|
+
ret
|
64
|
+
end
|
65
|
+
alias decr decrement
|
66
|
+
|
67
|
+
def decrementby(val)
|
68
|
+
ret = redis.decrby rediskey, val.to_i
|
69
|
+
update_expiration
|
70
|
+
ret
|
71
|
+
end
|
72
|
+
alias decrby decrementby
|
73
|
+
|
74
|
+
def append(val)
|
75
|
+
ret = redis.append rediskey, val
|
76
|
+
update_expiration
|
77
|
+
ret
|
78
|
+
end
|
79
|
+
alias << append
|
80
|
+
|
81
|
+
def getbit(offset)
|
82
|
+
redis.getbit rediskey, offset
|
83
|
+
end
|
84
|
+
|
85
|
+
def setbit(offset, val)
|
86
|
+
ret = redis.setbit rediskey, offset, val
|
87
|
+
update_expiration
|
88
|
+
ret
|
89
|
+
end
|
90
|
+
|
91
|
+
def getrange(spoint, epoint)
|
92
|
+
redis.getrange rediskey, spoint, epoint
|
93
|
+
end
|
94
|
+
|
95
|
+
def setrange(offset, val)
|
96
|
+
ret = redis.setrange rediskey, offset, val
|
97
|
+
update_expiration
|
98
|
+
ret
|
99
|
+
end
|
100
|
+
|
101
|
+
def getset(val)
|
102
|
+
ret = redis.getset rediskey, val
|
103
|
+
update_expiration
|
104
|
+
ret
|
105
|
+
end
|
106
|
+
|
107
|
+
def nil?
|
108
|
+
value.nil?
|
109
|
+
end
|
110
|
+
|
111
|
+
Familia::RedisType.register self, :string
|
112
|
+
Familia::RedisType.register self, :counter
|
113
|
+
Familia::RedisType.register self, :lock
|
114
|
+
end
|
115
|
+
end
|