Skip to content

Commit e0ebf92

Browse files
committed
Merge branch 'variadic-overloads' into 'master'
Add variadic overloads for several commands See merge request Mordil/swift-redi-stack!87
2 parents 8ce1dd8 + adcff65 commit e0ebf92

12 files changed

+222
-26
lines changed

Sources/RediStack/Commands/BasicCommands.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ extension RedisClient {
8585
return send(command: "DEL", with: args)
8686
.convertFromRESPValue()
8787
}
88+
89+
/// Removes the specified keys. A key is ignored if it does not exist.
90+
///
91+
/// [https://redis.io/commands/del](https://redis.io/commands/del)
92+
/// - Parameter keys: A list of keys to delete from the database.
93+
/// - Returns: The number of keys deleted from the database.
94+
@inlinable
95+
public func delete(_ keys: String...) -> EventLoopFuture<Int> {
96+
return self.delete(keys)
97+
}
8898

8999
/// Sets a timeout on key. After the timeout has expired, the key will automatically be deleted.
90100
/// - Note: A key with an associated timeout is often said to be "volatile" in Redis terminology.

Sources/RediStack/Commands/HashCommands.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ extension RedisClient {
5555
return send(command: "HDEL", with: args)
5656
.convertFromRESPValue()
5757
}
58+
59+
/// Removes the specified fields from a hash.
60+
///
61+
/// See [https://redis.io/commands/hdel](https://redis.io/commands/hdel)
62+
/// - Parameters:
63+
/// - fields: The list of field names that should be removed from the hash.
64+
/// - key: The key of the hash to delete from.
65+
/// - Returns: The number of fields that were deleted.
66+
@inlinable
67+
public func hdel(_ fields: String..., from key: String) -> EventLoopFuture<Int> {
68+
return self.hdel(fields, from: key)
69+
}
5870

5971
/// Checks if a hash contains the field specified.
6072
///
@@ -267,6 +279,18 @@ extension RedisClient {
267279
.convertFromRESPValue(to: [RESPValue].self)
268280
.map { return $0.map(String.init) }
269281
}
282+
283+
/// Gets the values of a hash for the fields specified.
284+
///
285+
/// See [https://redis.io/commands/hmget](https://redis.io/commands/hmget)
286+
/// - Parameters:
287+
/// - fields: A list of field names to get values for.
288+
/// - key: The key of the hash being accessed.
289+
/// - Returns: A list of values in the same order as the `fields` argument. Non-existent fields return `nil` values.
290+
@inlinable
291+
public func hmget(_ fields: String..., from key: String) -> EventLoopFuture<[String?]> {
292+
return self.hmget(fields, from: key)
293+
}
270294

271295
/// Returns all the fields and values stored in a hash.
272296
///

Sources/RediStack/Commands/ListCommands.swift

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,19 @@ extension RedisClient {
267267
return send(command: "LPUSH", with: args)
268268
.convertFromRESPValue()
269269
}
270+
271+
/// Pushes all of the provided elements into a list.
272+
/// - Note: This inserts the elements at the head of the list; for the tail see `rpush(_:into:)`.
273+
///
274+
/// See [https://redis.io/commands/lpush](https://redis.io/commands/lpush)
275+
/// - Parameters:
276+
/// - elements: The values to push into the list.
277+
/// - key: The key of the list.
278+
/// - Returns: The length of the list after adding the new elements.
279+
@inlinable
280+
public func lpush<Value: RESPValueConvertible>(_ elements: Value..., into key: String) -> EventLoopFuture<Int> {
281+
return self.lpush(elements, into: key)
282+
}
270283

271284
/// Pushes an element into a list, but only if the key exists and holds a list.
272285
/// - Note: This inserts the element at the head of the list, for the tail see `rpushx(_:into:)`.
@@ -318,6 +331,18 @@ extension RedisClient {
318331
return send(command: "RPUSH", with: args)
319332
.convertFromRESPValue()
320333
}
334+
335+
/// Pushes all of the provided elements into a list.
336+
/// - Note: This inserts the elements at the tail of the list; for the head see `lpush(_:into:)`.
337+
///
338+
/// See [https://redis.io/commands/rpush](https://redis.io/commands/rpush)
339+
/// - elements: The values to push into the list.
340+
/// - key: The key of the list.
341+
/// - Returns: The length of the list after adding the new elements.
342+
@inlinable
343+
public func rpush<Value: RESPValueConvertible>(_ elements: Value..., into key: String) -> EventLoopFuture<Int> {
344+
return self.rpush(elements, into: key)
345+
}
321346

322347
/// Pushes an element into a list, but only if the key exists and holds a list.
323348
/// - Note: This inserts the element at the tail of the list; for the head see `lpushx(_:into:)`.
@@ -378,12 +403,31 @@ extension RedisClient {
378403
///
379404
/// Otherwise, the key of the list the element was removed from and the popped element.
380405
@inlinable
381-
public func blpop(
382-
from keys: [String],
383-
timeout: Int = 0
384-
) -> EventLoopFuture<(String, RESPValue)?> {
406+
public func blpop(from keys: [String], timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
385407
return _bpop(command: "BLPOP", keys, timeout)
386408
}
409+
410+
/// Removes the first element of a list, blocking until an element is available.
411+
///
412+
/// - Important:
413+
/// This will block the connection from completing further commands until an element
414+
/// is available to pop from the group of lists.
415+
///
416+
/// It is **highly** recommended to set a reasonable `timeout`
417+
/// or to use the non-blocking `lpop` method where possible.
418+
///
419+
/// See [https://redis.io/commands/blpop](https://redis.io/commands/blpop)
420+
/// - Parameters:
421+
/// - keys: The keys of lists in Redis that should be popped from.
422+
/// - timeout: The time (in seconds) to wait. `0` means indefinitely.
423+
/// - Returns:
424+
/// If timeout was reached, `nil`.
425+
///
426+
/// Otherwise, the key of the list the element was removed from and the popped element.
427+
@inlinable
428+
public func blpop(from keys: String..., timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
429+
return self.blpop(from: keys, timeout: timeout)
430+
}
387431

388432
/// Removes the last element of a list, blocking until an element is available.
389433
///
@@ -422,13 +466,32 @@ extension RedisClient {
422466
///
423467
/// Otherwise, the key of the list the element was removed from and the popped element.
424468
@inlinable
425-
public func brpop(
426-
from keys: [String],
427-
timeout: Int = 0
428-
) -> EventLoopFuture<(String, RESPValue)?> {
469+
public func brpop(from keys: [String], timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
429470
return _bpop(command: "BRPOP", keys, timeout)
430471
}
431472

473+
/// Removes the last element of a list, blocking until an element is available.
474+
///
475+
/// - Important:
476+
/// This will block the connection from completing further commands until an element
477+
/// is available to pop from the group of lists.
478+
///
479+
/// It is **highly** recommended to set a reasonable `timeout`
480+
/// or to use the non-blocking `rpop` method where possible.
481+
///
482+
/// See [https://redis.io/commands/brpop](https://redis.io/commands/brpop)
483+
/// - Parameters:
484+
/// - keys: The keys of lists in Redis that should be popped from.
485+
/// - timeout: The time (in seconds) to wait. `0` means indefinitely.
486+
/// - Returns:
487+
/// If timeout was reached, `nil`.
488+
///
489+
/// Otherwise, the key of the list the element was removed from and the popped element.
490+
@inlinable
491+
public func brpop(from keys: String..., timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
492+
return self.brpop(from: keys, timeout: timeout)
493+
}
494+
432495
@usableFromInline
433496
func _bpop(
434497
command: String,

Sources/RediStack/Commands/SetCommands.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ extension RedisClient {
7979
return send(command: "SADD", with: args)
8080
.convertFromRESPValue()
8181
}
82+
83+
/// Adds elements to a set.
84+
///
85+
/// See [https://redis.io/commands/sadd](https://redis.io/commands/sadd)
86+
/// - Parameters:
87+
/// - elements: The values to add to the set.
88+
/// - key: The key of the set to insert into.
89+
/// - Returns: The number of elements that were added to the set.
90+
@inlinable
91+
public func sadd<Value: RESPValueConvertible>(_ elements: Value..., to key: String) -> EventLoopFuture<Int> {
92+
return self.sadd(elements, to: key)
93+
}
8294

8395
/// Removes elements from a set.
8496
///
@@ -97,6 +109,18 @@ extension RedisClient {
97109
return send(command: "SREM", with: args)
98110
.convertFromRESPValue()
99111
}
112+
113+
/// Removes elements from a set.
114+
///
115+
/// See [https://redis.io/commands/srem](https://redis.io/commands/srem)
116+
/// - Parameters:
117+
/// - elements: The values to remove from the set.
118+
/// - key: The key of the set to remove from.
119+
/// - Returns: The number of elements that were removed from the set.
120+
@inlinable
121+
public func srem<Value: RESPValueConvertible>(_ elements: Value..., from key: String) -> EventLoopFuture<Int> {
122+
return self.srem(elements, from: key)
123+
}
100124

101125
/// Randomly selects and removes one or more elements in a set.
102126
///
@@ -204,6 +228,16 @@ extension RedisClient {
204228
return send(command: "SDIFF", with: args)
205229
.convertFromRESPValue()
206230
}
231+
232+
/// Calculates the difference between two or more sets.
233+
///
234+
/// See [https://redis.io/commands/sdiff](https://redis.io/commands/sdiff)
235+
/// - Parameter keys: The source sets to calculate the difference of.
236+
/// - Returns: A list of elements resulting from the difference.
237+
@inlinable
238+
public func sdiff(of keys: String...) -> EventLoopFuture<[RESPValue]> {
239+
return self.sdiff(of: keys)
240+
}
207241

208242
/// Calculates the difference between two or more sets and stores the result.
209243
/// - Important: If the destination key already exists, it is overwritten.
@@ -241,6 +275,16 @@ extension RedisClient {
241275
return send(command: "SINTER", with: args)
242276
.convertFromRESPValue()
243277
}
278+
279+
/// Calculates the intersection of two or more sets.
280+
///
281+
/// See [https://redis.io/commands/sinter](https://redis.io/commands/sinter)
282+
/// - Parameter keys: The source sets to calculate the intersection of.
283+
/// - Returns: A list of elements resulting from the intersection.
284+
@inlinable
285+
public func sinter(of keys: String...) -> EventLoopFuture<[RESPValue]> {
286+
return self.sinter(of: keys)
287+
}
244288

245289
/// Calculates the intersetion of two or more sets and stores the result.
246290
/// - Important: If the destination key already exists, it is overwritten.
@@ -278,6 +322,16 @@ extension RedisClient {
278322
return send(command: "SUNION", with: args)
279323
.convertFromRESPValue()
280324
}
325+
326+
/// Calculates the union of two or more sets.
327+
///
328+
/// See [https://redis.io/commands/sunion](https://redis.io/commands/sunion)
329+
/// - Parameter keys: The source sets to calculate the union of.
330+
/// - Returns: A list of elements resulting from the union.
331+
@inlinable
332+
public func sunion(of keys: String...) -> EventLoopFuture<[RESPValue]> {
333+
return self.sunion(of: keys)
334+
}
281335

282336
/// Calculates the union of two or more sets and stores the result.
283337
/// - Important: If the destination key already exists, it is overwritten.

Sources/RediStack/Commands/SortedSetCommands.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,29 @@ extension RedisClient {
9393
return send(command: "ZADD", with: args)
9494
.convertFromRESPValue()
9595
}
96+
97+
/// Adds elements to a sorted set, assigning their score to the values provided.
98+
/// - Note: `INCR` is not supported by this library in `zadd`. Use the `zincrby(:element:in:)` method instead.
99+
///
100+
/// See [https://redis.io/commands/zadd](https://redis.io/commands/zadd)
101+
/// - Parameters:
102+
/// - elements: A list of elements and their score to add to the sorted set.
103+
/// - key: The key of the sorted set.
104+
/// - option: An option for modifying the behavior of the command.
105+
/// - returnChangedCount: `zadd` normally returns the number of new elements added to the set,
106+
/// but setting this to `true` will instead have the command return the number of elements changed.
107+
///
108+
/// "Changed" in this context are new elements added, and elements that had their score updated.
109+
/// - Returns: The number of elements added to the sorted set, unless `returnChangedCount` was set to `true`.
110+
@inlinable
111+
public func zadd<Value: RESPValueConvertible>(
112+
_ elements: (element: Value, score: Double)...,
113+
to key: String,
114+
option: RedisSortedSetAddOption? = nil,
115+
returnChangedCount: Bool = false
116+
) -> EventLoopFuture<Int> {
117+
return self.zadd(elements, to: key, option: option, returnChangedCount: returnChangedCount)
118+
}
96119

97120
/// Adds an element to a sorted set, assigning their score to the value provided.
98121
///
@@ -818,6 +841,18 @@ extension RedisClient {
818841
return send(command: "ZREM", with: args)
819842
.convertFromRESPValue()
820843
}
844+
845+
/// Removes the specified elements from a sorted set.
846+
///
847+
/// See [https://redis.io/commands/zrem](https://redis.io/commands/zrem)
848+
/// - Parameters:
849+
/// - elements: The values to remove from the sorted set.
850+
/// - key: The key of the sorted set.
851+
/// - Returns: The number of elements removed from the set.
852+
@inlinable
853+
public func zrem<Value: RESPValueConvertible>(_ elements: Value..., from key: String) -> EventLoopFuture<Int> {
854+
return self.zrem(elements, from: key)
855+
}
821856

822857
/// Removes elements from a sorted set whose lexiographical values are between the range specified.
823858
/// - Important: This assumes all elements in the sorted set have the same score. If not, the elements selected are unspecified.

Sources/RediStack/Commands/StringCommands.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ extension RedisClient {
5757
return send(command: "MGET", with: args)
5858
.convertFromRESPValue()
5959
}
60+
61+
/// Gets the values of all specified keys, using `.null` to represent non-existant values.
62+
///
63+
/// See [https://redis.io/commands/mget](https://redis.io/commands/mget)
64+
/// - Parameter keys: The list of keys to fetch the values from.
65+
/// - Returns: The values stored at the keys provided, matching the same order.
66+
@inlinable
67+
public func mget(_ keys: String...) -> EventLoopFuture<[RESPValue]> {
68+
return self.mget(keys)
69+
}
6070
}
6171

6272
// MARK: Set

Tests/RediStackIntegrationTests/Commands/BasicCommandsTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class BasicCommandsTests: RediStackIntegrationTestCase {
3333
let second = try connection.delete([keys[0]]).wait()
3434
XCTAssertEqual(second, 0)
3535

36-
let third = try connection.delete([keys[1], keys[2]]).wait()
36+
let third = try connection.delete(keys[1], keys[2]).wait()
3737
XCTAssertEqual(third, 2)
3838
}
3939

Tests/RediStackIntegrationTests/Commands/HashCommandsTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ final class HashCommandsTests: RediStackIntegrationTestCase {
4848

4949
func test_hmget() throws {
5050
_ = try connection.hmset(["first": "foo", "second": "bar"], in: #function).wait()
51-
let values = try connection.hmget(["first", "second", "fake"], from: #function).wait()
51+
let values = try connection.hmget("first", "second", "fake", from: #function).wait()
5252
XCTAssertEqual(values[0], "foo")
5353
XCTAssertEqual(values[1], "bar")
5454
XCTAssertNil(values[2])
@@ -63,7 +63,7 @@ final class HashCommandsTests: RediStackIntegrationTestCase {
6363

6464
func test_hdel() throws {
6565
_ = try connection.hmset(["first": "foo", "second": "bar"], in: #function).wait()
66-
let count = try connection.hdel(["first", "second", "fake"], from: #function).wait()
66+
let count = try connection.hdel("first", "second", "fake", from: #function).wait()
6767
XCTAssertEqual(count, 2)
6868
}
6969

Tests/RediStackIntegrationTests/Commands/ListCommandsTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ final class ListCommandsTests: RediStackIntegrationTestCase {
140140
let pop1 = try connection.blpop(from: "first").wait() ?? .null
141141
XCTAssertEqual(Int(fromRESP: pop1), 30)
142142

143-
let pop2 = try connection.blpop(from: ["fake", "first"]).wait()
143+
let pop2 = try connection.blpop(from: "fake", "first").wait()
144144
XCTAssertEqual(pop2?.0, "first")
145145

146146
let blockingConnection = try self.makeNewConnection()
@@ -158,7 +158,7 @@ final class ListCommandsTests: RediStackIntegrationTestCase {
158158
func test_lpush() throws {
159159
_ = try connection.rpush([10, 20, 30], into: #function).wait()
160160

161-
let size = try connection.lpush([100], into: #function).wait()
161+
let size = try connection.lpush(100, into: #function).wait()
162162
let element = try connection.lindex(0, from: #function).wait()
163163
XCTAssertEqual(size, 4)
164164
XCTAssertEqual(Int(fromRESP: element), 100)
@@ -199,7 +199,7 @@ final class ListCommandsTests: RediStackIntegrationTestCase {
199199
let pop1 = try connection.brpop(from: "first").wait() ?? .null
200200
XCTAssertEqual(Int(fromRESP: pop1), 10)
201201

202-
let pop2 = try connection.brpop(from: ["fake", "first"]).wait()
202+
let pop2 = try connection.brpop(from: "fake", "first").wait()
203203
XCTAssertEqual(pop2?.0, "first")
204204

205205
let blockingConnection = try self.makeNewConnection()
@@ -217,7 +217,7 @@ final class ListCommandsTests: RediStackIntegrationTestCase {
217217
func test_rpush() throws {
218218
_ = try connection.lpush([10, 20, 30], into: #function).wait()
219219

220-
let size = try connection.rpush([100], into: #function).wait()
220+
let size = try connection.rpush(100, into: #function).wait()
221221
let element = try connection.lindex(3, from: #function).wait()
222222
XCTAssertEqual(size, 4)
223223
XCTAssertEqual(Int(fromRESP: element), 100)

0 commit comments

Comments
 (0)