redis 3.3.1 → 4.0.1
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/.travis/Gemfile +3 -1
- data/.travis.yml +36 -52
- data/CHANGELOG.md +32 -13
- data/Gemfile +0 -1
- data/README.md +31 -75
- data/benchmarking/logging.rb +1 -1
- data/bors.toml +14 -0
- data/lib/redis/client.rb +15 -11
- data/lib/redis/connection/command_helper.rb +2 -8
- data/lib/redis/connection/hiredis.rb +2 -2
- data/lib/redis/connection/ruby.rb +18 -20
- data/lib/redis/connection/synchrony.rb +12 -4
- data/lib/redis/connection.rb +2 -2
- data/lib/redis/distributed.rb +21 -8
- data/lib/redis/hash_ring.rb +20 -64
- data/lib/redis/pipeline.rb +0 -6
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +102 -38
- data/makefile +42 -0
- data/redis.gemspec +7 -9
- data/test/bitpos_test.rb +13 -19
- data/test/blocking_commands_test.rb +3 -5
- data/test/client_test.rb +1 -1
- data/test/command_map_test.rb +3 -5
- data/test/commands_on_hashes_test.rb +2 -4
- data/test/commands_on_hyper_log_log_test.rb +3 -5
- data/test/commands_on_lists_test.rb +2 -4
- data/test/commands_on_sets_test.rb +2 -4
- data/test/commands_on_sorted_sets_test.rb +17 -4
- data/test/commands_on_strings_test.rb +3 -5
- data/test/commands_on_value_types_test.rb +44 -6
- data/test/connection_handling_test.rb +5 -7
- data/test/connection_test.rb +57 -0
- data/test/distributed_blocking_commands_test.rb +2 -4
- data/test/distributed_commands_on_hashes_test.rb +2 -4
- data/test/distributed_commands_on_hyper_log_log_test.rb +2 -4
- data/test/distributed_commands_on_lists_test.rb +2 -4
- data/test/distributed_commands_on_sets_test.rb +27 -4
- data/test/distributed_commands_on_sorted_sets_test.rb +2 -4
- data/test/distributed_commands_on_strings_test.rb +20 -10
- data/test/distributed_commands_on_value_types_test.rb +2 -4
- data/test/distributed_commands_requiring_clustering_test.rb +1 -3
- data/test/distributed_connection_handling_test.rb +1 -3
- data/test/distributed_internals_test.rb +8 -19
- data/test/distributed_key_tags_test.rb +4 -6
- data/test/distributed_persistence_control_commands_test.rb +1 -3
- data/test/distributed_publish_subscribe_test.rb +1 -3
- data/test/distributed_remote_server_control_commands_test.rb +1 -3
- data/test/distributed_scripting_test.rb +1 -3
- data/test/distributed_sorting_test.rb +1 -3
- data/test/distributed_test.rb +12 -14
- data/test/distributed_transactions_test.rb +1 -3
- data/test/encoding_test.rb +4 -8
- data/test/error_replies_test.rb +2 -4
- data/test/fork_safety_test.rb +1 -6
- data/test/helper.rb +10 -41
- data/test/helper_test.rb +1 -3
- data/test/internals_test.rb +27 -95
- data/test/lint/sets.rb +15 -0
- data/test/lint/strings.rb +6 -20
- data/test/lint/value_types.rb +8 -0
- data/test/persistence_control_commands_test.rb +1 -3
- data/test/pipelining_commands_test.rb +4 -8
- data/test/publish_subscribe_test.rb +1 -3
- data/test/remote_server_control_commands_test.rb +61 -4
- data/test/scanning_test.rb +1 -7
- data/test/scripting_test.rb +1 -3
- data/test/sentinel_command_test.rb +1 -3
- data/test/sentinel_test.rb +1 -3
- data/test/sorting_test.rb +1 -3
- data/test/ssl_test.rb +45 -42
- data/test/support/connection/hiredis.rb +1 -1
- data/test/support/connection/ruby.rb +1 -1
- data/test/support/connection/synchrony.rb +1 -1
- data/test/synchrony_driver.rb +6 -9
- data/test/thread_safety_test.rb +1 -3
- data/test/transactions_test.rb +1 -3
- data/test/unknown_commands_test.rb +1 -3
- data/test/url_param_test.rb +44 -46
- metadata +32 -16
- data/Rakefile +0 -87
data/lib/redis/distributed.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "hash_ring"
|
2
2
|
|
3
3
|
class Redis
|
4
4
|
class Distributed
|
@@ -144,8 +144,8 @@ class Redis
|
|
144
144
|
end
|
145
145
|
|
146
146
|
# Create a key using the serialized value, previously obtained using DUMP.
|
147
|
-
def restore(key, ttl, serialized_value)
|
148
|
-
node_for(key).restore(key, ttl, serialized_value)
|
147
|
+
def restore(key, ttl, serialized_value, options = {})
|
148
|
+
node_for(key).restore(key, ttl, serialized_value, options)
|
149
149
|
end
|
150
150
|
|
151
151
|
# Transfer a key from the connected instance to another instance.
|
@@ -277,13 +277,16 @@ class Redis
|
|
277
277
|
node_for(key).get(key)
|
278
278
|
end
|
279
279
|
|
280
|
-
# Get the values of all the given keys.
|
280
|
+
# Get the values of all the given keys as an Array.
|
281
281
|
def mget(*keys)
|
282
|
-
|
282
|
+
mapped_mget(*keys).values_at(*keys)
|
283
283
|
end
|
284
284
|
|
285
|
+
# Get the values of all the given keys as a Hash.
|
285
286
|
def mapped_mget(*keys)
|
286
|
-
|
287
|
+
keys.group_by { |k| node_for k }.inject({}) do |results, (node, subkeys)|
|
288
|
+
results.merge! node.mapped_mget(*subkeys)
|
289
|
+
end
|
287
290
|
end
|
288
291
|
|
289
292
|
# Overwrite part of a string at key starting at the specified offset.
|
@@ -483,8 +486,8 @@ class Redis
|
|
483
486
|
end
|
484
487
|
|
485
488
|
# Remove and return a random member from a set.
|
486
|
-
def spop(key)
|
487
|
-
node_for(key).spop(key)
|
489
|
+
def spop(key, count = nil)
|
490
|
+
node_for(key).spop(key, count)
|
488
491
|
end
|
489
492
|
|
490
493
|
# Get a random member from a set.
|
@@ -509,6 +512,16 @@ class Redis
|
|
509
512
|
node_for(key).smembers(key)
|
510
513
|
end
|
511
514
|
|
515
|
+
# Scan a set
|
516
|
+
def sscan(key, cursor, options={})
|
517
|
+
node_for(key).sscan(key, cursor, options)
|
518
|
+
end
|
519
|
+
|
520
|
+
# Scan a set and return an enumerator
|
521
|
+
def sscan_each(key, options={}, &block)
|
522
|
+
node_for(key).sscan_each(key, options, &block)
|
523
|
+
end
|
524
|
+
|
512
525
|
# Subtract multiple sets.
|
513
526
|
def sdiff(*keys)
|
514
527
|
ensure_same_node(:sdiff, keys) do |node|
|
data/lib/redis/hash_ring.rb
CHANGED
@@ -25,7 +25,6 @@ class Redis
|
|
25
25
|
@nodes << node
|
26
26
|
@replicas.times do |i|
|
27
27
|
key = Zlib.crc32("#{node.id}:#{i}")
|
28
|
-
raise "Node ID collision" if @ring.has_key?(key)
|
29
28
|
@ring[key] = node
|
30
29
|
@sorted_keys << key
|
31
30
|
end
|
@@ -61,72 +60,29 @@ class Redis
|
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
while (lower <= upper) {
|
81
|
-
idx = (lower + upper) / 2;
|
82
|
-
|
83
|
-
VALUE continuumValue = RARRAY_PTR(ary)[idx];
|
84
|
-
unsigned int l = NUM2UINT(continuumValue);
|
85
|
-
if (l == r) {
|
86
|
-
return idx;
|
87
|
-
}
|
88
|
-
else if (l > r) {
|
89
|
-
upper = idx - 1;
|
90
|
-
}
|
91
|
-
else {
|
92
|
-
lower = idx + 1;
|
93
|
-
}
|
94
|
-
}
|
95
|
-
if (upper < 0) {
|
96
|
-
upper = RARRAY_LEN(ary) - 1;
|
97
|
-
}
|
98
|
-
return upper;
|
99
|
-
}
|
100
|
-
EOM
|
101
|
-
end
|
102
|
-
rescue Exception
|
103
|
-
# Find the closest index in HashRing with value <= the given value
|
104
|
-
def binary_search(ary, value, &block)
|
105
|
-
upper = ary.size - 1
|
106
|
-
lower = 0
|
107
|
-
idx = 0
|
108
|
-
|
109
|
-
while(lower <= upper) do
|
110
|
-
idx = (lower + upper) / 2
|
111
|
-
comp = ary[idx] <=> value
|
112
|
-
|
113
|
-
if comp == 0
|
114
|
-
return idx
|
115
|
-
elsif comp > 0
|
116
|
-
upper = idx - 1
|
117
|
-
else
|
118
|
-
lower = idx + 1
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
if upper < 0
|
123
|
-
upper = ary.size - 1
|
124
|
-
end
|
125
|
-
return upper
|
63
|
+
# Find the closest index in HashRing with value <= the given value
|
64
|
+
def self.binary_search(ary, value, &block)
|
65
|
+
upper = ary.size - 1
|
66
|
+
lower = 0
|
67
|
+
idx = 0
|
68
|
+
|
69
|
+
while(lower <= upper) do
|
70
|
+
idx = (lower + upper) / 2
|
71
|
+
comp = ary[idx] <=> value
|
72
|
+
|
73
|
+
if comp == 0
|
74
|
+
return idx
|
75
|
+
elsif comp > 0
|
76
|
+
upper = idx - 1
|
77
|
+
else
|
78
|
+
lower = idx + 1
|
126
79
|
end
|
80
|
+
end
|
127
81
|
|
82
|
+
if upper < 0
|
83
|
+
upper = ary.size - 1
|
128
84
|
end
|
85
|
+
return upper
|
129
86
|
end
|
130
|
-
|
131
87
|
end
|
132
88
|
end
|
data/lib/redis/pipeline.rb
CHANGED
data/lib/redis/version.rb
CHANGED
data/lib/redis.rb
CHANGED
@@ -1,21 +1,8 @@
|
|
1
1
|
require "monitor"
|
2
|
-
|
2
|
+
require_relative "redis/errors"
|
3
3
|
|
4
4
|
class Redis
|
5
5
|
|
6
|
-
def self.deprecate(message, trace = caller[0])
|
7
|
-
$stderr.puts "\n#{message} (in #{trace})"
|
8
|
-
end
|
9
|
-
|
10
|
-
attr :client
|
11
|
-
|
12
|
-
# @deprecated The preferred way to create a new client object is using `#new`.
|
13
|
-
# This method does not actually establish a connection to Redis,
|
14
|
-
# in contrary to what you might expect.
|
15
|
-
def self.connect(options = {})
|
16
|
-
new(options)
|
17
|
-
end
|
18
|
-
|
19
6
|
def self.current
|
20
7
|
@current ||= Redis.new
|
21
8
|
end
|
@@ -119,6 +106,10 @@ class Redis
|
|
119
106
|
end
|
120
107
|
end
|
121
108
|
|
109
|
+
def _client
|
110
|
+
@client
|
111
|
+
end
|
112
|
+
|
122
113
|
# Authenticate to the server.
|
123
114
|
#
|
124
115
|
# @param [String] password must match the password specified in the
|
@@ -143,10 +134,11 @@ class Redis
|
|
143
134
|
|
144
135
|
# Ping the server.
|
145
136
|
#
|
137
|
+
# @param [optional, String] message
|
146
138
|
# @return [String] `PONG`
|
147
|
-
def ping
|
139
|
+
def ping(message = nil)
|
148
140
|
synchronize do |client|
|
149
|
-
client.call([:ping])
|
141
|
+
client.call([:ping, message].compact)
|
150
142
|
end
|
151
143
|
end
|
152
144
|
|
@@ -209,6 +201,25 @@ class Redis
|
|
209
201
|
end
|
210
202
|
end
|
211
203
|
|
204
|
+
# Manage client connections.
|
205
|
+
#
|
206
|
+
# @param [String, Symbol] subcommand e.g. `kill`, `list`, `getname`, `setname`
|
207
|
+
# @return [String, Hash] depends on subcommand
|
208
|
+
def client(subcommand = nil, *args)
|
209
|
+
synchronize do |client|
|
210
|
+
client.call([:client, subcommand] + args) do |reply|
|
211
|
+
if subcommand.to_s == "list"
|
212
|
+
reply.lines.map do |line|
|
213
|
+
entries = line.chomp.split(/[ =]/)
|
214
|
+
Hash[entries.each_slice(2).to_a]
|
215
|
+
end
|
216
|
+
else
|
217
|
+
reply
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
212
223
|
# Return the number of keys in the selected database.
|
213
224
|
#
|
214
225
|
# @return [Fixnum]
|
@@ -226,19 +237,31 @@ class Redis
|
|
226
237
|
|
227
238
|
# Remove all keys from all databases.
|
228
239
|
#
|
240
|
+
# @param [Hash] options
|
241
|
+
# - `:async => Boolean`: async flush (default: false)
|
229
242
|
# @return [String] `OK`
|
230
|
-
def flushall
|
243
|
+
def flushall(options = nil)
|
231
244
|
synchronize do |client|
|
232
|
-
|
245
|
+
if options && options[:async]
|
246
|
+
client.call([:flushall, :async])
|
247
|
+
else
|
248
|
+
client.call([:flushall])
|
249
|
+
end
|
233
250
|
end
|
234
251
|
end
|
235
252
|
|
236
253
|
# Remove all keys from the current database.
|
237
254
|
#
|
255
|
+
# @param [Hash] options
|
256
|
+
# - `:async => Boolean`: async flush (default: false)
|
238
257
|
# @return [String] `OK`
|
239
|
-
def flushdb
|
258
|
+
def flushdb(options = nil)
|
240
259
|
synchronize do |client|
|
241
|
-
|
260
|
+
if options && options[:async]
|
261
|
+
client.call([:flushdb, :async])
|
262
|
+
else
|
263
|
+
client.call([:flushdb])
|
264
|
+
end
|
242
265
|
end
|
243
266
|
end
|
244
267
|
|
@@ -458,10 +481,16 @@ class Redis
|
|
458
481
|
# @param [String] key
|
459
482
|
# @param [String] ttl
|
460
483
|
# @param [String] serialized_value
|
484
|
+
# @param [Hash] options
|
485
|
+
# - `:replace => Boolean`: if false, raises an error if key already exists
|
486
|
+
# @raise [Redis::CommandError]
|
461
487
|
# @return [String] `"OK"`
|
462
|
-
def restore(key, ttl, serialized_value)
|
488
|
+
def restore(key, ttl, serialized_value, options = {})
|
489
|
+
args = [:restore, key, ttl, serialized_value]
|
490
|
+
args << 'REPLACE' if options[:replace]
|
491
|
+
|
463
492
|
synchronize do |client|
|
464
|
-
client.call(
|
493
|
+
client.call(args)
|
465
494
|
end
|
466
495
|
end
|
467
496
|
|
@@ -477,8 +506,8 @@ class Redis
|
|
477
506
|
def migrate(key, options)
|
478
507
|
host = options[:host] || raise(RuntimeError, ":host not specified")
|
479
508
|
port = options[:port] || raise(RuntimeError, ":port not specified")
|
480
|
-
db = (options[:db] || client.db).to_i
|
481
|
-
timeout = (options[:timeout] || client.timeout).to_i
|
509
|
+
db = (options[:db] || @client.db).to_i
|
510
|
+
timeout = (options[:timeout] || @client.timeout).to_i
|
482
511
|
|
483
512
|
synchronize do |client|
|
484
513
|
client.call([:migrate, host, port, key, db, timeout])
|
@@ -756,8 +785,6 @@ class Redis
|
|
756
785
|
end
|
757
786
|
end
|
758
787
|
|
759
|
-
alias :[]= :set
|
760
|
-
|
761
788
|
# Set the time to live in seconds of a key.
|
762
789
|
#
|
763
790
|
# @param [String] key
|
@@ -863,8 +890,6 @@ class Redis
|
|
863
890
|
end
|
864
891
|
end
|
865
892
|
|
866
|
-
alias :[] :get
|
867
|
-
|
868
893
|
# Get the values of all the given keys.
|
869
894
|
#
|
870
895
|
# @example
|
@@ -1041,7 +1066,7 @@ class Redis
|
|
1041
1066
|
# Prepend one or more values to a list, creating the list if it doesn't exist
|
1042
1067
|
#
|
1043
1068
|
# @param [String] key
|
1044
|
-
# @param [String, Array] value string value, or array of string values to push
|
1069
|
+
# @param [String, Array<String>] value string value, or array of string values to push
|
1045
1070
|
# @return [Fixnum] the length of the list after the push operation
|
1046
1071
|
def lpush(key, value)
|
1047
1072
|
synchronize do |client|
|
@@ -1063,7 +1088,7 @@ class Redis
|
|
1063
1088
|
# Append one or more values to a list, creating the list if it doesn't exist
|
1064
1089
|
#
|
1065
1090
|
# @param [String] key
|
1066
|
-
# @param [String] value
|
1091
|
+
# @param [String, Array<String>] value string value, or array of string values to push
|
1067
1092
|
# @return [Fixnum] the length of the list after the push operation
|
1068
1093
|
def rpush(key, value)
|
1069
1094
|
synchronize do |client|
|
@@ -1336,13 +1361,18 @@ class Redis
|
|
1336
1361
|
end
|
1337
1362
|
end
|
1338
1363
|
|
1339
|
-
# Remove and return
|
1364
|
+
# Remove and return one or more random member from a set.
|
1340
1365
|
#
|
1341
1366
|
# @param [String] key
|
1342
1367
|
# @return [String]
|
1343
|
-
|
1368
|
+
# @param [Fixnum] count
|
1369
|
+
def spop(key, count = nil)
|
1344
1370
|
synchronize do |client|
|
1345
|
-
|
1371
|
+
if count.nil?
|
1372
|
+
client.call([:spop, key])
|
1373
|
+
else
|
1374
|
+
client.call([:spop, key, count])
|
1375
|
+
end
|
1346
1376
|
end
|
1347
1377
|
end
|
1348
1378
|
|
@@ -1696,6 +1726,30 @@ class Redis
|
|
1696
1726
|
end
|
1697
1727
|
end
|
1698
1728
|
|
1729
|
+
# Count the members, with the same score in a sorted set, within the given lexicographical range.
|
1730
|
+
#
|
1731
|
+
# @example Count members matching a
|
1732
|
+
# redis.zlexcount("zset", "[a", "[a\xff")
|
1733
|
+
# # => 1
|
1734
|
+
# @example Count members matching a-z
|
1735
|
+
# redis.zlexcount("zset", "[a", "[z\xff")
|
1736
|
+
# # => 26
|
1737
|
+
#
|
1738
|
+
# @param [String] key
|
1739
|
+
# @param [String] min
|
1740
|
+
# - inclusive minimum is specified by prefixing `(`
|
1741
|
+
# - exclusive minimum is specified by prefixing `[`
|
1742
|
+
# @param [String] max
|
1743
|
+
# - inclusive maximum is specified by prefixing `(`
|
1744
|
+
# - exclusive maximum is specified by prefixing `[`
|
1745
|
+
#
|
1746
|
+
# @return [Fixnum] number of members within the specified lexicographical range
|
1747
|
+
def zlexcount(key, min, max)
|
1748
|
+
synchronize do |client|
|
1749
|
+
client.call([:zlexcount, key, min, max])
|
1750
|
+
end
|
1751
|
+
end
|
1752
|
+
|
1699
1753
|
# Return a range of members with the same score in a sorted set, by lexicographical ordering
|
1700
1754
|
#
|
1701
1755
|
# @example Retrieve members matching a
|
@@ -2695,6 +2749,16 @@ class Redis
|
|
2695
2749
|
self.class.new(@options)
|
2696
2750
|
end
|
2697
2751
|
|
2752
|
+
def connection
|
2753
|
+
{
|
2754
|
+
host: @original_client.host,
|
2755
|
+
port: @original_client.port,
|
2756
|
+
db: @original_client.db,
|
2757
|
+
id: @original_client.id,
|
2758
|
+
location: @original_client.location
|
2759
|
+
}
|
2760
|
+
end
|
2761
|
+
|
2698
2762
|
def method_missing(command, *args)
|
2699
2763
|
synchronize do |client|
|
2700
2764
|
client.call([command] + args)
|
@@ -2766,8 +2830,8 @@ private
|
|
2766
2830
|
|
2767
2831
|
end
|
2768
2832
|
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2833
|
+
require_relative "redis/version"
|
2834
|
+
require_relative "redis/connection"
|
2835
|
+
require_relative "redis/client"
|
2836
|
+
require_relative "redis/pipeline"
|
2837
|
+
require_relative "redis/subscribe"
|
data/makefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
TEST_FILES := $(shell find test -name *_test.rb -type f)
|
2
|
+
REDIS_BRANCH := unstable
|
3
|
+
TMP := tmp
|
4
|
+
BUILD_DIR := ${TMP}/redis-${REDIS_BRANCH}
|
5
|
+
TARBALL := ${TMP}/redis-${REDIS_BRANCH}.tar.gz
|
6
|
+
BINARY := ${BUILD_DIR}/src/redis-server
|
7
|
+
PID_PATH := ${BUILD_DIR}/redis.pid
|
8
|
+
SOCKET_PATH := ${BUILD_DIR}/redis.sock
|
9
|
+
PORT := 6381
|
10
|
+
|
11
|
+
test: ${TEST_FILES}
|
12
|
+
make start
|
13
|
+
env SOCKET_PATH=${SOCKET_PATH} \
|
14
|
+
ruby -v $$(echo $? | tr ' ' '\n' | awk '{ print "-r./" $$0 }') -e ''
|
15
|
+
make stop
|
16
|
+
|
17
|
+
${TMP}:
|
18
|
+
mkdir $@
|
19
|
+
|
20
|
+
${TARBALL}: ${TMP}
|
21
|
+
wget https://github.com/antirez/redis/archive/${REDIS_BRANCH}.tar.gz -O $@
|
22
|
+
|
23
|
+
${BINARY}: ${TARBALL} ${TMP}
|
24
|
+
rm -rf ${BUILD_DIR}
|
25
|
+
mkdir -p ${BUILD_DIR}
|
26
|
+
tar xf ${TARBALL} -C ${TMP}
|
27
|
+
cd ${BUILD_DIR} && make
|
28
|
+
|
29
|
+
stop:
|
30
|
+
(test -f ${PID_PATH} && (kill $$(cat ${PID_PATH}) || true) && rm -f ${PID_PATH}) || true
|
31
|
+
|
32
|
+
start: ${BINARY}
|
33
|
+
${BINARY} \
|
34
|
+
--daemonize yes \
|
35
|
+
--pidfile ${PID_PATH} \
|
36
|
+
--port ${PORT} \
|
37
|
+
--unixsocket ${SOCKET_PATH}
|
38
|
+
|
39
|
+
clean:
|
40
|
+
(test -d ${BUILD_DIR} && cd ${BUILD_DIR}/src && make clean distclean) || true
|
41
|
+
|
42
|
+
.PHONY: test start stop
|
data/redis.gemspec
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$:.unshift File.expand_path("../lib", __FILE__)
|
4
|
-
|
5
|
-
require "redis/version"
|
1
|
+
require "./lib/redis/version"
|
6
2
|
|
7
3
|
Gem::Specification.new do |s|
|
8
4
|
s.name = "redis"
|
@@ -15,8 +11,7 @@ Gem::Specification.new do |s|
|
|
15
11
|
|
16
12
|
s.description = <<-EOS
|
17
13
|
A Ruby client that tries to match Redis' API one-to-one, while still
|
18
|
-
providing an idiomatic interface.
|
19
|
-
client-side sharding, pipelining, and an obsession for performance.
|
14
|
+
providing an idiomatic interface.
|
20
15
|
EOS
|
21
16
|
|
22
17
|
s.license = "MIT"
|
@@ -39,6 +34,9 @@ Gem::Specification.new do |s|
|
|
39
34
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
40
35
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
41
36
|
|
42
|
-
s.
|
43
|
-
|
37
|
+
s.required_ruby_version = '>= 2.2.2'
|
38
|
+
|
39
|
+
s.add_development_dependency("test-unit", ">= 3.1.5")
|
40
|
+
s.add_development_dependency("hiredis")
|
41
|
+
s.add_development_dependency("em-synchrony")
|
44
42
|
end
|
data/test/bitpos_test.rb
CHANGED
@@ -1,10 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
unless defined?(Enumerator)
|
6
|
-
Enumerator = Enumerable::Enumerator
|
7
|
-
end
|
1
|
+
require_relative "helper"
|
8
2
|
|
9
3
|
class TestBitpos < Test::Unit::TestCase
|
10
4
|
|
@@ -13,48 +7,48 @@ class TestBitpos < Test::Unit::TestCase
|
|
13
7
|
def test_bitpos_empty_zero
|
14
8
|
target_version "2.9.11" do
|
15
9
|
r.del "foo"
|
16
|
-
assert_equal
|
10
|
+
assert_equal(0, r.bitpos("foo", 0))
|
17
11
|
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def test_bitpos_empty_one
|
21
15
|
target_version "2.9.11" do
|
22
16
|
r.del "foo"
|
23
|
-
assert_equal
|
17
|
+
assert_equal(-1, r.bitpos("foo", 1))
|
24
18
|
end
|
25
19
|
end
|
26
20
|
|
27
21
|
def test_bitpos_zero
|
28
22
|
target_version "2.9.11" do
|
29
23
|
r.set "foo", "\xff\xf0\x00"
|
30
|
-
assert_equal
|
24
|
+
assert_equal(12, r.bitpos("foo", 0))
|
31
25
|
end
|
32
26
|
end
|
33
27
|
|
34
28
|
def test_bitpos_one
|
35
29
|
target_version "2.9.11" do
|
36
30
|
r.set "foo", "\x00\x0f\x00"
|
37
|
-
assert_equal
|
31
|
+
assert_equal(12, r.bitpos("foo", 1))
|
38
32
|
end
|
39
33
|
end
|
40
34
|
|
41
35
|
def test_bitpos_zero_end_is_given
|
42
36
|
target_version "2.9.11" do
|
43
37
|
r.set "foo", "\xff\xff\xff"
|
44
|
-
assert_equal
|
45
|
-
assert_equal
|
46
|
-
assert_equal
|
38
|
+
assert_equal(24, r.bitpos("foo", 0))
|
39
|
+
assert_equal(24, r.bitpos("foo", 0, 0))
|
40
|
+
assert_equal(-1, r.bitpos("foo", 0, 0, -1))
|
47
41
|
end
|
48
42
|
end
|
49
43
|
|
50
44
|
def test_bitpos_one_intervals
|
51
45
|
target_version "2.9.11" do
|
52
46
|
r.set "foo", "\x00\xff\x00"
|
53
|
-
assert_equal
|
54
|
-
assert_equal
|
55
|
-
assert_equal
|
56
|
-
assert_equal
|
57
|
-
assert_equal
|
47
|
+
assert_equal(8, r.bitpos("foo", 1, 0, -1))
|
48
|
+
assert_equal(8, r.bitpos("foo", 1, 1, -1))
|
49
|
+
assert_equal(-1, r.bitpos("foo", 1, 2, -1))
|
50
|
+
assert_equal(-1, r.bitpos("foo", 1, 2, 200))
|
51
|
+
assert_equal(8, r.bitpos("foo", 1, 1, 1))
|
58
52
|
end
|
59
53
|
end
|
60
54
|
|
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/blocking_commands"
|
1
|
+
require_relative "helper"
|
2
|
+
require_relative "lint/blocking_commands"
|
5
3
|
|
6
4
|
class TestBlockingCommands < Test::Unit::TestCase
|
7
5
|
|
@@ -17,7 +15,7 @@ class TestBlockingCommands < Test::Unit::TestCase
|
|
17
15
|
yield(r)
|
18
16
|
t2 = Time.now
|
19
17
|
|
20
|
-
assert timeout == r.
|
18
|
+
assert timeout == r._client.timeout
|
21
19
|
assert delay <= (t2 - t1)
|
22
20
|
end
|
23
21
|
end
|
data/test/client_test.rb
CHANGED
data/test/command_map_test.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
1
|
+
require_relative "helper"
|
4
2
|
|
5
3
|
class TestCommandMap < Test::Unit::TestCase
|
6
4
|
|
@@ -11,7 +9,7 @@ class TestCommandMap < Test::Unit::TestCase
|
|
11
9
|
|
12
10
|
assert_equal 2, r.incr("counter")
|
13
11
|
|
14
|
-
r.
|
12
|
+
r._client.command_map[:incr] = :decr
|
15
13
|
|
16
14
|
assert_equal 1, r.incr("counter")
|
17
15
|
end
|
@@ -23,7 +21,7 @@ class TestCommandMap < Test::Unit::TestCase
|
|
23
21
|
r.idontexist("key")
|
24
22
|
end
|
25
23
|
|
26
|
-
r.
|
24
|
+
r._client.command_map[:idontexist] = :get
|
27
25
|
|
28
26
|
assert_equal "value", r.idontexist("key")
|
29
27
|
end
|
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
4
|
-
require "lint/hyper_log_log"
|
1
|
+
require_relative "helper"
|
2
|
+
require_relative "lint/hyper_log_log"
|
5
3
|
|
6
4
|
class TestCommandsOnHyperLogLog < Test::Unit::TestCase
|
7
5
|
|
@@ -18,4 +16,4 @@ class TestCommandsOnHyperLogLog < Test::Unit::TestCase
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
|
-
end
|
19
|
+
end
|