redis 4.0.1 → 4.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e0d0ba2328aca583c0f487729779c2b10b12c7b
4
- data.tar.gz: 4a411cfa3512bafe7c2c12ac8a02c02bc87065aa
3
+ metadata.gz: e8fe8cb80ceaefd35f21b3ae06bdfa7594a1878a
4
+ data.tar.gz: ec9c330b13ac9639b6033c96b9e92da659eede4e
5
5
  SHA512:
6
- metadata.gz: 3af7dc63dc7bdc243da306817583db9b6989c21a0714c6652b4a443bfd9c46b2afba0707b028d708a74148bbeedd09d4ec207a0459b3559cb19b95f2f030bb07
7
- data.tar.gz: 98d5aed456ebcd3ccdc50980879a3c14be4c8a1874c6febae95579d2fb3828bda2e82b05e62dc6a4966e178993d4a2a20dc3dedd9f8583cd731851eab2f8e164
6
+ metadata.gz: 215cf01a2c7987aafb818959f1dd70688099b48f51fbc55d0bacc2ebddc27d45f7a60aca57e412a80f94dc6d9316312fa29be1e1077092a92657bd75103cae2a
7
+ data.tar.gz: f26724045477ec4d5d5351611266489c13f778fe2eed7ace4824f37dcadfc378a69271abe22166fc2da16da0ac0b5236448828d36a0c44146a22dfe0d886045e
@@ -1,4 +1,10 @@
1
1
  language: ruby
2
+ cache:
3
+ directories:
4
+ - tmp/cache
5
+ before_install:
6
+ - gem update --system 2.6.14
7
+ - gem --version
2
8
 
3
9
  script: make test
4
10
 
@@ -6,8 +12,8 @@ rvm:
6
12
  - 2.2.2
7
13
  - 2.3.3
8
14
  - 2.4.1
9
- - jruby-9
10
- - rbx-3
15
+ - 2.5.0
16
+ - jruby-9.1.17.0
11
17
 
12
18
  gemfile: ".travis/Gemfile"
13
19
 
@@ -27,7 +33,7 @@ env:
27
33
  - DRIVER=hiredis REDIS_BRANCH=3.2
28
34
  - DRIVER=synchrony REDIS_BRANCH=3.0
29
35
  - DRIVER=synchrony REDIS_BRANCH=3.2
30
- - DRIVER=ruby REDIS_BRANCH=unstable
36
+ - DRIVER=ruby REDIS_BRANCH=4.0
31
37
 
32
38
  branches:
33
39
  only:
@@ -38,34 +44,16 @@ branches:
38
44
  matrix:
39
45
  exclude:
40
46
  # hiredis
41
- - rvm: jruby-9
42
- gemfile: .travis/Gemfile
43
- env: DRIVER=hiredis REDIS_BRANCH=3.0
44
- - rvm: jruby-9
45
- gemfile: .travis/Gemfile
46
- env: DRIVER=hiredis REDIS_BRANCH=3.2
47
- - rvm: jruby-9
48
- gemfile: .travis/Gemfile
49
- env: DRIVER=hiredis REDIS_BRANCH=3.0
50
- - rvm: jruby-9
51
- gemfile: .travis/Gemfile
52
- env: DRIVER=hiredis REDIS_BRANCH=3.2
47
+ - rvm: jruby-9.1.17.0
48
+ env: DRIVER=hiredis REDIS_BRANCH=3.0
49
+ - rvm: jruby-9.1.17.0
50
+ env: DRIVER=hiredis REDIS_BRANCH=3.2
53
51
 
54
52
  # synchrony
55
- - rvm: jruby-9
56
- gemfile: .travis/Gemfile
53
+ - rvm: jruby-9.1.17.0
57
54
  env: DRIVER=synchrony REDIS_BRANCH=3.0
58
- - rvm: jruby-9
59
- gemfile: .travis/Gemfile
55
+ - rvm: jruby-9.1.17.0
60
56
  env: DRIVER=synchrony REDIS_BRANCH=3.2
61
- - rvm: jruby-9
62
- gemfile: .travis/Gemfile
63
- env: DRIVER=synchrony REDIS_BRANCH=3.0
64
- - rvm: jruby-9
65
- gemfile: .travis/Gemfile
66
- env: DRIVER=synchrony REDIS_BRANCH=3.2
67
- allow_failures:
68
- - rvm: rbx-3
69
57
 
70
58
  notifications:
71
59
  irc:
@@ -2,6 +2,11 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec :path => "../"
4
4
 
5
+ # Using jruby-openssl 0.10.0, we get NPEs in jruby tests: https://github.com/redis/redis-rb/issues/756
6
+ platform :jruby do
7
+ gem 'jruby-openssl', '<0.10.0'
8
+ end
9
+
5
10
  case ENV["DRIVER"]
6
11
  when "hiredis"
7
12
  gem "hiredis"
@@ -1,3 +1,17 @@
1
+ # 4.0.2
2
+
3
+ * Added `Redis#unlink`. See #766.
4
+
5
+ * `Redis.new` now accept a custom connector via `:connector`. See #591.
6
+
7
+ * `Redis#multi` no longer perform empty transactions. See #747.
8
+
9
+ * `Redis#hdel` now accepts hash keys as multiple arguments like `#del`. See #755.
10
+
11
+ * Allow to skip SSL verification. See #745.
12
+
13
+ * Add Geo commands: `geoadd`, `geohash`, `georadius`, `georadiusbymember`, `geopos`, `geodist`. See #730.
14
+
1
15
  # 4.0.1
2
16
 
3
17
  * `Redis::Distributed` now supports `mget` and `mapped_mget`. See #687.
@@ -21,6 +35,15 @@
21
35
 
22
36
  * Dropped official support for Ruby < 2.2.2.
23
37
 
38
+ # 3.3.5
39
+
40
+ * Fixed Ruby 1.8 compatibility after backporting `Redis#connection`. See #719.
41
+
42
+ # 3.3.4 (yanked)
43
+
44
+ * `Redis#connection` returns a hash with connection information.
45
+ You shouldn't need to call `Redis#_client`, ever.
46
+
24
47
  # 3.3.3
25
48
 
26
49
  * Improved timeout handling after dropping Timeout module.
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ # Using jruby-openssl 0.10.0, we get NPEs in jruby tests: https://github.com/redis/redis-rb/issues/756
6
+ platform :jruby do
7
+ gem 'jruby-openssl', '<0.10.0'
8
+ end
data/README.md CHANGED
@@ -176,7 +176,7 @@ it can't connect to the server a `Redis::CannotConnectError` error will be raise
176
176
  ```ruby
177
177
  begin
178
178
  redis.ping
179
- rescue Exception => e
179
+ rescue StandardError => e
180
180
  e.inspect
181
181
  # => #<Redis::CannotConnectError: Timed out connecting to Redis on 10.0.1.1:6380>
182
182
 
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ TARBALL = ARGV[0]
4
+
5
+ require 'digest/sha1'
6
+ require 'fileutils'
7
+
8
+ class Builder
9
+ def initialize(redis_branch, tmp_dir)
10
+ @redis_branch = redis_branch
11
+ @tmp_dir = tmp_dir
12
+ @build_dir = File.join(@tmp_dir, "cache", "redis-#{redis_branch}")
13
+ end
14
+
15
+ def run
16
+ download_tarball
17
+ if old_checkum != checksum
18
+ build
19
+ update_checksum
20
+ end
21
+ 0
22
+ end
23
+
24
+ def download_tarball
25
+ command!('wget', tarball_url, '-O', tarball_path)
26
+ end
27
+
28
+ def tarball_path
29
+ File.join(@tmp_dir, "redis-#{@redis_branch}.tar.gz")
30
+ end
31
+
32
+ def tarball_url
33
+ "https://github.com/antirez/redis/archive/#{@redis_branch}.tar.gz"
34
+ end
35
+
36
+ def build
37
+ FileUtils.rm_rf(@build_dir)
38
+ FileUtils.mkdir_p(@build_dir)
39
+ command!('tar', 'xf', tarball_path, '-C', File.expand_path('../', @build_dir))
40
+ Dir.chdir(@build_dir) do
41
+ command!('make')
42
+ end
43
+ end
44
+
45
+ def update_checksum
46
+ File.write(checksum_path, checksum)
47
+ end
48
+
49
+ def old_checkum
50
+ File.read(checksum_path)
51
+ rescue Errno::ENOENT
52
+ nil
53
+ end
54
+
55
+ def checksum_path
56
+ File.join(@build_dir, 'build.checksum')
57
+ end
58
+
59
+ def checksum
60
+ @checksum ||= Digest::SHA1.file(tarball_path).hexdigest
61
+ end
62
+
63
+ def command!(*args)
64
+ puts "$ #{args.join(' ')}"
65
+ unless system(*args)
66
+ raise "Command failed with status #{$?.exitstatus}"
67
+ end
68
+ end
69
+ end
70
+
71
+ exit Builder.new(ARGV[0], ARGV[1]).run
@@ -524,6 +524,16 @@ class Redis
524
524
  end
525
525
  end
526
526
 
527
+ # Unlink one or more keys.
528
+ #
529
+ # @param [String, Array<String>] keys
530
+ # @return [Fixnum] number of keys that were unlinked
531
+ def unlink(*keys)
532
+ synchronize do |client|
533
+ client.call([:unlink] + keys)
534
+ end
535
+ end
536
+
527
537
  # Determine if a key exists.
528
538
  #
529
539
  # @param [String] key
@@ -2102,9 +2112,9 @@ class Redis
2102
2112
  # @param [String] key
2103
2113
  # @param [String, Array<String>] field
2104
2114
  # @return [Fixnum] the number of fields that were removed from the hash
2105
- def hdel(key, field)
2115
+ def hdel(key, *fields)
2106
2116
  synchronize do |client|
2107
- client.call([:hdel, key, field])
2117
+ client.call([:hdel, key, *fields])
2108
2118
  end
2109
2119
  end
2110
2120
 
@@ -2710,6 +2720,86 @@ class Redis
2710
2720
  end
2711
2721
  end
2712
2722
 
2723
+ # Adds the specified geospatial items (latitude, longitude, name) to the specified key
2724
+ #
2725
+ # @param [String] key
2726
+ # @param [Array] member arguemnts for member or members: longitude, latitude, name
2727
+ # @return [Intger] number of elements added to the sorted set
2728
+ def geoadd(key, *member)
2729
+ synchronize do |client|
2730
+ client.call([:geoadd, key, member])
2731
+ end
2732
+ end
2733
+
2734
+ # Returns geohash string representing position for specified members of the specified key.
2735
+ #
2736
+ # @param [String] key
2737
+ # @param [String, Array<String>] member one member or array of members
2738
+ # @return [Array<String, nil>] returns array containg geohash string if member is present, nil otherwise
2739
+ def geohash(key, member)
2740
+ synchronize do |client|
2741
+ client.call([:geohash, key, member])
2742
+ end
2743
+ end
2744
+
2745
+
2746
+ # Query a sorted set representing a geospatial index to fetch members matching a
2747
+ # given maximum distance from a point
2748
+ #
2749
+ # @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi)
2750
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2751
+ # @param [Integer] count limit the results to the first N matching items
2752
+ # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2753
+ # @return [Array<String>] may be changed with `options`
2754
+
2755
+ def georadius(*args, **geoptions)
2756
+ geoarguments = _geoarguments(*args, **geoptions)
2757
+
2758
+ synchronize do |client|
2759
+ client.call([:georadius, *geoarguments])
2760
+ end
2761
+ end
2762
+
2763
+ # Query a sorted set representing a geospatial index to fetch members matching a
2764
+ # given maximum distance from an already existing member
2765
+ #
2766
+ # @param [Array] args key, member, radius, unit(m|km|ft|mi)
2767
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2768
+ # @param [Integer] count limit the results to the first N matching items
2769
+ # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2770
+ # @return [Array<String>] may be changed with `options`
2771
+
2772
+ def georadiusbymember(*args, **geoptions)
2773
+ geoarguments = _geoarguments(*args, **geoptions)
2774
+
2775
+ synchronize do |client|
2776
+ client.call([:georadiusbymember, *geoarguments])
2777
+ end
2778
+ end
2779
+
2780
+ # Returns longitude and latitude of members of a geospatial index
2781
+ #
2782
+ # @param [String] key
2783
+ # @param [String, Array<String>] member one member or array of members
2784
+ # @return [Array<Array<String>, nil>] returns array of elements, where each element is either array of longitude and latitude or nil
2785
+ def geopos(key, member)
2786
+ synchronize do |client|
2787
+ client.call([:geopos, key, member])
2788
+ end
2789
+ end
2790
+
2791
+ # Returns the distance between two members of a geospatial index
2792
+ #
2793
+ # @param [String ]key
2794
+ # @param [Array<String>] members
2795
+ # @param ['m', 'km', 'mi', 'ft'] unit
2796
+ # @return [String, nil] returns distance in spefied unit if both members present, nil otherwise.
2797
+ def geodist(key, member1, member2, unit = 'm')
2798
+ synchronize do |client|
2799
+ client.call([:geodist, key, member1, member2, unit])
2800
+ end
2801
+ end
2802
+
2713
2803
  # Interact with the sentinel command (masters, master, slaves, failover)
2714
2804
  #
2715
2805
  # @param [String] subcommand e.g. `masters`, `master`, `slaves`
@@ -2805,14 +2895,24 @@ private
2805
2895
  }
2806
2896
 
2807
2897
  FloatifyPairs =
2808
- lambda { |array|
2809
- if array
2810
- array.each_slice(2).map do |member, score|
2898
+ lambda { |result|
2899
+ if result.respond_to?(:each_slice)
2900
+ result.each_slice(2).map do |member, score|
2811
2901
  [member, Floatify.call(score)]
2812
2902
  end
2903
+ else
2904
+ result
2813
2905
  end
2814
2906
  }
2815
2907
 
2908
+ def _geoarguments(*args, options: nil, sort: nil, count: nil)
2909
+ args.push sort if sort
2910
+ args.push 'count', count if count
2911
+ args.push options if options
2912
+
2913
+ args.uniq
2914
+ end
2915
+
2816
2916
  def _subscription(method, timeout, channels, block)
2817
2917
  return @client.call([method] + channels) if subscribed?
2818
2918
 
@@ -150,9 +150,12 @@ class Redis
150
150
  end
151
151
 
152
152
  def call_pipeline(pipeline)
153
+ commands = pipeline.commands
154
+ return [] if commands.empty?
155
+
153
156
  with_reconnect pipeline.with_reconnect? do
154
157
  begin
155
- pipeline.finish(call_pipelined(pipeline.commands)).tap do
158
+ pipeline.finish(call_pipelined(commands)).tap do
156
159
  self.db = pipeline.db if pipeline.db
157
160
  end
158
161
  rescue ConnectionError => e
@@ -334,6 +337,7 @@ class Redis
334
337
  @connection = @options[:driver].connect(@options)
335
338
  @pending_reads = 0
336
339
  rescue TimeoutError,
340
+ SocketError,
337
341
  Errno::ECONNREFUSED,
338
342
  Errno::EHOSTDOWN,
339
343
  Errno::EHOSTUNREACH,
@@ -444,6 +448,8 @@ class Redis
444
448
  options[:read_timeout] = Float(options[:read_timeout])
445
449
  options[:write_timeout] = Float(options[:write_timeout])
446
450
 
451
+ options[:reconnect_attempts] = options[:reconnect_attempts].to_i
452
+
447
453
  options[:db] = options[:db].to_i
448
454
  options[:driver] = _parse_driver(options[:driver]) || Connection.drivers.last
449
455
 
@@ -267,7 +267,10 @@ class Redis
267
267
  ssl_sock = new(tcp_sock, ctx)
268
268
  ssl_sock.hostname = host
269
269
  ssl_sock.connect
270
- ssl_sock.post_connection_check(host)
270
+
271
+ unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE
272
+ ssl_sock.post_connection_check(host)
273
+ end
271
274
 
272
275
  ssl_sock
273
276
  end
@@ -294,7 +297,7 @@ class Redis
294
297
  end
295
298
 
296
299
  instance = new(sock)
297
- instance.timeout = config[:timeout]
300
+ instance.timeout = config[:read_timeout]
298
301
  instance.write_timeout = config[:write_timeout]
299
302
  instance.set_tcp_keepalive config[:tcp_keepalive]
300
303
  instance
@@ -161,6 +161,14 @@ class Redis
161
161
  end
162
162
  end
163
163
 
164
+ # Unlink keys.
165
+ def unlink(*args)
166
+ keys_per_node = args.group_by { |key| node_for(key) }
167
+ keys_per_node.inject(0) do |sum, (node, keys)|
168
+ sum + node.unlink(*keys)
169
+ end
170
+ end
171
+
164
172
  # Determine if a key exists.
165
173
  def exists(key)
166
174
  node_for(key).exists(key)
@@ -692,8 +700,8 @@ class Redis
692
700
  end
693
701
 
694
702
  # Delete one or more hash fields.
695
- def hdel(key, field)
696
- node_for(key).hdel(key, field)
703
+ def hdel(key, *fields)
704
+ node_for(key).hdel(key, *fields)
697
705
  end
698
706
 
699
707
  # Determine if a hash field exists.
@@ -22,6 +22,10 @@ class Redis
22
22
  @shutdown
23
23
  end
24
24
 
25
+ def empty?
26
+ @futures.empty?
27
+ end
28
+
25
29
  def call(command, &block)
26
30
  # A pipeline that contains a shutdown should not raise ECONNRESET when
27
31
  # the connection is gone.
@@ -86,7 +90,11 @@ class Redis
86
90
  end
87
91
 
88
92
  def commands
89
- [[:multi]] + super + [[:exec]]
93
+ if empty?
94
+ []
95
+ else
96
+ [[:multi]] + super + [[:exec]]
97
+ end
90
98
  end
91
99
  end
92
100
  end
@@ -1,3 +1,3 @@
1
1
  class Redis
2
- VERSION = "4.0.1"
2
+ VERSION = "4.0.2"
3
3
  end
data/makefile CHANGED
@@ -1,7 +1,7 @@
1
- TEST_FILES := $(shell find test -name *_test.rb -type f)
2
- REDIS_BRANCH := unstable
1
+ TEST_FILES := $(shell find ./test -name *_test.rb -type f)
2
+ REDIS_BRANCH ?= unstable
3
3
  TMP := tmp
4
- BUILD_DIR := ${TMP}/redis-${REDIS_BRANCH}
4
+ BUILD_DIR := ${TMP}/cache/redis-${REDIS_BRANCH}
5
5
  TARBALL := ${TMP}/redis-${REDIS_BRANCH}.tar.gz
6
6
  BINARY := ${BUILD_DIR}/src/redis-server
7
7
  PID_PATH := ${BUILD_DIR}/redis.pid
@@ -11,20 +11,14 @@ PORT := 6381
11
11
  test: ${TEST_FILES}
12
12
  make start
13
13
  env SOCKET_PATH=${SOCKET_PATH} \
14
- ruby -v $$(echo $? | tr ' ' '\n' | awk '{ print "-r./" $$0 }') -e ''
14
+ bundle exec ruby -v -e 'ARGV.each { |test_file| require test_file }' ${TEST_FILES}
15
15
  make stop
16
16
 
17
17
  ${TMP}:
18
18
  mkdir $@
19
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
20
+ ${BINARY}: ${TMP}
21
+ bin/build ${REDIS_BRANCH} ${TMP}
28
22
 
29
23
  stop:
30
24
  (test -f ${PID_PATH} && (kill $$(cat ${PID_PATH}) || true) && rm -f ${PID_PATH}) || true
@@ -0,0 +1,116 @@
1
+ require_relative "helper"
2
+
3
+ class TestCommandsGeo < Test::Unit::TestCase
4
+ include Helper::Client
5
+
6
+ def setup
7
+ super
8
+
9
+ target_version "3.2.0" do
10
+ added_items_count = r.geoadd("Sicily", 13.361389, 38.115556, "Palermo", 15.087269, 37.502669, "Catania")
11
+ assert_equal 2, added_items_count
12
+ end
13
+ end
14
+
15
+ def test_georadius_with_sort
16
+ target_version "3.2.0" do
17
+ nearest_cities = r.georadius("Sicily", 15, 37, 200, 'km', sort: 'asc')
18
+ assert_equal %w(Catania Palermo), nearest_cities
19
+
20
+ farthest_cities = r.georadius("Sicily", 15, 37, 200, 'km', sort: 'desc')
21
+ assert_equal %w(Palermo Catania), farthest_cities
22
+ end
23
+ end
24
+
25
+ def test_georadius_with_count
26
+ target_version "3.2.0" do
27
+ city = r.georadius("Sicily", 15, 37, 200, 'km', count: 1)
28
+ assert_equal %w(Catania), city
29
+ end
30
+ end
31
+
32
+ def test_georadius_with_options_count_sort
33
+ target_version "3.2.0" do
34
+ city = r.georadius("Sicily", 15, 37, 200, 'km', sort: :desc, options: :WITHDIST, count: 1)
35
+ assert_equal [["Palermo", "190.4424"]], city
36
+ end
37
+ end
38
+
39
+ def test_georadiusbymember_with_sort
40
+ target_version "3.2.0" do
41
+ nearest_cities = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: 'asc')
42
+ assert_equal %w(Catania Palermo), nearest_cities
43
+
44
+ farthest_cities = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: 'desc')
45
+ assert_equal %w(Palermo Catania), farthest_cities
46
+ end
47
+ end
48
+
49
+ def test_georadiusbymember_with_count
50
+ target_version "3.2.0" do
51
+ city = r.georadiusbymember("Sicily", "Catania", 200, 'km', count: 1)
52
+ assert_equal %w(Catania), city
53
+ end
54
+ end
55
+
56
+ def test_georadiusbymember_with_options_count_sort
57
+ target_version "3.2.0" do
58
+ city = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: :desc, options: :WITHDIST, count: 1)
59
+ assert_equal [["Palermo", "166.2742"]], city
60
+ end
61
+ end
62
+
63
+ def test_geopos
64
+ target_version "3.2.0" do
65
+ location = r.geopos("Sicily", "Catania")
66
+ assert_equal [["15.08726745843887329", "37.50266842333162032"]], location
67
+
68
+ locations = r.geopos("Sicily", ["Palermo", "Catania"])
69
+ assert_equal [["13.36138933897018433", "38.11555639549629859"], ["15.08726745843887329", "37.50266842333162032"]], locations
70
+ end
71
+ end
72
+
73
+ def test_geopos_nonexistant_location
74
+ target_version "3.2.0" do
75
+ location = r.geopos("Sicily", "Rome")
76
+ assert_equal [nil], location
77
+
78
+ locations = r.geopos("Sicily", ["Rome", "Catania"])
79
+ assert_equal [nil, ["15.08726745843887329", "37.50266842333162032"]], locations
80
+ end
81
+ end
82
+
83
+ def test_geodist
84
+ target_version "3.2.0" do
85
+ distination_in_meters = r.geodist("Sicily", "Palermo", "Catania")
86
+ assert_equal "166274.1516", distination_in_meters
87
+
88
+ distination_in_feet = r.geodist("Sicily", "Palermo", "Catania", 'ft')
89
+ assert_equal "545518.8700", distination_in_feet
90
+ end
91
+ end
92
+
93
+ def test_geodist_with_nonexistant_location
94
+ target_version "3.2.0" do
95
+ distination = r.geodist("Sicily", "Palermo", "Rome")
96
+ assert_equal nil, distination
97
+ end
98
+ end
99
+
100
+ def test_geohash
101
+ target_version "3.2.0" do
102
+ geohash = r.geohash("Sicily", "Palermo")
103
+ assert_equal ["sqc8b49rny0"], geohash
104
+
105
+ geohashes = r.geohash("Sicily", ["Palermo", "Catania"])
106
+ assert_equal %w(sqc8b49rny0 sqdtr74hyu0), geohashes
107
+ end
108
+ end
109
+
110
+ def test_geohash_with_nonexistant_location
111
+ target_version "3.2.0" do
112
+ geohashes = r.geohash("Sicily", ["Palermo", "Rome"])
113
+ assert_equal ["sqc8b49rny0", nil], geohashes
114
+ end
115
+ end
116
+ end
@@ -38,6 +38,42 @@ class TestCommandsOnValueTypes < Test::Unit::TestCase
38
38
  assert_equal [], r.keys("*").sort
39
39
  end
40
40
 
41
+ def test_unlink
42
+ target_version "4.0.0" do
43
+ r.set "foo", "s1"
44
+ r.set "bar", "s2"
45
+ r.set "baz", "s3"
46
+
47
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
48
+
49
+ assert_equal 1, r.unlink("foo")
50
+
51
+ assert_equal ["bar", "baz"], r.keys("*").sort
52
+
53
+ assert_equal 2, r.unlink("bar", "baz")
54
+
55
+ assert_equal [], r.keys("*").sort
56
+ end
57
+ end
58
+
59
+ def test_unlink_with_array_argument
60
+ target_version "4.0.0" do
61
+ r.set "foo", "s1"
62
+ r.set "bar", "s2"
63
+ r.set "baz", "s3"
64
+
65
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
66
+
67
+ assert_equal 1, r.unlink(["foo"])
68
+
69
+ assert_equal ["bar", "baz"], r.keys("*").sort
70
+
71
+ assert_equal 2, r.unlink(["bar", "baz"])
72
+
73
+ assert_equal [], r.keys("*").sort
74
+ end
75
+ end
76
+
41
77
  def test_randomkey
42
78
  assert r.randomkey.to_s.empty?
43
79
 
@@ -38,6 +38,42 @@ class TestDistributedCommandsOnValueTypes < Test::Unit::TestCase
38
38
  assert_equal [], r.keys("*").sort
39
39
  end
40
40
 
41
+ def test_unlink
42
+ target_version "4.0.0" do
43
+ r.set "foo", "s1"
44
+ r.set "bar", "s2"
45
+ r.set "baz", "s3"
46
+
47
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
48
+
49
+ assert_equal 1, r.unlink("foo")
50
+
51
+ assert_equal ["bar", "baz"], r.keys("*").sort
52
+
53
+ assert_equal 2, r.unlink("bar", "baz")
54
+
55
+ assert_equal [], r.keys("*").sort
56
+ end
57
+ end
58
+
59
+ def test_unlink_with_array_argument
60
+ target_version "4.0.0" do
61
+ r.set "foo", "s1"
62
+ r.set "bar", "s2"
63
+ r.set "baz", "s3"
64
+
65
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
66
+
67
+ assert_equal 1, r.unlink(["foo"])
68
+
69
+ assert_equal ["bar", "baz"], r.keys("*").sort
70
+
71
+ assert_equal 2, r.unlink(["bar", "baz"])
72
+
73
+ assert_equal [], r.keys("*").sort
74
+ end
75
+ end
76
+
41
77
  def test_randomkey
42
78
  assert_raise Redis::Distributed::CannotDistribute do
43
79
  r.randomkey
@@ -334,7 +334,13 @@ class TestInternals < Test::Unit::TestCase
334
334
  begin
335
335
  sa = Socket.pack_sockaddr_in(1024 + Random.rand(63076), hosts[af])
336
336
  s.bind(sa)
337
- rescue Errno::EADDRINUSE
337
+ rescue Errno::EADDRINUSE => e
338
+ # On JRuby (9.1.15.0), if IPv6 is globally disabled on the system,
339
+ # we get an EADDRINUSE with belows message.
340
+ if e.message =~ /Protocol family unavailable/
341
+ return
342
+ end
343
+
338
344
  tries -= 1
339
345
  retry if tries > 0
340
346
 
@@ -30,6 +30,21 @@ module Lint
30
30
  assert_equal nil, r.hget("foo", "f1")
31
31
  end
32
32
 
33
+ def test_splat_hdel
34
+ target_version "2.3.9" do
35
+ r.hset("foo", "f1", "s1")
36
+ r.hset("foo", "f2", "s2")
37
+
38
+ assert_equal "s1", r.hget("foo", "f1")
39
+ assert_equal "s2", r.hget("foo", "f2")
40
+
41
+ assert_equal 2, r.hdel("foo", "f1", "f2")
42
+
43
+ assert_equal nil, r.hget("foo", "f1")
44
+ assert_equal nil, r.hget("foo", "f2")
45
+ end
46
+ end
47
+
33
48
  def test_variadic_hdel
34
49
  target_version "2.3.9" do
35
50
  r.hset("foo", "f1", "s1")
@@ -128,6 +128,14 @@ class TestPipeliningCommands < Test::Unit::TestCase
128
128
  end
129
129
  end
130
130
 
131
+ def test_futures_raise_when_command_errors_and_needs_transformation
132
+ assert_raise(Redis::CommandError) do
133
+ r.pipelined do
134
+ @result = r.zrange("a", "b", 5, :with_scores => true)
135
+ end
136
+ end
137
+ end
138
+
131
139
  def test_futures_can_be_identified
132
140
  r.pipelined do
133
141
  @result = r.sadd("foo", 1)
@@ -42,7 +42,7 @@ module RedisMock
42
42
  end
43
43
  end
44
44
  rescue => ex
45
- $stderr.puts "Error running mock server: #{ex.message}"
45
+ $stderr.puts "Error running mock server: #{ex.class}: #{ex.message}"
46
46
  $stderr.puts ex.backtrace
47
47
  retry
48
48
  ensure
@@ -114,6 +114,16 @@ class TestTransactions < Test::Unit::TestCase
114
114
  assert_equal "s1", r.get("foo")
115
115
  end
116
116
 
117
+ def test_empty_multi_exec
118
+ result = nil
119
+
120
+ redis_mock(:exec => lambda { |*_| "-ERROR" }) do |redis|
121
+ result = redis.multi {}
122
+ end
123
+
124
+ assert_equal [], result
125
+ end
126
+
117
127
  def test_raise_command_errors_when_accessing_futures_after_multi_exec
118
128
  begin
119
129
  r.multi do |m|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2017-09-28 00:00:00.000000000 Z
19
+ date: 2018-08-13 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: test-unit
@@ -65,7 +65,8 @@ description: |2
65
65
  providing an idiomatic interface.
66
66
  email:
67
67
  - redis-db@googlegroups.com
68
- executables: []
68
+ executables:
69
+ - build
69
70
  extensions: []
70
71
  extra_rdoc_files: []
71
72
  files:
@@ -82,6 +83,7 @@ files:
82
83
  - benchmarking/speed.rb
83
84
  - benchmarking/suite.rb
84
85
  - benchmarking/worker.rb
86
+ - bin/build
85
87
  - bors.toml
86
88
  - examples/basic.rb
87
89
  - examples/consistency.rb
@@ -115,6 +117,7 @@ files:
115
117
  - test/blocking_commands_test.rb
116
118
  - test/client_test.rb
117
119
  - test/command_map_test.rb
120
+ - test/commands_on_geo_test.rb
118
121
  - test/commands_on_hashes_test.rb
119
122
  - test/commands_on_hyper_log_log_test.rb
120
123
  - test/commands_on_lists_test.rb
@@ -218,6 +221,7 @@ test_files:
218
221
  - test/blocking_commands_test.rb
219
222
  - test/client_test.rb
220
223
  - test/command_map_test.rb
224
+ - test/commands_on_geo_test.rb
221
225
  - test/commands_on_hashes_test.rb
222
226
  - test/commands_on_hyper_log_log_test.rb
223
227
  - test/commands_on_lists_test.rb