Skip to content

Commit

Permalink
Add sadd? and srem?, deprecate boolean return of sadd and srem
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Aug 22, 2022
1 parent 6b5dfe4 commit 47a6f93
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

* Introduce `sadd?` and `srem?` as boolean returning versions of `sadd` and `srem`.
* Deprecate `sadd` and `srem` returning a boolean when called with a single argument.
To enable the redis 5.0 behavior you can set `Redis.sadd_returns_boolean = true`.

# 4.7.1

* Gracefully handle OpenSSL 3.0 EOF Errors (`OpenSSL::SSL::SSLError: SSL_read: unexpected eof while reading`). See #1106
Expand Down
3 changes: 2 additions & 1 deletion lib/redis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
class Redis
BASE_PATH = __dir__
@exists_returns_integer = true
@sadd_returns_boolean = true

Deprecated = Class.new(StandardError)

class << self
attr_reader :exists_returns_integer
attr_accessor :silence_deprecations, :raise_deprecations
attr_accessor :silence_deprecations, :raise_deprecations, :sadd_returns_boolean

def exists_returns_integer=(value)
unless value
Expand Down
6 changes: 2 additions & 4 deletions lib/redis/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@ module Commands
# returning false.
Boolify = lambda { |value|
case value
when 1
true
when 0
false
when Integer
value > 0
else
value
end
Expand Down
48 changes: 32 additions & 16 deletions lib/redis/commands/sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ def scard(key)
# array of members is specified, holding the number of members that were
# successfully added
def sadd(key, member)
send_command([:sadd, key, member]) do |reply|
if member.is_a? Array
# Variadic: return integer
reply
else
# Single argument: return boolean
Boolify.call(reply)
end
block = if Redis.sadd_returns_boolean && !member.is_a?(Array)
::Redis.deprecate!(
"Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead." \
"(called from: #{caller(1, 1).first})"
)
Boolify
end
send_command([:sadd, key, member], &block)
end

# Add one or more members to a set.
#
# @param [String] key
# @param [String, Array<String>] member one member, or array of members
# @return [Boolean] Whether or not at least one member was added.
def sadd?(key, member)
send_command([:sadd, key, member], &Boolify)
end

# Remove one or more members from a set.
Expand All @@ -40,15 +48,23 @@ def sadd(key, member)
# array of members is specified, holding the number of members that were
# successfully removed
def srem(key, member)
send_command([:srem, key, member]) do |reply|
if member.is_a? Array
# Variadic: return integer
reply
else
# Single argument: return boolean
Boolify.call(reply)
end
block = if Redis.sadd_returns_boolean && !member.is_a?(Array)
::Redis.deprecate!(
"Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead." \
"(called from: #{caller(1, 1).first})"
)
Boolify
end
send_command([:srem, key, member], &block)
end

# Remove one or more members from a set.
#
# @param [String] key
# @param [String, Array<String>] member one member, or array of members
# @return [Boolean] `Boolean` Whether or not a member was removed.
def srem?(key, member)
send_command([:srem, key, member], &Boolify)
end

# Remove and return one or more random member from a set.
Expand Down
10 changes: 10 additions & 0 deletions lib/redis/distributed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -543,11 +543,21 @@ def sadd(key, member)
node_for(key).sadd(key, member)
end

# Add one or more members to a set.
def sadd?(key, member)
node_for(key).sadd?(key, member)
end

# Remove one or more members from a set.
def srem(key, member)
node_for(key).srem(key, member)
end

# Remove one or more members from a set.
def srem?(key, member)
node_for(key).srem?(key, member)
end

# Remove and return a random member from a set.
def spop(key, count = nil)
node_for(key).spop(key, count)
Expand Down
18 changes: 18 additions & 0 deletions test/lint/sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ def test_sadd
assert_equal ["s1", "s2"], r.smembers("foo").sort
end

def test_sadd?
assert_equal true, r.sadd?("foo", "s1")
assert_equal true, r.sadd?("foo", "s2")
assert_equal false, r.sadd?("foo", ["s1", "s2"])

assert_equal ["s1", "s2"], r.smembers("foo").sort
end

def test_variadic_sadd
target_version "2.3.9" do # 2.4-rc6
assert_equal 2, r.sadd("foo", ["s1", "s2"])
Expand All @@ -29,6 +37,16 @@ def test_srem
assert_equal ["s2"], r.smembers("foo")
end

def test_srem?
r.sadd("foo", "s1")
r.sadd("foo", "s2")

assert_equal true, r.srem?("foo", ["s1", "s5"])
assert_equal false, r.srem?("foo", ["s3", "s4"])

assert_equal ["s2"], r.smembers("foo")
end

def test_variadic_srem
target_version "2.3.9" do # 2.4-rc6
r.sadd("foo", "s1")
Expand Down

0 comments on commit 47a6f93

Please sign in to comment.