mirror of
https://github.com/swift-server/RediStack.git
synced 2026-06-02 07:37:33 +00:00
Add type-safe representation of Redis keys
Motivation: Inspired by Swift by Sundell's article on type-safe identifers, the goal of this commit is to have the compiler assist in preventing incorrect Redis key values from being used in API calls. See https://www.swiftbysundell.com/articles/type-safe-identifiers-in-swift/ for the inspiration. Modifications: - Add new `RedisKey` struct that wraps around a single `String` value that conforms to several expected protocols (Hashable, Comparable, Codable, etc.) - Change all command APIs to require `RedisKey` rather than plain strings Result: When encountering an API requiring a RedisKey, it should be much more apparant at the use site what form a value should take.
This commit is contained in:
@@ -90,7 +90,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: A list of keys to delete from the database.
|
||||
/// - Returns: The number of keys deleted from the database.
|
||||
@inlinable
|
||||
public func delete(_ keys: [String]) -> EventLoopFuture<Int> {
|
||||
public func delete(_ keys: [RedisKey]) -> EventLoopFuture<Int> {
|
||||
guard keys.count > 0 else { return self.eventLoop.makeSucceededFuture(0) }
|
||||
|
||||
let args = keys.map(RESPValue.init)
|
||||
@@ -104,7 +104,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: A list of keys to delete from the database.
|
||||
/// - Returns: The number of keys deleted from the database.
|
||||
@inlinable
|
||||
public func delete(_ keys: String...) -> EventLoopFuture<Int> {
|
||||
public func delete(_ keys: RedisKey...) -> EventLoopFuture<Int> {
|
||||
return self.delete(keys)
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ extension RedisClient {
|
||||
/// - timeout: The time from now the key will expire at.
|
||||
/// - Returns: `true` if the expiration was set.
|
||||
@inlinable
|
||||
public func expire(_ key: String, after timeout: TimeAmount) -> EventLoopFuture<Bool> {
|
||||
public func expire(_ key: RedisKey, after timeout: TimeAmount) -> EventLoopFuture<Bool> {
|
||||
let amount = timeout.nanoseconds / 1_000_000_000
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -153,7 +153,7 @@ extension RedisClient {
|
||||
internal func _scan<T>(
|
||||
command: String,
|
||||
resultType: T.Type = T.self,
|
||||
_ key: String?,
|
||||
_ key: RedisKey?,
|
||||
_ pos: Int,
|
||||
_ count: Int?,
|
||||
_ match: String?
|
||||
|
||||
@@ -46,7 +46,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash to delete from.
|
||||
/// - Returns: The number of fields that were deleted.
|
||||
@inlinable
|
||||
public func hdel(_ fields: [String], from key: String) -> EventLoopFuture<Int> {
|
||||
public func hdel(_ fields: [String], from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
guard fields.count > 0 else { return self.eventLoop.makeSucceededFuture(0) }
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -64,7 +64,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash to delete from.
|
||||
/// - Returns: The number of fields that were deleted.
|
||||
@inlinable
|
||||
public func hdel(_ fields: String..., from key: String) -> EventLoopFuture<Int> {
|
||||
public func hdel(_ fields: String..., from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.hdel(fields, from: key)
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash to look within.
|
||||
/// - Returns: `true` if the hash contains the field, `false` if either the key or field do not exist.
|
||||
@inlinable
|
||||
public func hexists(_ field: String, in key: String) -> EventLoopFuture<Bool> {
|
||||
public func hexists(_ field: String, in key: RedisKey) -> EventLoopFuture<Bool> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: field)
|
||||
@@ -92,7 +92,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the hash to get field count of.
|
||||
/// - Returns: The number of fields in the hash, or `0` if the key doesn't exist.
|
||||
@inlinable
|
||||
public func hlen(of key: String) -> EventLoopFuture<Int> {
|
||||
public func hlen(of key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "HLEN", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -106,7 +106,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash.
|
||||
/// - Returns: The string length of the hash field's value, or `0` if the field or hash do not exist.
|
||||
@inlinable
|
||||
public func hstrlen(of field: String, in key: String) -> EventLoopFuture<Int> {
|
||||
public func hstrlen(of field: String, in key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: field)
|
||||
@@ -121,7 +121,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the hash.
|
||||
/// - Returns: A list of field names stored within the hash.
|
||||
@inlinable
|
||||
public func hkeys(in key: String) -> EventLoopFuture<[String]> {
|
||||
public func hkeys(in key: RedisKey) -> EventLoopFuture<[String]> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "HKEYS", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -133,7 +133,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the hash.
|
||||
/// - Returns: A list of all values stored in a hash.
|
||||
@inlinable
|
||||
public func hvals(in key: String) -> EventLoopFuture<[RESPValue]> {
|
||||
public func hvals(in key: RedisKey) -> EventLoopFuture<[RESPValue]> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "HVALS", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -150,7 +150,7 @@ extension RedisClient {
|
||||
/// - Returns: A cursor position for additional invocations with a limited collection of found fields and their values.
|
||||
@inlinable
|
||||
public func hscan(
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
startingFrom position: Int = 0,
|
||||
count: Int? = nil,
|
||||
matching match: String? = nil
|
||||
@@ -179,7 +179,7 @@ extension RedisClient {
|
||||
public func hset<Value: RESPValueConvertible>(
|
||||
_ field: String,
|
||||
to value: Value,
|
||||
in key: String
|
||||
in key: RedisKey
|
||||
) -> EventLoopFuture<Bool> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -204,7 +204,7 @@ extension RedisClient {
|
||||
public func hsetnx<Value: RESPValueConvertible>(
|
||||
_ field: String,
|
||||
to value: Value,
|
||||
in key: String
|
||||
in key: RedisKey
|
||||
) -> EventLoopFuture<Bool> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -226,7 +226,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func hmset<Value: RESPValueConvertible>(
|
||||
_ fields: [String: Value],
|
||||
in key: String
|
||||
in key: RedisKey
|
||||
) -> EventLoopFuture<Void> {
|
||||
assert(fields.count > 0, "At least 1 key-value pair should be specified")
|
||||
|
||||
@@ -252,7 +252,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash being accessed.
|
||||
/// - Returns: The value of the hash field, or `nil` if either the key or field does not exist.
|
||||
@inlinable
|
||||
public func hget(_ field: String, from key: String) -> EventLoopFuture<String?> {
|
||||
public func hget(_ field: String, from key: RedisKey) -> EventLoopFuture<String?> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: field)
|
||||
@@ -269,7 +269,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash being accessed.
|
||||
/// - Returns: A list of values in the same order as the `fields` argument. Non-existent fields return `nil` values.
|
||||
@inlinable
|
||||
public func hmget(_ fields: [String], from key: String) -> EventLoopFuture<[String?]> {
|
||||
public func hmget(_ fields: [String], from key: RedisKey) -> EventLoopFuture<[String?]> {
|
||||
guard fields.count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -288,7 +288,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash being accessed.
|
||||
/// - Returns: A list of values in the same order as the `fields` argument. Non-existent fields return `nil` values.
|
||||
@inlinable
|
||||
public func hmget(_ fields: String..., from key: String) -> EventLoopFuture<[String?]> {
|
||||
public func hmget(_ fields: String..., from key: RedisKey) -> EventLoopFuture<[String?]> {
|
||||
return self.hmget(fields, from: key)
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the hash to pull from.
|
||||
/// - Returns: A key-value pair list of fields and their values.
|
||||
@inlinable
|
||||
public func hgetall(from key: String) -> EventLoopFuture<[String: String]> {
|
||||
public func hgetall(from key: RedisKey) -> EventLoopFuture<[String: String]> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "HGETALL", with: args)
|
||||
.convertFromRESPValue(to: [String].self)
|
||||
@@ -318,7 +318,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash the field is stored in.
|
||||
/// - Returns: The new value of the hash field.
|
||||
@inlinable
|
||||
public func hincrby(_ amount: Int, field: String, in key: String) -> EventLoopFuture<Int> {
|
||||
public func hincrby(_ amount: Int, field: String, in key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return _hincr(command: "HINCRBY", amount, field, key)
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ extension RedisClient {
|
||||
/// - key: The key of the hash the field is stored in.
|
||||
/// - Returns: The new value of the hash field.
|
||||
@inlinable
|
||||
public func hincrbyfloat<Value>(_ amount: Value, field: String, in key: String) -> EventLoopFuture<Value>
|
||||
public func hincrbyfloat<Value>(_ amount: Value, field: String, in key: RedisKey) -> EventLoopFuture<Value>
|
||||
where
|
||||
Value: BinaryFloatingPoint,
|
||||
Value: RESPValueConvertible
|
||||
@@ -344,7 +344,7 @@ extension RedisClient {
|
||||
command: String,
|
||||
_ amount: Value,
|
||||
_ field: String,
|
||||
_ key: String
|
||||
_ key: RedisKey
|
||||
) -> EventLoopFuture<Value> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
|
||||
@@ -23,7 +23,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the list.
|
||||
/// - Returns: The number of elements in the list.
|
||||
@inlinable
|
||||
public func llen(of key: String) -> EventLoopFuture<Int> {
|
||||
public func llen(of key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "LLEN", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -37,7 +37,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The element stored at index, or `.null` if out of bounds.
|
||||
@inlinable
|
||||
public func lindex(_ index: Int, from key: String) -> EventLoopFuture<RESPValue> {
|
||||
public func lindex(_ index: Int, from key: RedisKey) -> EventLoopFuture<RESPValue> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: index)
|
||||
@@ -57,7 +57,7 @@ extension RedisClient {
|
||||
public func lset<Value: RESPValueConvertible>(
|
||||
index: Int,
|
||||
to value: Value,
|
||||
in key: String
|
||||
in key: RedisKey
|
||||
) -> EventLoopFuture<Void> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -79,7 +79,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func lrem<Value: RESPValueConvertible>(
|
||||
_ value: Value,
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
count: Int = 0
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
@@ -100,7 +100,7 @@ extension RedisClient {
|
||||
/// - stop: The index of the last element to keep.
|
||||
/// - Returns: An `EventLoopFuture` that resolves when the operation has succeeded, or fails with a `RedisError`.
|
||||
@inlinable
|
||||
public func ltrim(_ key: String, before start: Int, after stop: Int) -> EventLoopFuture<Void> {
|
||||
public func ltrim(_ key: RedisKey, before start: Int, after stop: Int) -> EventLoopFuture<Void> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: start),
|
||||
@@ -120,7 +120,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func lrange(
|
||||
within range: (startIndex: Int, endIndex: Int),
|
||||
from key: String
|
||||
from key: RedisKey
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -139,7 +139,7 @@ extension RedisClient {
|
||||
/// - dest: The key of the list to push to.
|
||||
/// - Returns: The element that was moved.
|
||||
@inlinable
|
||||
public func rpoplpush(from source: String, to dest: String) -> EventLoopFuture<RESPValue> {
|
||||
public func rpoplpush(from source: RedisKey, to dest: RedisKey) -> EventLoopFuture<RESPValue> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: source),
|
||||
.init(bulk: dest)
|
||||
@@ -166,8 +166,8 @@ extension RedisClient {
|
||||
/// or `nil` if the timeout was reached.
|
||||
@inlinable
|
||||
public func brpoplpush(
|
||||
from source: String,
|
||||
to dest: String,
|
||||
from source: RedisKey,
|
||||
to dest: RedisKey,
|
||||
timeout: Int = 0
|
||||
) -> EventLoopFuture<RESPValue?> {
|
||||
let args: [RESPValue] = [
|
||||
@@ -194,7 +194,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func linsert<Value: RESPValueConvertible>(
|
||||
_ element: Value,
|
||||
into key: String,
|
||||
into key: RedisKey,
|
||||
before pivot: Value
|
||||
) -> EventLoopFuture<Int> {
|
||||
return _linsert(pivotKeyword: "BEFORE", element, key, pivot)
|
||||
@@ -211,7 +211,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func linsert<Value: RESPValueConvertible>(
|
||||
_ element: Value,
|
||||
into key: String,
|
||||
into key: RedisKey,
|
||||
after pivot: Value
|
||||
) -> EventLoopFuture<Int> {
|
||||
return _linsert(pivotKeyword: "AFTER", element, key, pivot)
|
||||
@@ -221,7 +221,7 @@ extension RedisClient {
|
||||
func _linsert<Value: RESPValueConvertible>(
|
||||
pivotKeyword: String,
|
||||
_ element: Value,
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
_ pivot: Value
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
@@ -244,7 +244,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the list to pop from.
|
||||
/// - Returns: The element that was popped from the list, or `.null`.
|
||||
@inlinable
|
||||
public func lpop(from key: String) -> EventLoopFuture<RESPValue> {
|
||||
public func lpop(from key: RedisKey) -> EventLoopFuture<RESPValue> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "LPOP", with: args)
|
||||
}
|
||||
@@ -258,7 +258,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func lpush<Value: RESPValueConvertible>(_ elements: [Value], into key: String) -> EventLoopFuture<Int> {
|
||||
public func lpush<Value: RESPValueConvertible>(_ elements: [Value], into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
assert(elements.count > 0, "At least 1 element should be provided.")
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -277,7 +277,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func lpush<Value: RESPValueConvertible>(_ elements: Value..., into key: String) -> EventLoopFuture<Int> {
|
||||
public func lpush<Value: RESPValueConvertible>(_ elements: Value..., into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.lpush(elements, into: key)
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func lpushx<Value: RESPValueConvertible>(_ element: Value, into key: String) -> EventLoopFuture<Int> {
|
||||
public func lpushx<Value: RESPValueConvertible>(_ element: Value, into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -309,7 +309,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the list to pop from.
|
||||
/// - Returns: The element that was popped from the list, else `.null`.
|
||||
@inlinable
|
||||
public func rpop(from key: String) -> EventLoopFuture<RESPValue> {
|
||||
public func rpop(from key: RedisKey) -> EventLoopFuture<RESPValue> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "RPOP", with: args)
|
||||
}
|
||||
@@ -322,7 +322,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func rpush<Value: RESPValueConvertible>(_ elements: [Value], into key: String) -> EventLoopFuture<Int> {
|
||||
public func rpush<Value: RESPValueConvertible>(_ elements: [Value], into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
assert(elements.count > 0, "At least 1 element should be provided.")
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -340,7 +340,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func rpush<Value: RESPValueConvertible>(_ elements: Value..., into key: String) -> EventLoopFuture<Int> {
|
||||
public func rpush<Value: RESPValueConvertible>(_ elements: Value..., into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.rpush(elements, into: key)
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list.
|
||||
/// - Returns: The length of the list after adding the new elements.
|
||||
@inlinable
|
||||
public func rpushx<Value: RESPValueConvertible>(_ element: Value, into key: String) -> EventLoopFuture<Int> {
|
||||
public func rpushx<Value: RESPValueConvertible>(_ element: Value, into key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -380,7 +380,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list to pop from.
|
||||
/// - Returns: The element that was popped from the list, or `nil` if the timout was reached.
|
||||
@inlinable
|
||||
public func blpop(from key: String, timeout: Int = 0) -> EventLoopFuture<RESPValue?> {
|
||||
public func blpop(from key: RedisKey, timeout: Int = 0) -> EventLoopFuture<RESPValue?> {
|
||||
return blpop(from: [key], timeout: timeout)
|
||||
.map { $0?.1 }
|
||||
}
|
||||
@@ -403,7 +403,7 @@ extension RedisClient {
|
||||
///
|
||||
/// Otherwise, the key of the list the element was removed from and the popped element.
|
||||
@inlinable
|
||||
public func blpop(from keys: [String], timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
|
||||
public func blpop(from keys: [RedisKey], timeout: Int = 0) -> EventLoopFuture<(RedisKey, RESPValue)?> {
|
||||
return _bpop(command: "BLPOP", keys, timeout)
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ extension RedisClient {
|
||||
///
|
||||
/// Otherwise, the key of the list the element was removed from and the popped element.
|
||||
@inlinable
|
||||
public func blpop(from keys: String..., timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
|
||||
public func blpop(from keys: RedisKey..., timeout: Int = 0) -> EventLoopFuture<(RedisKey, RESPValue)?> {
|
||||
return self.blpop(from: keys, timeout: timeout)
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ extension RedisClient {
|
||||
/// - key: The key of the list to pop from.
|
||||
/// - Returns: The element that was popped from the list, or `nil` if the timout was reached.
|
||||
@inlinable
|
||||
public func brpop(from key: String, timeout: Int = 0) -> EventLoopFuture<RESPValue?> {
|
||||
public func brpop(from key: RedisKey, timeout: Int = 0) -> EventLoopFuture<RESPValue?> {
|
||||
return brpop(from: [key], timeout: timeout)
|
||||
.map { $0?.1 }
|
||||
}
|
||||
@@ -466,7 +466,7 @@ extension RedisClient {
|
||||
///
|
||||
/// Otherwise, the key of the list the element was removed from and the popped element.
|
||||
@inlinable
|
||||
public func brpop(from keys: [String], timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
|
||||
public func brpop(from keys: [RedisKey], timeout: Int = 0) -> EventLoopFuture<(RedisKey, RESPValue)?> {
|
||||
return _bpop(command: "BRPOP", keys, timeout)
|
||||
}
|
||||
|
||||
@@ -488,16 +488,16 @@ extension RedisClient {
|
||||
///
|
||||
/// Otherwise, the key of the list the element was removed from and the popped element.
|
||||
@inlinable
|
||||
public func brpop(from keys: String..., timeout: Int = 0) -> EventLoopFuture<(String, RESPValue)?> {
|
||||
public func brpop(from keys: RedisKey..., timeout: Int = 0) -> EventLoopFuture<(RedisKey, RESPValue)?> {
|
||||
return self.brpop(from: keys, timeout: timeout)
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
func _bpop(
|
||||
command: String,
|
||||
_ keys: [String],
|
||||
_ keys: [RedisKey],
|
||||
_ timeout: Int
|
||||
) -> EventLoopFuture<(String, RESPValue)?> {
|
||||
) -> EventLoopFuture<(RedisKey, RESPValue)?> {
|
||||
var args = keys.map(RESPValue.init)
|
||||
args.append(.init(bulk: timeout))
|
||||
|
||||
@@ -511,7 +511,7 @@ extension RedisClient {
|
||||
guard let key = response[0].string else {
|
||||
throw RedisClientError.assertionFailure(message: "Unexpected structure in response: \(response)")
|
||||
}
|
||||
return (key, response[1])
|
||||
return (.init(key), response[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the set.
|
||||
/// - Returns: A list of elements found within the set.
|
||||
@inlinable
|
||||
public func smembers(of key: String) -> EventLoopFuture<[RESPValue]> {
|
||||
public func smembers(of key: RedisKey) -> EventLoopFuture<[RESPValue]> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "SMEMBERS", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -40,7 +40,7 @@ extension RedisClient {
|
||||
/// - key: The key of the set to look in.
|
||||
/// - Returns: `true` if the element is in the set.
|
||||
@inlinable
|
||||
public func sismember<Value: RESPValueConvertible>(_ element: Value, of key: String) -> EventLoopFuture<Bool> {
|
||||
public func sismember<Value: RESPValueConvertible>(_ element: Value, of key: RedisKey) -> EventLoopFuture<Bool> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -56,7 +56,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the set.
|
||||
/// - Returns: The total count of elements in the set.
|
||||
@inlinable
|
||||
public func scard(of key: String) -> EventLoopFuture<Int> {
|
||||
public func scard(of key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "SCARD", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -70,7 +70,7 @@ extension RedisClient {
|
||||
/// - key: The key of the set to insert into.
|
||||
/// - Returns: The number of elements that were added to the set.
|
||||
@inlinable
|
||||
public func sadd<Value: RESPValueConvertible>(_ elements: [Value], to key: String) -> EventLoopFuture<Int> {
|
||||
public func sadd<Value: RESPValueConvertible>(_ elements: [Value], to key: RedisKey) -> EventLoopFuture<Int> {
|
||||
guard elements.count > 0 else { return self.eventLoop.makeSucceededFuture(0) }
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -88,7 +88,7 @@ extension RedisClient {
|
||||
/// - key: The key of the set to insert into.
|
||||
/// - Returns: The number of elements that were added to the set.
|
||||
@inlinable
|
||||
public func sadd<Value: RESPValueConvertible>(_ elements: Value..., to key: String) -> EventLoopFuture<Int> {
|
||||
public func sadd<Value: RESPValueConvertible>(_ elements: Value..., to key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.sadd(elements, to: key)
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ extension RedisClient {
|
||||
/// - key: The key of the set to remove from.
|
||||
/// - Returns: The number of elements that were removed from the set.
|
||||
@inlinable
|
||||
public func srem<Value: RESPValueConvertible>(_ elements: [Value], from key: String) -> EventLoopFuture<Int> {
|
||||
public func srem<Value: RESPValueConvertible>(_ elements: [Value], from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
guard elements.count > 0 else { return self.eventLoop.makeSucceededFuture(0) }
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -118,7 +118,7 @@ extension RedisClient {
|
||||
/// - key: The key of the set to remove from.
|
||||
/// - Returns: The number of elements that were removed from the set.
|
||||
@inlinable
|
||||
public func srem<Value: RESPValueConvertible>(_ elements: Value..., from key: String) -> EventLoopFuture<Int> {
|
||||
public func srem<Value: RESPValueConvertible>(_ elements: Value..., from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.srem(elements, from: key)
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ extension RedisClient {
|
||||
/// - count: The max number of elements to pop from the set.
|
||||
/// - Returns: The element that was popped from the set.
|
||||
@inlinable
|
||||
public func spop(from key: String, max count: Int = 1) -> EventLoopFuture<[RESPValue]> {
|
||||
public func spop(from key: RedisKey, max count: Int = 1) -> EventLoopFuture<[RESPValue]> {
|
||||
assert(count >= 0, "A negative max count is nonsense.")
|
||||
|
||||
guard count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
@@ -155,7 +155,7 @@ extension RedisClient {
|
||||
/// - count: The max number of elements to select from the set.
|
||||
/// - Returns: The elements randomly selected from the set.
|
||||
@inlinable
|
||||
public func srandmember(from key: String, max count: Int = 1) -> EventLoopFuture<[RESPValue]> {
|
||||
public func srandmember(from key: RedisKey, max count: Int = 1) -> EventLoopFuture<[RESPValue]> {
|
||||
guard count != 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
let args: [RESPValue] = [
|
||||
@@ -177,8 +177,8 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func smove<Value: RESPValueConvertible>(
|
||||
_ element: Value,
|
||||
from sourceKey: String,
|
||||
to destKey: String
|
||||
from sourceKey: RedisKey,
|
||||
to destKey: RedisKey
|
||||
) -> EventLoopFuture<Bool> {
|
||||
guard sourceKey != destKey else { return self.eventLoop.makeSucceededFuture(true) }
|
||||
|
||||
@@ -203,7 +203,7 @@ extension RedisClient {
|
||||
/// - Returns: A cursor position for additional invocations with a limited collection of elements found in the set.
|
||||
@inlinable
|
||||
public func sscan(
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
startingFrom position: Int = 0,
|
||||
count: Int? = nil,
|
||||
matching match: String? = nil
|
||||
@@ -221,7 +221,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the difference of.
|
||||
/// - Returns: A list of elements resulting from the difference.
|
||||
@inlinable
|
||||
public func sdiff(of keys: [String]) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sdiff(of keys: [RedisKey]) -> EventLoopFuture<[RESPValue]> {
|
||||
guard keys.count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
let args = keys.map(RESPValue.init)
|
||||
@@ -235,7 +235,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the difference of.
|
||||
/// - Returns: A list of elements resulting from the difference.
|
||||
@inlinable
|
||||
public func sdiff(of keys: String...) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sdiff(of keys: RedisKey...) -> EventLoopFuture<[RESPValue]> {
|
||||
return self.sdiff(of: keys)
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ extension RedisClient {
|
||||
/// - sources: The list of source sets to calculate the difference of.
|
||||
/// - Returns: The number of elements in the difference result.
|
||||
@inlinable
|
||||
public func sdiffstore(as destination: String, sources keys: [String]) -> EventLoopFuture<Int> {
|
||||
public func sdiffstore(as destination: RedisKey, sources keys: [RedisKey]) -> EventLoopFuture<Int> {
|
||||
assert(keys.count > 0, "At least 1 key should be provided.")
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: destination)]
|
||||
@@ -268,7 +268,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the intersection of.
|
||||
/// - Returns: A list of elements resulting from the intersection.
|
||||
@inlinable
|
||||
public func sinter(of keys: [String]) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sinter(of keys: [RedisKey]) -> EventLoopFuture<[RESPValue]> {
|
||||
guard keys.count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
let args = keys.map(RESPValue.init)
|
||||
@@ -282,7 +282,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the intersection of.
|
||||
/// - Returns: A list of elements resulting from the intersection.
|
||||
@inlinable
|
||||
public func sinter(of keys: String...) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sinter(of keys: RedisKey...) -> EventLoopFuture<[RESPValue]> {
|
||||
return self.sinter(of: keys)
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ extension RedisClient {
|
||||
/// - sources: A list of source sets to calculate the intersection of.
|
||||
/// - Returns: The number of elements in the intersection result.
|
||||
@inlinable
|
||||
public func sinterstore(as destination: String, sources keys: [String]) -> EventLoopFuture<Int> {
|
||||
public func sinterstore(as destination: RedisKey, sources keys: [RedisKey]) -> EventLoopFuture<Int> {
|
||||
assert(keys.count > 0, "At least 1 key should be provided.")
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: destination)]
|
||||
@@ -315,7 +315,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the union of.
|
||||
/// - Returns: A list of elements resulting from the union.
|
||||
@inlinable
|
||||
public func sunion(of keys: [String]) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sunion(of keys: [RedisKey]) -> EventLoopFuture<[RESPValue]> {
|
||||
guard keys.count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
let args = keys.map(RESPValue.init)
|
||||
@@ -329,7 +329,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The source sets to calculate the union of.
|
||||
/// - Returns: A list of elements resulting from the union.
|
||||
@inlinable
|
||||
public func sunion(of keys: String...) -> EventLoopFuture<[RESPValue]> {
|
||||
public func sunion(of keys: RedisKey...) -> EventLoopFuture<[RESPValue]> {
|
||||
return self.sunion(of: keys)
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ extension RedisClient {
|
||||
/// - sources: A list of source sets to calculate the union of.
|
||||
/// - Returns: The number of elements in the union result.
|
||||
@inlinable
|
||||
public func sunionstore(as destination: String, sources keys: [String]) -> EventLoopFuture<Int> {
|
||||
public func sunionstore(as destination: RedisKey, sources keys: [RedisKey]) -> EventLoopFuture<Int> {
|
||||
assert(keys.count > 0, "At least 1 key should be provided.")
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: destination)]
|
||||
|
||||
@@ -73,7 +73,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zadd<Value: RESPValueConvertible>(
|
||||
_ elements: [(element: Value, score: Double)],
|
||||
to key: String,
|
||||
to key: RedisKey,
|
||||
option: RedisSortedSetAddOption? = nil,
|
||||
returnChangedCount: Bool = false
|
||||
) -> EventLoopFuture<Int> {
|
||||
@@ -110,7 +110,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zadd<Value: RESPValueConvertible>(
|
||||
_ elements: (element: Value, score: Double)...,
|
||||
to key: String,
|
||||
to key: RedisKey,
|
||||
option: RedisSortedSetAddOption? = nil,
|
||||
returnChangedCount: Bool = false
|
||||
) -> EventLoopFuture<Int> {
|
||||
@@ -132,7 +132,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zadd<Value: RESPValueConvertible>(
|
||||
_ element: (element: Value, score: Double),
|
||||
to key: String,
|
||||
to key: RedisKey,
|
||||
option: RedisSortedSetAddOption? = nil,
|
||||
returnChangedCount: Bool = false
|
||||
) -> EventLoopFuture<Bool> {
|
||||
@@ -146,7 +146,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key of the sorted set.
|
||||
/// - Returns: The number of elements in the sorted set.
|
||||
@inlinable
|
||||
public func zcard(of key: String) -> EventLoopFuture<Int> {
|
||||
public func zcard(of key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "ZCARD", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -160,7 +160,7 @@ extension RedisClient {
|
||||
/// - key: The key of the sorted set.
|
||||
/// - Returns: The score of the element provided, or `nil` if the element is not found in the set or the set does not exist.
|
||||
@inlinable
|
||||
public func zscore<Value: RESPValueConvertible>(of element: Value, in key: String) -> EventLoopFuture<Double?> {
|
||||
public func zscore<Value: RESPValueConvertible>(of element: Value, in key: RedisKey) -> EventLoopFuture<Double?> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -180,7 +180,7 @@ extension RedisClient {
|
||||
/// - Returns: A cursor position for additional invocations with a limited collection of elements found in the sorted set with their scores.
|
||||
@inlinable
|
||||
public func zscan(
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
startingFrom position: Int = 0,
|
||||
count: Int? = nil,
|
||||
matching match: String? = nil
|
||||
@@ -206,7 +206,7 @@ extension RedisClient {
|
||||
/// - key: The key of the sorted set to search.
|
||||
/// - Returns: The index of the element, or `nil` if the key was not found.
|
||||
@inlinable
|
||||
public func zrank<Value: RESPValueConvertible>(of element: Value, in key: String) -> EventLoopFuture<Int?> {
|
||||
public func zrank<Value: RESPValueConvertible>(of element: Value, in key: RedisKey) -> EventLoopFuture<Int?> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -225,7 +225,7 @@ extension RedisClient {
|
||||
/// - key: The key of the sorted set to search.
|
||||
/// - Returns: The index of the element, or `nil` if the key was not found.
|
||||
@inlinable
|
||||
public func zrevrank<Value: RESPValueConvertible>(of element: Value, in key: String) -> EventLoopFuture<Int?> {
|
||||
public func zrevrank<Value: RESPValueConvertible>(of element: Value, in key: RedisKey) -> EventLoopFuture<Int?> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
element.convertedToRESPValue()
|
||||
@@ -247,7 +247,7 @@ extension RedisClient {
|
||||
/// - Returns: The number of elements in the sorted set that fit within the score range.
|
||||
@inlinable
|
||||
public func zcount(
|
||||
of key: String,
|
||||
of key: RedisKey,
|
||||
within range: (min: String, max: String)
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
@@ -269,7 +269,7 @@ extension RedisClient {
|
||||
/// - Returns: The number of elements in the sorted set that fit within the value range.
|
||||
@inlinable
|
||||
public func zlexcount(
|
||||
of key: String,
|
||||
of key: RedisKey,
|
||||
within range: (min: String, max: String)
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
@@ -293,7 +293,7 @@ extension RedisClient {
|
||||
/// - count: The max number of elements to pop from the set.
|
||||
/// - Returns: A list of elements popped from the sorted set with their associated score.
|
||||
@inlinable
|
||||
public func zpopmin(from key: String, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> {
|
||||
public func zpopmin(from key: RedisKey, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> {
|
||||
return _zpop(command: "ZPOPMIN", count, key)
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key identifying the sorted set in Redis.
|
||||
/// - Returns: The element and its associated score that was popped from the sorted set, or `nil` if set was empty.
|
||||
@inlinable
|
||||
public func zpopmin(from key: String) -> EventLoopFuture<(RESPValue, Double)?> {
|
||||
public func zpopmin(from key: RedisKey) -> EventLoopFuture<(RESPValue, Double)?> {
|
||||
return _zpop(command: "ZPOPMIN", nil, key)
|
||||
.map { return $0.count > 0 ? $0[0] : nil }
|
||||
}
|
||||
@@ -316,7 +316,7 @@ extension RedisClient {
|
||||
/// - count: The max number of elements to pop from the set.
|
||||
/// - Returns: A list of elements popped from the sorted set with their associated score.
|
||||
@inlinable
|
||||
public func zpopmax(from key: String, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> {
|
||||
public func zpopmax(from key: RedisKey, max count: Int) -> EventLoopFuture<[(RESPValue, Double)]> {
|
||||
return _zpop(command: "ZPOPMAX", count, key)
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key identifying the sorted set in Redis.
|
||||
/// - Returns: The element and its associated score that was popped from the sorted set, or `nil` if set was empty.
|
||||
@inlinable
|
||||
public func zpopmax(from key: String) -> EventLoopFuture<(RESPValue, Double)?> {
|
||||
public func zpopmax(from key: RedisKey) -> EventLoopFuture<(RESPValue, Double)?> {
|
||||
return _zpop(command: "ZPOPMAX", nil, key)
|
||||
.map { return $0.count > 0 ? $0[0] : nil }
|
||||
}
|
||||
@@ -335,7 +335,7 @@ extension RedisClient {
|
||||
func _zpop(
|
||||
command: String,
|
||||
_ count: Int?,
|
||||
_ key: String
|
||||
_ key: RedisKey
|
||||
) -> EventLoopFuture<[(RESPValue, Double)]> {
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
|
||||
@@ -373,7 +373,7 @@ extension RedisClient {
|
||||
/// or `nil` if the timeout was reached.
|
||||
@inlinable
|
||||
public func bzpopmin(
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
timeout: Int = 0
|
||||
) -> EventLoopFuture<(Double, RESPValue)?> {
|
||||
return bzpopmin(from: [key], timeout: timeout)
|
||||
@@ -404,7 +404,7 @@ extension RedisClient {
|
||||
/// and its associated score is returned.
|
||||
@inlinable
|
||||
public func bzpopmin(
|
||||
from keys: [String],
|
||||
from keys: [RedisKey],
|
||||
timeout: Int = 0
|
||||
) -> EventLoopFuture<(String, Double, RESPValue)?> {
|
||||
return self._bzpop(command: "BZPOPMIN", keys, timeout)
|
||||
@@ -429,7 +429,7 @@ extension RedisClient {
|
||||
/// or `nil` if the timeout was reached.
|
||||
@inlinable
|
||||
public func bzpopmax(
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
timeout: Int = 0
|
||||
) -> EventLoopFuture<(Double, RESPValue)?> {
|
||||
return self.bzpopmax(from: [key], timeout: timeout)
|
||||
@@ -460,7 +460,7 @@ extension RedisClient {
|
||||
/// and its associated score is returned.
|
||||
@inlinable
|
||||
public func bzpopmax(
|
||||
from keys: [String],
|
||||
from keys: [RedisKey],
|
||||
timeout: Int = 0
|
||||
) -> EventLoopFuture<(String, Double, RESPValue)?> {
|
||||
return self._bzpop(command: "BZPOPMAX", keys, timeout)
|
||||
@@ -469,7 +469,7 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _bzpop(
|
||||
command: String,
|
||||
_ keys: [String],
|
||||
_ keys: [RedisKey],
|
||||
_ timeout: Int
|
||||
) -> EventLoopFuture<(String, Double, RESPValue)?> {
|
||||
var args = keys.map(RESPValue.init)
|
||||
@@ -511,7 +511,7 @@ extension RedisClient {
|
||||
public func zincrby<Value: RESPValueConvertible>(
|
||||
_ amount: Double,
|
||||
element: Value,
|
||||
in key: String
|
||||
in key: RedisKey
|
||||
) -> EventLoopFuture<Double> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -552,8 +552,8 @@ extension RedisClient {
|
||||
/// - Returns: The number of elements in the new sorted set.
|
||||
@inlinable
|
||||
public func zunionstore(
|
||||
as destination: String,
|
||||
sources: [String],
|
||||
as destination: RedisKey,
|
||||
sources: [RedisKey],
|
||||
weights: [Int]? = nil,
|
||||
aggregateMethod aggregate: RedisSortedSetAggregateMethod? = nil
|
||||
) -> EventLoopFuture<Int> {
|
||||
@@ -572,8 +572,8 @@ extension RedisClient {
|
||||
/// - Returns: The number of elements in the new sorted set.
|
||||
@inlinable
|
||||
public func zinterstore(
|
||||
as destination: String,
|
||||
sources: [String],
|
||||
as destination: RedisKey,
|
||||
sources: [RedisKey],
|
||||
weights: [Int]? = nil,
|
||||
aggregateMethod aggregate: RedisSortedSetAggregateMethod? = nil
|
||||
) -> EventLoopFuture<Int> {
|
||||
@@ -583,8 +583,8 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _zopstore(
|
||||
command: String,
|
||||
_ sources: [String],
|
||||
_ destination: String,
|
||||
_ sources: [RedisKey],
|
||||
_ destination: RedisKey,
|
||||
_ weights: [Int]?,
|
||||
_ aggregate: RedisSortedSetAggregateMethod?
|
||||
) -> EventLoopFuture<Int> {
|
||||
@@ -631,7 +631,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrange(
|
||||
within range: (start: Int, stop: Int),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
withScores: Bool = false
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
return _zrange(command: "ZRANGE", key, range.start, range.stop, withScores)
|
||||
@@ -651,7 +651,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrevrange(
|
||||
within range: (start: Int, stop: Int),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
withScores: Bool = false
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
return _zrange(command: "ZREVRANGE", key, range.start, range.stop, withScores)
|
||||
@@ -660,7 +660,7 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _zrange(
|
||||
command: String,
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
_ start: Int,
|
||||
_ stop: Int,
|
||||
_ withScores: Bool
|
||||
@@ -696,7 +696,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrangebyscore(
|
||||
within range: (min: String, max: String),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
withScores: Bool = false,
|
||||
limitBy limit: (offset: Int, count: Int)? = nil
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
@@ -718,7 +718,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrevrangebyscore(
|
||||
within range: (min: String, max: String),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
withScores: Bool = false,
|
||||
limitBy limit: (offset: Int, count: Int)? = nil
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
@@ -728,7 +728,7 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _zrangebyscore(
|
||||
command: String,
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
_ range: (min: String, max: String),
|
||||
_ withScores: Bool,
|
||||
_ limit: (offset: Int, count: Int)?
|
||||
@@ -769,7 +769,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrangebylex(
|
||||
within range: (min: String, max: String),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
limitBy limit: (offset: Int, count: Int)? = nil
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
return _zrangebylex(command: "ZRANGEBYLEX", key, range, limit)
|
||||
@@ -790,7 +790,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zrevrangebylex(
|
||||
within range: (min: String, max: String),
|
||||
from key: String,
|
||||
from key: RedisKey,
|
||||
limitBy limit: (offset: Int, count: Int)? = nil
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
return _zrangebylex(command: "ZREVRANGEBYLEX", key, (range.max, range.min), limit)
|
||||
@@ -799,7 +799,7 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _zrangebylex(
|
||||
command: String,
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
_ range: (min: String, max: String),
|
||||
_ limit: (offset: Int, count: Int)?
|
||||
) -> EventLoopFuture<[RESPValue]> {
|
||||
@@ -832,7 +832,7 @@ extension RedisClient {
|
||||
/// - key: The key of the sorted set.
|
||||
/// - Returns: The number of elements removed from the set.
|
||||
@inlinable
|
||||
public func zrem<Value: RESPValueConvertible>(_ elements: [Value], from key: String) -> EventLoopFuture<Int> {
|
||||
public func zrem<Value: RESPValueConvertible>(_ elements: [Value], from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
guard elements.count > 0 else { return self.eventLoop.makeSucceededFuture(0) }
|
||||
|
||||
var args: [RESPValue] = [.init(bulk: key)]
|
||||
@@ -850,7 +850,7 @@ extension RedisClient {
|
||||
/// - key: The key of the sorted set.
|
||||
/// - Returns: The number of elements removed from the set.
|
||||
@inlinable
|
||||
public func zrem<Value: RESPValueConvertible>(_ elements: Value..., from key: String) -> EventLoopFuture<Int> {
|
||||
public func zrem<Value: RESPValueConvertible>(_ elements: Value..., from key: RedisKey) -> EventLoopFuture<Int> {
|
||||
return self.zrem(elements, from: key)
|
||||
}
|
||||
|
||||
@@ -865,7 +865,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zremrangebylex(
|
||||
within range: (min: String, max: String),
|
||||
from key: String
|
||||
from key: RedisKey
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -886,7 +886,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zremrangebyrank(
|
||||
within range: (start: Int, stop: Int),
|
||||
from key: String
|
||||
from key: RedisKey
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
@@ -907,7 +907,7 @@ extension RedisClient {
|
||||
@inlinable
|
||||
public func zremrangebyscore(
|
||||
within range: (min: String, max: String),
|
||||
from key: String
|
||||
from key: RedisKey
|
||||
) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
|
||||
@@ -23,7 +23,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key to fetch the value from.
|
||||
/// - Returns: The string value stored at the key provided, otherwise `nil` if the key does not exist.
|
||||
@inlinable
|
||||
public func get(_ key: String) -> EventLoopFuture<String?> {
|
||||
public func get(_ key: RedisKey) -> EventLoopFuture<String?> {
|
||||
return self.get(key, as: String.self)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ extension RedisClient {
|
||||
/// - Returns: The converted value stored at the key provided, otherwise `nil` if the key does not exist or fails the conversion.
|
||||
@inlinable
|
||||
public func get<StoredType: RESPValueConvertible>(
|
||||
_ key: String,
|
||||
_ key: RedisKey,
|
||||
as type: StoredType.Type
|
||||
) -> EventLoopFuture<StoredType?> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
@@ -50,7 +50,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The list of keys to fetch the values from.
|
||||
/// - Returns: The values stored at the keys provided, matching the same order.
|
||||
@inlinable
|
||||
public func mget(_ keys: [String]) -> EventLoopFuture<[RESPValue]> {
|
||||
public func mget(_ keys: [RedisKey]) -> EventLoopFuture<[RESPValue]> {
|
||||
guard keys.count > 0 else { return self.eventLoop.makeSucceededFuture([]) }
|
||||
|
||||
let args = keys.map(RESPValue.init)
|
||||
@@ -64,7 +64,7 @@ extension RedisClient {
|
||||
/// - Parameter keys: The list of keys to fetch the values from.
|
||||
/// - Returns: The values stored at the keys provided, matching the same order.
|
||||
@inlinable
|
||||
public func mget(_ keys: String...) -> EventLoopFuture<[RESPValue]> {
|
||||
public func mget(_ keys: RedisKey...) -> EventLoopFuture<[RESPValue]> {
|
||||
return self.mget(keys)
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ extension RedisClient {
|
||||
/// - key: The key to use to uniquely identify this value.
|
||||
/// - Returns: The length of the key's value after appending the additional value.
|
||||
@inlinable
|
||||
public func append<Value: RESPValueConvertible>(_ value: Value, to key: String) -> EventLoopFuture<Int> {
|
||||
public func append<Value: RESPValueConvertible>(_ value: Value, to key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
value.convertedToRESPValue()
|
||||
@@ -102,7 +102,7 @@ extension RedisClient {
|
||||
/// - value: The value to set the key to.
|
||||
/// - Returns: An `EventLoopFuture` that resolves if the operation was successful.
|
||||
@inlinable
|
||||
public func set<Value: RESPValueConvertible>(_ key: String, to value: Value) -> EventLoopFuture<Void> {
|
||||
public func set<Value: RESPValueConvertible>(_ key: RedisKey, to value: Value) -> EventLoopFuture<Void> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
value.convertedToRESPValue()
|
||||
@@ -118,7 +118,7 @@ extension RedisClient {
|
||||
/// - Parameter operations: The key-value list of SET operations to execute.
|
||||
/// - Returns: An `EventLoopFuture` that resolves if the operation was successful.
|
||||
@inlinable
|
||||
public func mset<Value: RESPValueConvertible>(_ operations: [String: Value]) -> EventLoopFuture<Void> {
|
||||
public func mset<Value: RESPValueConvertible>(_ operations: [RedisKey: Value]) -> EventLoopFuture<Void> {
|
||||
return _mset(command: "MSET", operations)
|
||||
.map { _ in () }
|
||||
}
|
||||
@@ -130,7 +130,7 @@ extension RedisClient {
|
||||
/// - Parameter operations: The key-value list of SET operations to execute.
|
||||
/// - Returns: `true` if the operation successfully completed.
|
||||
@inlinable
|
||||
public func msetnx<Value: RESPValueConvertible>(_ operations: [String: Value]) -> EventLoopFuture<Bool> {
|
||||
public func msetnx<Value: RESPValueConvertible>(_ operations: [RedisKey: Value]) -> EventLoopFuture<Bool> {
|
||||
return _mset(command: "MSETNX", operations)
|
||||
.convertFromRESPValue(to: Int.self)
|
||||
.map { return $0 == 1 }
|
||||
@@ -139,7 +139,7 @@ extension RedisClient {
|
||||
@usableFromInline
|
||||
func _mset<Value: RESPValueConvertible>(
|
||||
command: String,
|
||||
_ operations: [String: Value]
|
||||
_ operations: [RedisKey: Value]
|
||||
) -> EventLoopFuture<RESPValue> {
|
||||
assert(operations.count > 0, "At least 1 key-value pair should be provided.")
|
||||
|
||||
@@ -164,7 +164,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key whose value should be incremented.
|
||||
/// - Returns: The new value after the operation.
|
||||
@inlinable
|
||||
public func increment(_ key: String) -> EventLoopFuture<Int> {
|
||||
public func increment(_ key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "INCR", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -178,7 +178,7 @@ extension RedisClient {
|
||||
/// - count: The amount that this value should be incremented, supporting both positive and negative values.
|
||||
/// - Returns: The new value after the operation.
|
||||
@inlinable
|
||||
public func increment(_ key: String, by count: Int) -> EventLoopFuture<Int> {
|
||||
public func increment(_ key: RedisKey, by count: Int) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: count)
|
||||
@@ -195,7 +195,7 @@ extension RedisClient {
|
||||
/// - count: The amount that this value should be incremented, supporting both positive and negative values.
|
||||
/// - Returns: The new value after the operation.
|
||||
@inlinable
|
||||
public func increment<Value>(_ key: String, by count: Value) -> EventLoopFuture<Value>
|
||||
public func increment<Value>(_ key: RedisKey, by count: Value) -> EventLoopFuture<Value>
|
||||
where
|
||||
Value: BinaryFloatingPoint,
|
||||
Value: RESPValueConvertible
|
||||
@@ -218,7 +218,7 @@ extension RedisClient {
|
||||
/// - Parameter key: The key whose value should be decremented.
|
||||
/// - Returns: The new value after the operation.
|
||||
@inlinable
|
||||
public func decrement(_ key: String) -> EventLoopFuture<Int> {
|
||||
public func decrement(_ key: RedisKey) -> EventLoopFuture<Int> {
|
||||
let args = [RESPValue(bulk: key)]
|
||||
return send(command: "DECR", with: args)
|
||||
.convertFromRESPValue()
|
||||
@@ -231,7 +231,7 @@ extension RedisClient {
|
||||
/// - key: The key whose value should be decremented.
|
||||
/// - count: The amount that this value should be decremented, supporting both positive and negative values.
|
||||
/// - Returns: The new value after the operation.
|
||||
public func decrement(_ key: String, by count: Int) -> EventLoopFuture<Int> {
|
||||
public func decrement(_ key: RedisKey, by count: Int) -> EventLoopFuture<Int> {
|
||||
let args: [RESPValue] = [
|
||||
.init(bulk: key),
|
||||
.init(bulk: count)
|
||||
|
||||
@@ -150,3 +150,15 @@ extension RESPValue: Equatable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: RESPValueConvertible
|
||||
|
||||
extension RESPValue: RESPValueConvertible {
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
self = value
|
||||
}
|
||||
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,33 +29,6 @@ public protocol RESPValueConvertible {
|
||||
func convertedToRESPValue() -> RESPValue
|
||||
}
|
||||
|
||||
extension RESPValue: RESPValueConvertible {
|
||||
/// See `RESPValueConvertible.init(fromRESP:)`
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
self = value
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
extension RedisError: RESPValueConvertible {
|
||||
/// Unwraps an `.error` representation directly into a `RedisError` instance.
|
||||
///
|
||||
/// See `RESPValueConvertible.init(fromRESP:)`
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
guard case let .error(e) = value else { return nil }
|
||||
self = e
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .error(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension String: RESPValueConvertible {
|
||||
/// Attempts to provide a UTF-8 representation of the `RESPValue` provided.
|
||||
///
|
||||
@@ -80,7 +53,6 @@ extension String: RESPValueConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .init(bulk: self)
|
||||
}
|
||||
@@ -104,7 +76,6 @@ extension FixedWidthInteger {
|
||||
}
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .init(bulk: self.description)
|
||||
}
|
||||
@@ -135,7 +106,6 @@ extension Double: RESPValueConvertible {
|
||||
self = double
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .init(bulk: self.description)
|
||||
}
|
||||
@@ -155,7 +125,6 @@ extension Float: RESPValueConvertible {
|
||||
self = float
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .init(bulk: self.description)
|
||||
}
|
||||
@@ -224,7 +193,6 @@ extension Optional: RESPValueConvertible where Wrapped: RESPValueConvertible {
|
||||
import struct Foundation.Data
|
||||
|
||||
extension Data: RESPValueConvertible {
|
||||
/// See `RESPValueConvertible.init(fromRESP:)`
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
switch value {
|
||||
case let .simpleString(buffer),
|
||||
@@ -236,7 +204,6 @@ extension Data: RESPValueConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
/// See `RESPValueConvertible.convertedToRESPValue()`
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
var buffer = RESPValue.allocator.buffer(capacity: self.count)
|
||||
buffer.writeBytes(self)
|
||||
|
||||
@@ -50,3 +50,19 @@ public struct RedisError: LocalizedError, Equatable {
|
||||
return lhs.message == rhs.message
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: RESPValueConvertible
|
||||
|
||||
extension RedisError: RESPValueConvertible {
|
||||
/// Unwraps an `.error` representation directly into a `RedisError` instance.
|
||||
///
|
||||
/// See `RESPValueConvertible.init(fromRESP:)`
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
guard case let .error(e) = value else { return nil }
|
||||
self = e
|
||||
}
|
||||
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .error(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the RediStack open source project
|
||||
//
|
||||
// Copyright (c) 2019 RediStack project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of RediStack project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// A representation of a key in Redis.
|
||||
///
|
||||
/// `RedisKey` is a thin wrapper around `String`, to provide stronger type-safety at compile-time.
|
||||
///
|
||||
/// It conforms to `ExpressibleByStringLiteral`, so creating a key is simple:
|
||||
/// ```swift
|
||||
/// let key: RedisKey = "foo"
|
||||
/// ```
|
||||
public struct RedisKey: RawRepresentable {
|
||||
public typealias RawValue = String
|
||||
|
||||
public let rawValue: String
|
||||
|
||||
/// Initializes a type-safe representation of a key to a value in a Redis instance.
|
||||
/// - Parameter key: The key of a value in a Redis instance.
|
||||
public init(_ key: String) {
|
||||
self.rawValue = key
|
||||
}
|
||||
|
||||
public init?(rawValue: String) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: ExpressibleByStringLiteral
|
||||
|
||||
extension RedisKey: ExpressibleByStringLiteral {
|
||||
public init(stringLiteral value: String) {
|
||||
self.rawValue = value
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: CustomStringConvertible
|
||||
|
||||
extension RedisKey: CustomStringConvertible {
|
||||
public var description: String { return self.rawValue }
|
||||
}
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
extension RedisKey: CustomDebugStringConvertible {
|
||||
public var debugDescription: String { return "RedisKey: \(self.rawValue)" }
|
||||
}
|
||||
|
||||
// MARK: Comparable && Equatable
|
||||
|
||||
extension RedisKey: Comparable {
|
||||
public static func <(lhs: RedisKey, rhs: RedisKey) -> Bool {
|
||||
return lhs.rawValue < rhs.rawValue
|
||||
}
|
||||
|
||||
public static func ==(lhs: RedisKey, rhs: RedisKey) -> Bool {
|
||||
return lhs.rawValue == rhs.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Hashable
|
||||
|
||||
extension RedisKey: Hashable {
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(self.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Codable
|
||||
|
||||
extension RedisKey: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
self.rawValue = try container.decode(String.self)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(self.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: RESPValue
|
||||
|
||||
extension RESPValue {
|
||||
/// Initializes a `bulkString` value from the `RedisKey`.
|
||||
/// - Prameter key: The RedisKey to store in a `.bulkString` representation.
|
||||
public init(bulk key: RedisKey) {
|
||||
self = .init(bulk: key.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: RESPValueConvertible
|
||||
|
||||
extension RedisKey: RESPValueConvertible {
|
||||
public init?(fromRESP value: RESPValue) {
|
||||
guard let string = value.string else { return nil }
|
||||
self.rawValue = string
|
||||
}
|
||||
|
||||
public func convertedToRESPValue() -> RESPValue {
|
||||
return .init(bulk: self.rawValue)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ final class BasicCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_delete() throws {
|
||||
let keys = [ #function + "1", #function + "2", #function + "3" ]
|
||||
let keys = [ #function + "1", #function + "2", #function + "3" ].map(RedisKey.init(_:))
|
||||
try connection.set(keys[0], to: "value").wait()
|
||||
try connection.set(keys[1], to: "value").wait()
|
||||
try connection.set(keys[2], to: "value").wait()
|
||||
@@ -87,9 +87,9 @@ final class BasicCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_scan() throws {
|
||||
var dataset: [String] = .init(repeating: "", count: 10)
|
||||
var dataset: [RedisKey] = .init(repeating: "", count: 10)
|
||||
for index in 1...15 {
|
||||
let key = "key\(index)\(index % 2 == 0 ? "_even" : "_odd")"
|
||||
let key = RedisKey("key\(index)\(index % 2 == 0 ? "_even" : "_odd")")
|
||||
dataset.append(key)
|
||||
_ = try connection.set(key, to: "\(index)").wait()
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sdiff() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([3, 4, 5], to: key2).wait()
|
||||
@@ -110,9 +110,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sdiffstore() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([3, 4, 5], to: key2).wait()
|
||||
@@ -125,9 +125,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sinter() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([3, 4, 5], to: key2).wait()
|
||||
@@ -147,9 +147,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sinterstore() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([3, 4, 5], to: key2).wait()
|
||||
@@ -178,9 +178,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sunion() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([3, 4, 5], to: key2).wait()
|
||||
@@ -197,9 +197,9 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sunionstore() throws {
|
||||
let key1 = #function
|
||||
let key2 = #file
|
||||
let key3 = key1 + key2
|
||||
let key1: RedisKey = #function
|
||||
let key2: RedisKey = #file
|
||||
let key3 = RedisKey(key1.rawValue + key2.rawValue)
|
||||
|
||||
_ = try connection.sadd([1, 2, 3], to: key1).wait()
|
||||
_ = try connection.sadd([2, 3, 4], to: key2).wait()
|
||||
@@ -214,7 +214,7 @@ final class SetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_sscan() throws {
|
||||
let key = #function
|
||||
let key: RedisKey = #function
|
||||
let dataset = [
|
||||
"Copenhagen, Denmark",
|
||||
"Roskilde, Denmark",
|
||||
|
||||
@@ -18,9 +18,9 @@ import RediStackTestUtils
|
||||
import XCTest
|
||||
|
||||
final class SortedSetCommandsTests: RediStackIntegrationTestCase {
|
||||
private static let testKey = "SortedSetCommandsTests"
|
||||
private static let testKey: RedisKey = "SortedSetCommandsTests"
|
||||
|
||||
private var key: String { return SortedSetCommandsTests.testKey }
|
||||
private var key: RedisKey { return SortedSetCommandsTests.testKey }
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
@@ -158,7 +158,7 @@ final class SortedSetCommandsTests: RediStackIntegrationTestCase {
|
||||
let min1 = try connection.bzpopmin(from: key).wait()
|
||||
XCTAssertEqual(min1?.0, 1)
|
||||
let min2 = try connection.bzpopmin(from: [#function, key]).wait()
|
||||
XCTAssertEqual(min2?.0, key)
|
||||
XCTAssertEqual(min2?.0, key.rawValue)
|
||||
XCTAssertEqual(min2?.1, 2)
|
||||
|
||||
let blockingConnection = try self.makeNewConnection()
|
||||
@@ -192,7 +192,7 @@ final class SortedSetCommandsTests: RediStackIntegrationTestCase {
|
||||
let max1 = try connection.bzpopmax(from: key).wait()
|
||||
XCTAssertEqual(max1?.0, 10)
|
||||
let max2 = try connection.bzpopmax(from: [#function, key]).wait()
|
||||
XCTAssertEqual(max2?.0, key)
|
||||
XCTAssertEqual(max2?.0, key.rawValue)
|
||||
XCTAssertEqual(max2?.1, 9)
|
||||
|
||||
let blockingConnection = try self.makeNewConnection()
|
||||
@@ -219,19 +219,21 @@ final class SortedSetCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_zunionstore() throws {
|
||||
let testKey = RedisKey(#function + #file)
|
||||
|
||||
_ = try connection.zadd([(1, 1), (2, 2)], to: #function).wait()
|
||||
_ = try connection.zadd([(3, 3), (4, 4)], to: #file).wait()
|
||||
|
||||
let unionCount = try connection.zunionstore(
|
||||
as: #function+#file,
|
||||
as: testKey,
|
||||
sources: [key, #function, #file],
|
||||
weights: [3, 2, 1],
|
||||
aggregateMethod: .max
|
||||
).wait()
|
||||
XCTAssertEqual(unionCount, 10)
|
||||
let rank = try connection.zrank(of: 10, in: #function+#file).wait()
|
||||
let rank = try connection.zrank(of: 10, in: testKey).wait()
|
||||
XCTAssertEqual(rank, 9)
|
||||
let score = try connection.zscore(of: 10, in: #function+#file).wait()
|
||||
let score = try connection.zscore(of: 10, in: testKey).wait()
|
||||
XCTAssertEqual(score, 30)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ final class StringCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_mget() throws {
|
||||
let keys = ["one", "two"]
|
||||
let keys = ["one", "two"].map(RedisKey.init(_:))
|
||||
try keys.forEach { _ = try connection.set($0, to: $0).wait() }
|
||||
|
||||
let values = try connection.mget(keys + ["empty"]).wait()
|
||||
@@ -58,7 +58,7 @@ final class StringCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_mset() throws {
|
||||
let data = [
|
||||
let data: [RedisKey: Int] = [
|
||||
"first": 1,
|
||||
"second": 2
|
||||
]
|
||||
@@ -74,7 +74,7 @@ final class StringCommandsTests: RediStackIntegrationTestCase {
|
||||
}
|
||||
|
||||
func test_msetnx() throws {
|
||||
let data = [
|
||||
let data: [RedisKey: Int] = [
|
||||
"first": 1,
|
||||
"second": 2
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user