familia 1.2.3 → 2.0.0.pre.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +68 -0
- data/.github/workflows/docs.yml +64 -0
- data/.gitignore +3 -0
- data/.pre-commit-config.yaml +3 -1
- data/.rubocop.yml +16 -9
- data/.rubocop_todo.yml +177 -31
- data/.yardopts +9 -0
- data/CLAUDE.md +141 -0
- data/Gemfile +15 -2
- data/Gemfile.lock +61 -61
- data/README.md +39 -23
- data/bin/irb +3 -0
- data/docs/connection_pooling.md +317 -0
- data/familia.gemspec +8 -5
- data/lib/familia/base.rb +19 -9
- data/lib/familia/connection.rb +232 -65
- data/lib/familia/core_ext.rb +1 -1
- data/lib/familia/datatype/commands.rb +59 -0
- data/lib/familia/{redistype → datatype}/serialization.rb +9 -13
- data/lib/familia/{redistype → datatype}/types/hashkey.rb +25 -25
- data/lib/familia/{redistype → datatype}/types/list.rb +13 -13
- data/lib/familia/{redistype → datatype}/types/sorted_set.rb +20 -20
- data/lib/familia/{redistype → datatype}/types/string.rb +22 -21
- data/lib/familia/{redistype → datatype}/types/unsorted_set.rb +11 -11
- data/lib/familia/datatype.rb +243 -0
- data/lib/familia/errors.rb +5 -2
- data/lib/familia/features/expiration.rb +33 -34
- data/lib/familia/features/quantization.rb +9 -3
- data/lib/familia/features/safe_dump.rb +2 -3
- data/lib/familia/features.rb +2 -2
- data/lib/familia/horreum/class_methods.rb +97 -130
- data/lib/familia/horreum/commands.rb +46 -51
- data/lib/familia/horreum/connection.rb +82 -0
- data/lib/familia/horreum/{relations_management.rb → related_fields_management.rb} +37 -35
- data/lib/familia/horreum/serialization.rb +61 -198
- data/lib/familia/horreum/settings.rb +6 -17
- data/lib/familia/horreum/utils.rb +11 -10
- data/lib/familia/horreum.rb +69 -60
- data/lib/familia/logging.rb +12 -12
- data/lib/familia/multi_result.rb +72 -0
- data/lib/familia/refinements.rb +7 -44
- data/lib/familia/settings.rb +11 -11
- data/lib/familia/utils.rb +123 -90
- data/lib/familia/version.rb +4 -21
- data/lib/familia.rb +17 -12
- data/lib/middleware/database_middleware.rb +150 -0
- data/try/configuration/scenarios_try.rb +65 -0
- data/try/core/connection_try.rb +58 -0
- data/try/core/errors_try.rb +93 -0
- data/try/core/extensions_try.rb +26 -0
- data/try/{10_familia_try.rb → core/familia_extended_try.rb} +11 -10
- data/try/{00_familia_try.rb → core/familia_try.rb} +5 -3
- data/try/core/middleware_try.rb +68 -0
- data/try/core/refinements_try.rb +39 -0
- data/try/core/settings_try.rb +76 -0
- data/try/core/tools_try.rb +54 -0
- data/try/core/utils_try.rb +189 -0
- data/try/{26_redis_bool_try.rb → datatypes/boolean_try.rb} +4 -2
- data/try/datatypes/datatype_base_try.rb +69 -0
- data/try/{25_redis_type_hash_try.rb → datatypes/hash_try.rb} +5 -3
- data/try/{23_redis_type_list_try.rb → datatypes/list_try.rb} +5 -3
- data/try/{22_redis_type_set_try.rb → datatypes/set_try.rb} +5 -3
- data/try/{21_redis_type_zset_try.rb → datatypes/sorted_set_try.rb} +6 -4
- data/try/{24_redis_type_string_try.rb → datatypes/string_try.rb} +8 -8
- data/try/edge_cases/empty_identifiers_try.rb +48 -0
- data/try/{92_symbolize_try.rb → edge_cases/hash_symbolization_try.rb} +12 -8
- data/try/edge_cases/json_serialization_try.rb +85 -0
- data/try/edge_cases/race_conditions_try.rb +60 -0
- data/try/edge_cases/reserved_keywords_try.rb +59 -0
- data/try/{93_string_coercion_try.rb → edge_cases/string_coercion_try.rb} +63 -60
- data/try/edge_cases/ttl_side_effects_try.rb +51 -0
- data/try/features/expiration_try.rb +86 -0
- data/try/features/quantization_try.rb +90 -0
- data/try/{35_feature_safedump_try.rb → features/safe_dump_advanced_try.rb} +7 -6
- data/try/features/safe_dump_try.rb +137 -0
- data/try/{test_helpers.rb → helpers/test_helpers.rb} +25 -60
- data/try/{27_redis_horreum_try.rb → horreum/base_try.rb} +39 -14
- data/try/horreum/class_methods_try.rb +41 -0
- data/try/horreum/commands_try.rb +49 -0
- data/try/{29_redis_horreum_initialization_try.rb → horreum/initialization_try.rb} +9 -7
- data/try/horreum/relations_try.rb +146 -0
- data/try/{28_redis_horreum_serialization_try.rb → horreum/serialization_try.rb} +13 -11
- data/try/horreum/settings_try.rb +43 -0
- data/try/integration/cross_component_try.rb +46 -0
- data/try/{41_customer_safedump_try.rb → models/customer_safe_dump_try.rb} +9 -7
- data/try/{40_customer_try.rb → models/customer_try.rb} +20 -17
- data/try/models/datatype_base_try.rb +101 -0
- data/try/{30_familia_object_try.rb → models/familia_object_try.rb} +18 -16
- data/try/performance/benchmarks_try.rb +55 -0
- data/try/pooling/README.md +20 -0
- data/try/pooling/configurable_stress_test_try.rb +435 -0
- data/try/pooling/connection_pool_test_try.rb +273 -0
- data/try/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +192 -0
- data/try/pooling/lib/connection_pool_metrics.rb +372 -0
- data/try/pooling/lib/connection_pool_stress_test.rb +959 -0
- data/try/pooling/lib/connection_pool_threading_models.rb +421 -0
- data/try/pooling/lib/visualize_stress_results.rb +434 -0
- data/try/pooling/pool_siege_try.rb +509 -0
- data/try/pooling/run_stress_tests_try.rb +482 -0
- data/try/prototypes/atomic_saves_v1_context_proxy.rb +121 -0
- data/try/prototypes/atomic_saves_v2_connection_switching.rb +161 -0
- data/try/prototypes/atomic_saves_v3_connection_pool.rb +189 -0
- data/try/prototypes/atomic_saves_v4.rb +105 -0
- data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +124 -0
- data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +192 -0
- metadata +124 -38
- data/.github/workflows/ruby.yml +0 -71
- data/VERSION.yml +0 -4
- data/lib/familia/redistype/commands.rb +0 -59
- data/lib/familia/redistype.rb +0 -228
- data/lib/familia/tools.rb +0 -68
- data/lib/redis_middleware.rb +0 -109
- data/try/20_redis_type_try.rb +0 -70
- data/try/91_json_bug_try.rb +0 -86
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# lib/familia/datatype/types/hashkey.rb
|
2
2
|
|
3
3
|
module Familia
|
4
|
-
class HashKey <
|
4
|
+
class HashKey < DataType
|
5
5
|
# Returns the number of fields in the hash
|
6
6
|
# @return [Integer] number of fields
|
7
7
|
def field_count
|
8
|
-
|
8
|
+
dbclient.hlen dbkey
|
9
9
|
end
|
10
10
|
alias size field_count
|
11
11
|
|
@@ -16,22 +16,22 @@ module Familia
|
|
16
16
|
# +return+ [Integer] Returns 1 if the field is new and added, 0 if the
|
17
17
|
# field already existed and the value was updated.
|
18
18
|
def []=(field, val)
|
19
|
-
ret =
|
19
|
+
ret = dbclient.hset dbkey, field.to_s, serialize_value(val)
|
20
20
|
update_expiration
|
21
21
|
ret
|
22
22
|
rescue TypeError => e
|
23
23
|
Familia.le "[hset]= #{e.message}"
|
24
|
-
Familia.ld "[hset]= #{
|
25
|
-
echo :hset, caller(1..1).first if Familia.debug # logs via echo to
|
24
|
+
Familia.ld "[hset]= #{dbkey} #{field}=#{val}" if Familia.debug
|
25
|
+
echo :hset, caller(1..1).first if Familia.debug # logs via echo to the db and back
|
26
26
|
klass = val.class
|
27
|
-
msg = "Cannot store #{field} => #{val.inspect} (#{klass}) in #{
|
27
|
+
msg = "Cannot store #{field} => #{val.inspect} (#{klass}) in #{dbkey}"
|
28
28
|
raise e.class, msg
|
29
29
|
end
|
30
30
|
alias put []=
|
31
31
|
alias store []=
|
32
32
|
|
33
33
|
def [](field)
|
34
|
-
deserialize_value
|
34
|
+
deserialize_value dbclient.hget(dbkey, field.to_s)
|
35
35
|
end
|
36
36
|
alias get []
|
37
37
|
|
@@ -47,22 +47,22 @@ module Familia
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def keys
|
50
|
-
|
50
|
+
dbclient.hkeys dbkey
|
51
51
|
end
|
52
52
|
|
53
53
|
def values
|
54
|
-
|
54
|
+
dbclient.hvals(dbkey).map { |v| deserialize_value v }
|
55
55
|
end
|
56
56
|
|
57
57
|
def hgetall
|
58
|
-
|
58
|
+
dbclient.hgetall(dbkey).each_with_object({}) do |(k,v), ret|
|
59
59
|
ret[k] = deserialize_value v
|
60
60
|
end
|
61
61
|
end
|
62
62
|
alias all hgetall
|
63
63
|
|
64
64
|
def key?(field)
|
65
|
-
|
65
|
+
dbclient.hexists dbkey, field.to_s
|
66
66
|
end
|
67
67
|
alias has_key? key?
|
68
68
|
alias include? key?
|
@@ -72,12 +72,12 @@ module Familia
|
|
72
72
|
# @param field [String] The field to remove
|
73
73
|
# @return [Integer] The number of fields that were removed (0 or 1)
|
74
74
|
def remove_field(field)
|
75
|
-
|
75
|
+
dbclient.hdel dbkey, field.to_s
|
76
76
|
end
|
77
77
|
alias remove remove_field # deprecated
|
78
78
|
|
79
79
|
def increment(field, by = 1)
|
80
|
-
|
80
|
+
dbclient.hincrby(dbkey, field.to_s, by).to_i
|
81
81
|
end
|
82
82
|
alias incr increment
|
83
83
|
alias incrby increment
|
@@ -93,7 +93,7 @@ module Familia
|
|
93
93
|
|
94
94
|
data = hsh.inject([]) { |ret, pair| ret << [pair[0], serialize_value(pair[1])] }.flatten
|
95
95
|
|
96
|
-
ret =
|
96
|
+
ret = dbclient.hmset(dbkey, *data)
|
97
97
|
update_expiration
|
98
98
|
ret
|
99
99
|
end
|
@@ -101,11 +101,11 @@ module Familia
|
|
101
101
|
|
102
102
|
def values_at *fields
|
103
103
|
string_fields = fields.flatten.compact.map(&:to_s)
|
104
|
-
elements =
|
104
|
+
elements = dbclient.hmget(dbkey, *string_fields)
|
105
105
|
deserialize_values(*elements)
|
106
106
|
end
|
107
107
|
|
108
|
-
# The Great
|
108
|
+
# The Great Database Refresh-o-matic 3000 for HashKey!
|
109
109
|
#
|
110
110
|
# This method performs a complete refresh of the hash's state from Redis.
|
111
111
|
# It's like giving your hash a memory transfusion - out with the old state,
|
@@ -117,7 +117,7 @@ module Familia
|
|
117
117
|
# @return [void] Returns nothing, but your hash will be sparkling clean
|
118
118
|
# with all its fields synchronized with Redis.
|
119
119
|
#
|
120
|
-
# @raise [Familia::KeyNotFoundError] If the
|
120
|
+
# @raise [Familia::KeyNotFoundError] If the dbkey for this hash no
|
121
121
|
# longer exists. Time travelers beware!
|
122
122
|
#
|
123
123
|
# @example Basic usage
|
@@ -127,14 +127,14 @@ module Familia
|
|
127
127
|
# begin
|
128
128
|
# my_hash.refresh!
|
129
129
|
# rescue Familia::KeyNotFoundError
|
130
|
-
# puts "Oops! Our hash seems to have vanished into the
|
130
|
+
# puts "Oops! Our hash seems to have vanished into the Database void!"
|
131
131
|
# end
|
132
132
|
def refresh!
|
133
|
-
Familia.trace :REFRESH,
|
134
|
-
raise Familia::KeyNotFoundError,
|
133
|
+
Familia.trace :REFRESH, dbclient, uri, caller(1..1) if Familia.debug?
|
134
|
+
raise Familia::KeyNotFoundError, dbkey unless dbclient.exists(dbkey)
|
135
135
|
|
136
136
|
fields = hgetall
|
137
|
-
Familia.ld "[refresh!] #{self.class} #{
|
137
|
+
Familia.ld "[refresh!] #{self.class} #{dbkey} #{fields.keys}"
|
138
138
|
|
139
139
|
# For HashKey, we update by merging the fresh data
|
140
140
|
update(fields)
|
@@ -148,7 +148,7 @@ module Familia
|
|
148
148
|
#
|
149
149
|
# @return [self] Returns the refreshed hash, ready for more adventures!
|
150
150
|
#
|
151
|
-
# @raise [Familia::KeyNotFoundError] If the
|
151
|
+
# @raise [Familia::KeyNotFoundError] If the dbkey does not exist.
|
152
152
|
# The hash must exist in Redis-land for this to work!
|
153
153
|
#
|
154
154
|
# @example Refresh and chain
|
@@ -161,7 +161,7 @@ module Familia
|
|
161
161
|
self
|
162
162
|
end
|
163
163
|
|
164
|
-
Familia::
|
165
|
-
Familia::
|
164
|
+
Familia::DataType.register self, :hash # legacy, deprecated
|
165
|
+
Familia::DataType.register self, :hashkey
|
166
166
|
end
|
167
167
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# lib/familia/datatype/types/list.rb
|
2
2
|
|
3
3
|
module Familia
|
4
|
-
class List <
|
4
|
+
class List < DataType
|
5
5
|
|
6
6
|
# Returns the number of elements in the list
|
7
7
|
# @return [Integer] number of elements
|
8
8
|
def element_count
|
9
|
-
|
9
|
+
dbclient.llen dbkey
|
10
10
|
end
|
11
11
|
alias size element_count
|
12
12
|
|
@@ -16,8 +16,8 @@ module Familia
|
|
16
16
|
|
17
17
|
def push *values
|
18
18
|
echo :push, caller(1..1).first if Familia.debug
|
19
|
-
values.flatten.compact.each { |v|
|
20
|
-
|
19
|
+
values.flatten.compact.each { |v| dbclient.rpush dbkey, serialize_value(v) }
|
20
|
+
dbclient.ltrim dbkey, -@opts[:maxlength], -1 if @opts[:maxlength]
|
21
21
|
update_expiration
|
22
22
|
self
|
23
23
|
end
|
@@ -29,20 +29,20 @@ module Familia
|
|
29
29
|
alias add <<
|
30
30
|
|
31
31
|
def unshift *values
|
32
|
-
values.flatten.compact.each { |v|
|
32
|
+
values.flatten.compact.each { |v| dbclient.lpush dbkey, serialize_value(v) }
|
33
33
|
# TODO: test maxlength
|
34
|
-
|
34
|
+
dbclient.ltrim dbkey, 0, @opts[:maxlength] - 1 if @opts[:maxlength]
|
35
35
|
update_expiration
|
36
36
|
self
|
37
37
|
end
|
38
38
|
alias prepend unshift
|
39
39
|
|
40
40
|
def pop
|
41
|
-
deserialize_value
|
41
|
+
deserialize_value dbclient.rpop(dbkey)
|
42
42
|
end
|
43
43
|
|
44
44
|
def shift
|
45
|
-
deserialize_value
|
45
|
+
deserialize_value dbclient.lpop(dbkey)
|
46
46
|
end
|
47
47
|
|
48
48
|
def [](idx, count = nil)
|
@@ -65,7 +65,7 @@ module Familia
|
|
65
65
|
# @param count [Integer] Number of elements to remove (0 means all)
|
66
66
|
# @return [Integer] The number of removed elements
|
67
67
|
def remove_element(value, count = 0)
|
68
|
-
|
68
|
+
dbclient.lrem dbkey, count, serialize_value(value)
|
69
69
|
end
|
70
70
|
alias remove remove_element
|
71
71
|
|
@@ -75,7 +75,7 @@ module Familia
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def rangeraw(sidx = 0, eidx = -1)
|
78
|
-
|
78
|
+
dbclient.lrange(dbkey, sidx, eidx)
|
79
79
|
end
|
80
80
|
|
81
81
|
def members(count = -1)
|
@@ -124,7 +124,7 @@ module Familia
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def at(idx)
|
127
|
-
deserialize_value
|
127
|
+
deserialize_value dbclient.lindex(dbkey, idx)
|
128
128
|
end
|
129
129
|
|
130
130
|
def first
|
@@ -157,6 +157,6 @@ module Familia
|
|
157
157
|
# end
|
158
158
|
# end
|
159
159
|
|
160
|
-
Familia::
|
160
|
+
Familia::DataType.register self, :list
|
161
161
|
end
|
162
162
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# lib/familia/datatype/types/sorted_set.rb
|
2
2
|
|
3
3
|
module Familia
|
4
|
-
class SortedSet <
|
4
|
+
class SortedSet < DataType
|
5
5
|
# Returns the number of elements in the sorted set
|
6
6
|
# @return [Integer] number of elements
|
7
7
|
def element_count
|
8
|
-
|
8
|
+
dbclient.zcard dbkey
|
9
9
|
end
|
10
10
|
alias size element_count
|
11
11
|
|
@@ -46,32 +46,32 @@ module Familia
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def add(score, val)
|
49
|
-
ret =
|
49
|
+
ret = dbclient.zadd dbkey, score, serialize_value(val)
|
50
50
|
update_expiration
|
51
51
|
ret
|
52
52
|
end
|
53
53
|
|
54
54
|
def score(val)
|
55
|
-
ret =
|
55
|
+
ret = dbclient.zscore dbkey, serialize_value(val, strict_values: false)
|
56
56
|
ret&.to_f
|
57
57
|
end
|
58
58
|
alias [] score
|
59
59
|
|
60
60
|
def member?(val)
|
61
|
-
Familia.trace :MEMBER,
|
61
|
+
Familia.trace :MEMBER, dbclient, "#{val}<#{val.class}>", caller(1..1) if Familia.debug?
|
62
62
|
!rank(val).nil?
|
63
63
|
end
|
64
64
|
alias include? member?
|
65
65
|
|
66
66
|
# rank of member +v+ when ordered lowest to highest (starts at 0)
|
67
67
|
def rank(v)
|
68
|
-
ret =
|
68
|
+
ret = dbclient.zrank dbkey, serialize_value(v, strict_values: false)
|
69
69
|
ret&.to_i
|
70
70
|
end
|
71
71
|
|
72
72
|
# rank of member +v+ when ordered highest to lowest (starts at 0)
|
73
73
|
def revrank(v)
|
74
|
-
ret =
|
74
|
+
ret = dbclient.zrevrank dbkey, serialize_value(v, strict_values: false)
|
75
75
|
ret&.to_i
|
76
76
|
end
|
77
77
|
|
@@ -140,12 +140,12 @@ module Familia
|
|
140
140
|
def rangeraw(sidx, eidx, opts = {})
|
141
141
|
# NOTE: :withscores (no underscore) is the correct naming for the
|
142
142
|
# redis-4.x gem. We pass :withscores through explicitly b/c
|
143
|
-
#
|
143
|
+
# dbclient.zrange et al only accept that one optional argument.
|
144
144
|
# Passing `opts`` through leads to an ArgumentError:
|
145
145
|
#
|
146
146
|
# sorted_sets.rb:374:in `zrevrange': wrong number of arguments (given 4, expected 3) (ArgumentError)
|
147
147
|
#
|
148
|
-
|
148
|
+
dbclient.zrange(dbkey, sidx, eidx, **opts)
|
149
149
|
end
|
150
150
|
|
151
151
|
def revrange(sidx, eidx, opts = {})
|
@@ -155,7 +155,7 @@ module Familia
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def revrangeraw(sidx, eidx, opts = {})
|
158
|
-
|
158
|
+
dbclient.zrevrange(dbkey, sidx, eidx, **opts)
|
159
159
|
end
|
160
160
|
|
161
161
|
# e.g. obj.metrics.rangebyscore (now-12.hours), now, :limit => [0, 10]
|
@@ -167,7 +167,7 @@ module Familia
|
|
167
167
|
|
168
168
|
def rangebyscoreraw(sscore, escore, opts = {})
|
169
169
|
echo :rangebyscoreraw, caller(1..1).first if Familia.debug
|
170
|
-
|
170
|
+
dbclient.zrangebyscore(dbkey, sscore, escore, **opts)
|
171
171
|
end
|
172
172
|
|
173
173
|
# e.g. obj.metrics.revrangebyscore (now-12.hours), now, :limit => [0, 10]
|
@@ -180,19 +180,19 @@ module Familia
|
|
180
180
|
def revrangebyscoreraw(sscore, escore, opts = {})
|
181
181
|
echo :revrangebyscoreraw, caller(1..1).first if Familia.debug
|
182
182
|
opts[:with_scores] = true if opts[:withscores]
|
183
|
-
|
183
|
+
dbclient.zrevrangebyscore(dbkey, sscore, escore, opts)
|
184
184
|
end
|
185
185
|
|
186
186
|
def remrangebyrank(srank, erank)
|
187
|
-
|
187
|
+
dbclient.zremrangebyrank dbkey, srank, erank
|
188
188
|
end
|
189
189
|
|
190
190
|
def remrangebyscore(sscore, escore)
|
191
|
-
|
191
|
+
dbclient.zremrangebyscore dbkey, sscore, escore
|
192
192
|
end
|
193
193
|
|
194
194
|
def increment(val, by = 1)
|
195
|
-
|
195
|
+
dbclient.zincrby(dbkey, by, val).to_i
|
196
196
|
end
|
197
197
|
alias incr increment
|
198
198
|
alias incrby increment
|
@@ -207,13 +207,13 @@ module Familia
|
|
207
207
|
# @param value The value to remove from the sorted set
|
208
208
|
# @return [Integer] The number of members that were removed (0 or 1)
|
209
209
|
def remove_element(value)
|
210
|
-
Familia.trace :REMOVE_ELEMENT,
|
210
|
+
Familia.trace :REMOVE_ELEMENT, dbclient, "#{value}<#{value.class}>", caller(1..1) if Familia.debug?
|
211
211
|
# We use `strict_values: false` here to allow for the deletion of values
|
212
212
|
# that are in the sorted set. If it's a horreum object, the value is
|
213
213
|
# the identifier and not a serialized version of the object. So either
|
214
214
|
# the value exists in the sorted set or it doesn't -- we don't need to
|
215
215
|
# raise an error if it's not found.
|
216
|
-
|
216
|
+
dbclient.zrem dbkey, serialize_value(value, strict_values: false)
|
217
217
|
end
|
218
218
|
alias remove remove_element # deprecated
|
219
219
|
|
@@ -231,7 +231,7 @@ module Familia
|
|
231
231
|
at(-1)
|
232
232
|
end
|
233
233
|
|
234
|
-
Familia::
|
235
|
-
Familia::
|
234
|
+
Familia::DataType.register self, :sorted_set
|
235
|
+
Familia::DataType.register self, :zset
|
236
236
|
end
|
237
237
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# lib/familia/datatype/types/string.rb
|
2
2
|
|
3
3
|
module Familia
|
4
|
-
class String <
|
4
|
+
class String < DataType
|
5
5
|
def init; end
|
6
6
|
|
7
7
|
# Returns the number of elements in the list
|
@@ -17,22 +17,23 @@ module Familia
|
|
17
17
|
|
18
18
|
def value
|
19
19
|
echo :value, caller(0..0) if Familia.debug
|
20
|
-
|
21
|
-
deserialize_value
|
20
|
+
dbclient.setnx dbkey, @opts[:default] if @opts[:default]
|
21
|
+
deserialize_value dbclient.get(dbkey)
|
22
22
|
end
|
23
23
|
alias content value
|
24
24
|
alias get value
|
25
25
|
|
26
26
|
def to_s
|
27
|
-
|
27
|
+
return super if value.to_s.empty?
|
28
|
+
value.to_s
|
28
29
|
end
|
29
30
|
|
30
31
|
def to_i
|
31
|
-
value
|
32
|
+
value&.to_i || 0
|
32
33
|
end
|
33
34
|
|
34
35
|
def value=(val)
|
35
|
-
ret =
|
36
|
+
ret = dbclient.set(dbkey, serialize_value(val))
|
36
37
|
update_expiration
|
37
38
|
ret
|
38
39
|
end
|
@@ -40,68 +41,68 @@ module Familia
|
|
40
41
|
alias set value=
|
41
42
|
|
42
43
|
def setnx(val)
|
43
|
-
ret =
|
44
|
+
ret = dbclient.setnx(dbkey, serialize_value(val))
|
44
45
|
update_expiration
|
45
46
|
ret
|
46
47
|
end
|
47
48
|
|
48
49
|
def increment
|
49
|
-
ret =
|
50
|
+
ret = dbclient.incr(dbkey)
|
50
51
|
update_expiration
|
51
52
|
ret
|
52
53
|
end
|
53
54
|
alias incr increment
|
54
55
|
|
55
56
|
def incrementby(val)
|
56
|
-
ret =
|
57
|
+
ret = dbclient.incrby(dbkey, val.to_i)
|
57
58
|
update_expiration
|
58
59
|
ret
|
59
60
|
end
|
60
61
|
alias incrby incrementby
|
61
62
|
|
62
63
|
def decrement
|
63
|
-
ret =
|
64
|
+
ret = dbclient.decr dbkey
|
64
65
|
update_expiration
|
65
66
|
ret
|
66
67
|
end
|
67
68
|
alias decr decrement
|
68
69
|
|
69
70
|
def decrementby(val)
|
70
|
-
ret =
|
71
|
+
ret = dbclient.decrby dbkey, val.to_i
|
71
72
|
update_expiration
|
72
73
|
ret
|
73
74
|
end
|
74
75
|
alias decrby decrementby
|
75
76
|
|
76
77
|
def append(val)
|
77
|
-
ret =
|
78
|
+
ret = dbclient.append dbkey, val
|
78
79
|
update_expiration
|
79
80
|
ret
|
80
81
|
end
|
81
82
|
alias << append
|
82
83
|
|
83
84
|
def getbit(offset)
|
84
|
-
|
85
|
+
dbclient.getbit dbkey, offset
|
85
86
|
end
|
86
87
|
|
87
88
|
def setbit(offset, val)
|
88
|
-
ret =
|
89
|
+
ret = dbclient.setbit dbkey, offset, val
|
89
90
|
update_expiration
|
90
91
|
ret
|
91
92
|
end
|
92
93
|
|
93
94
|
def getrange(spoint, epoint)
|
94
|
-
|
95
|
+
dbclient.getrange dbkey, spoint, epoint
|
95
96
|
end
|
96
97
|
|
97
98
|
def setrange(offset, val)
|
98
|
-
ret =
|
99
|
+
ret = dbclient.setrange dbkey, offset, val
|
99
100
|
update_expiration
|
100
101
|
ret
|
101
102
|
end
|
102
103
|
|
103
104
|
def getset(val)
|
104
|
-
ret =
|
105
|
+
ret = dbclient.getset dbkey, val
|
105
106
|
update_expiration
|
106
107
|
ret
|
107
108
|
end
|
@@ -110,8 +111,8 @@ module Familia
|
|
110
111
|
value.nil?
|
111
112
|
end
|
112
113
|
|
113
|
-
Familia::
|
114
|
-
Familia::
|
115
|
-
Familia::
|
114
|
+
Familia::DataType.register self, :string
|
115
|
+
Familia::DataType.register self, :counter
|
116
|
+
Familia::DataType.register self, :lock
|
116
117
|
end
|
117
118
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# lib/familia/datatype/types/unsorted_set.rb
|
2
2
|
|
3
3
|
module Familia
|
4
|
-
class Set <
|
4
|
+
class Set < DataType
|
5
5
|
|
6
6
|
# Returns the number of elements in the unsorted set
|
7
7
|
# @return [Integer] number of elements
|
8
8
|
def element_count
|
9
|
-
|
9
|
+
dbclient.scard dbkey
|
10
10
|
end
|
11
11
|
alias size element_count
|
12
12
|
|
@@ -15,7 +15,7 @@ module Familia
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def add *values
|
18
|
-
values.flatten.compact.each { |v|
|
18
|
+
values.flatten.compact.each { |v| dbclient.sadd? dbkey, serialize_value(v) }
|
19
19
|
update_expiration
|
20
20
|
self
|
21
21
|
end
|
@@ -33,7 +33,7 @@ module Familia
|
|
33
33
|
alias to_a members
|
34
34
|
|
35
35
|
def membersraw
|
36
|
-
|
36
|
+
dbclient.smembers(dbkey)
|
37
37
|
end
|
38
38
|
|
39
39
|
def each(&blk)
|
@@ -69,7 +69,7 @@ module Familia
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def member?(val)
|
72
|
-
|
72
|
+
dbclient.sismember dbkey, serialize_value(val)
|
73
73
|
end
|
74
74
|
alias include? member?
|
75
75
|
|
@@ -77,7 +77,7 @@ module Familia
|
|
77
77
|
# @param value The value to remove from the set
|
78
78
|
# @return [Integer] The number of members that were removed (0 or 1)
|
79
79
|
def remove_element(value)
|
80
|
-
|
80
|
+
dbclient.srem dbkey, serialize_value(value)
|
81
81
|
end
|
82
82
|
alias remove remove_element # deprecated
|
83
83
|
|
@@ -86,11 +86,11 @@ module Familia
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def pop
|
89
|
-
|
89
|
+
dbclient.spop dbkey
|
90
90
|
end
|
91
91
|
|
92
92
|
def move(dstkey, val)
|
93
|
-
|
93
|
+
dbclient.smove dbkey, dstkey, val
|
94
94
|
end
|
95
95
|
|
96
96
|
def random
|
@@ -98,7 +98,7 @@ module Familia
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def randomraw
|
101
|
-
|
101
|
+
dbclient.srandmember(dbkey)
|
102
102
|
end
|
103
103
|
|
104
104
|
## Make the value stored at KEY identical to the given list
|
@@ -122,6 +122,6 @@ module Familia
|
|
122
122
|
# end
|
123
123
|
# end
|
124
124
|
|
125
|
-
Familia::
|
125
|
+
Familia::DataType.register self, :set
|
126
126
|
end
|
127
127
|
end
|