From d1227ce2e3e088afbd50ff4ddecd1cca86b5a5d5 Mon Sep 17 00:00:00 2001 From: Stephen Mitchell Date: Wed, 14 Oct 2020 09:40:04 -0400 Subject: [PATCH 1/3] Adds username AUTH, disconnect methods. --- Sources/SwiftRedis/Redis.swift | 18 +++++++++++++++++- Sources/SwiftRedis/RedisResp.swift | 8 ++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftRedis/Redis.swift b/Sources/SwiftRedis/Redis.swift index 0354411..f99c7dc 100644 --- a/Sources/SwiftRedis/Redis.swift +++ b/Sources/SwiftRedis/Redis.swift @@ -23,7 +23,7 @@ import Foundation public class Redis { /// Redis Serialization Protocol handle - private var respHandle: RedisResp? + public var respHandle: RedisResp? /// Whether the client is connected or not. /// Does not reflect state changes in the event of a disconnect. @@ -48,9 +48,15 @@ public class Redis { callback(nil) } } + + /// Disconnects from a redis server + public func disconnect(){ + respHandle?.disconnect() + } /// Authenticate against the server /// + /// - Parameter username: String for the username (Redis 6+ only). /// - Parameter pswd: String for the password. /// - Parameter callback: callback function that is called after authenticating, /// NSError will be nil if successful. @@ -61,6 +67,16 @@ public class Redis { callback(error) } } + + public func auth(_ username: String, _ pswd: String, callback: (NSError?) -> Void) { + if username == "" { + return auth(pswd, callback: callback) + } + issueCommand("AUTH", username, pswd) {(response: RedisResponse) in + let (_, error) = self.redisOkResponseHandler(response, nilOk: false) + callback(error) + } + } /// Select the database to use /// diff --git a/Sources/SwiftRedis/RedisResp.swift b/Sources/SwiftRedis/RedisResp.swift index 9cdd9cf..6b039ac 100644 --- a/Sources/SwiftRedis/RedisResp.swift +++ b/Sources/SwiftRedis/RedisResp.swift @@ -22,10 +22,10 @@ enum RedisRespStatus { case connected } -class RedisResp { +public class RedisResp { /// /// Socket used to talk with the server - private var socket: Socket? + public var socket: Socket? // Mark: Prebuilt constant UTF8 strings (these strings are all proper UTF-8 strings) private static let asterisk = RedisString("*").asData @@ -46,6 +46,10 @@ class RedisResp { try? socket?.connect(to: host, port: port) } + func disconnect(){ + socket?.close() + } + func issueCommand(_ stringArgs: [String], callback: (RedisResponse) -> Void) { guard let socket = socket else { return } From 5855efd375fb5657ec3f7bf8a8520f68ab6599df Mon Sep 17 00:00:00 2001 From: Stephen Mitchell Date: Fri, 5 Feb 2021 09:15:59 -0500 Subject: [PATCH 2/3] Code review --- Sources/SwiftRedis/Redis.swift | 98 +++++++++++++++--------------- Sources/SwiftRedis/RedisResp.swift | 2 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Sources/SwiftRedis/Redis.swift b/Sources/SwiftRedis/Redis.swift index f99c7dc..f85a5ab 100644 --- a/Sources/SwiftRedis/Redis.swift +++ b/Sources/SwiftRedis/Redis.swift @@ -21,19 +21,19 @@ import Foundation /// The `Redis` class represents a handle for issueing commands to a Redis server. /// It provides a set of type safe functions for issueing those commands. public class Redis { - + /// Redis Serialization Protocol handle - public var respHandle: RedisResp? - + private var respHandle: RedisResp? + /// Whether the client is connected or not. /// Does not reflect state changes in the event of a disconnect. public var connected: Bool { return respHandle?.status == .connected } - + /// Initializes a `Redis` instance public init () {} - + /// Connects to a redis server /// /// - Parameter host: the server IP address. @@ -53,7 +53,7 @@ public class Redis { public func disconnect(){ respHandle?.disconnect() } - + /// Authenticate against the server /// /// - Parameter username: String for the username (Redis 6+ only). @@ -61,7 +61,7 @@ public class Redis { /// - Parameter callback: callback function that is called after authenticating, /// NSError will be nil if successful. public func auth(_ pswd: String, callback: (NSError?) -> Void) { - + issueCommand("AUTH", pswd) {(response: RedisResponse) in let (_, error) = self.redisOkResponseHandler(response, nilOk: false) callback(error) @@ -77,27 +77,27 @@ public class Redis { callback(error) } } - + /// Select the database to use /// /// - Parameter db: numeric index for the database. /// - Parameter callback: callback function for after the database is selected, /// NSError will be nil if successful. public func select(_ db: Int, callback: (NSError?) -> Void) { - + issueCommand("SELECT", String(db)) {(response: RedisResponse) in let (_, error) = self.redisOkResponseHandler(response, nilOk: false) callback(error) } } - + /// Ping the server to test if a connection is still alive /// /// - Parameter pingStr: String for the ping message. /// - Parameter callback: callback function for after the pong is received, /// NSError will be nil if successful. public func ping(_ pingStr: String?=nil, callback: (NSError?) -> Void) { - + var command = ["PING"] if let pingStr = pingStr { command.append(pingStr) @@ -123,19 +123,19 @@ public class Redis { } } } - + /// Echos a message /// /// - Parameter str: String for the message. /// - Parameter callback: callback function with the String echoed back, /// NSError will be nil if successful. public func echo(_ str: String, callback: (RedisString?, NSError?) -> Void) { - + issueCommand("ECHO", str) {(response: RedisResponse) in self.redisStringResponseHandler(response, callback: callback) } } - + /// Get information and statistics about the server /// /// - Parameter callback: callback function with the response as a collection of text @@ -145,7 +145,7 @@ public class Redis { self.redisStringResponseHandler(response, callback: callback) } } - + /// Get information and statistics about the server /// /// - Parameter callback: callback function with the response as a struct @@ -156,7 +156,7 @@ public class Redis { self.redisDictionaryResponseHandler(response, callback: callback) } } - + /// Delete all the keys of the currently selected DB. This command never fails. /// /// - Parameter callback: a function returning the response, @@ -167,22 +167,22 @@ public class Redis { callback(ok, _: error) } } - - + + // // MARK: Transaction support // - + /// Create a `RedisMulti` object in order to perform a Redis transaction public func multi() -> RedisMulti { return RedisMulti(redis: self) } - - + + // // MARK: Base API functions // - + /// Issue a Redis command /// /// - Parameter stringArgs: A list of Strings making up the Redis command to issue @@ -190,7 +190,7 @@ public class Redis { public func issueCommand(_ stringArgs: String..., callback: (RedisResponse) -> Void) { issueCommandInArray(stringArgs, callback: callback) } - + /// Issue a Redis command /// /// - Parameter stringArgs: An array of Strings making up the Redis command to issue @@ -200,15 +200,15 @@ public class Redis { callback(RedisResponse.Error("Not connected to Redis server")) return } - + guard stringArgs.count > 0 else { callback(RedisResponse.Error("Empty command")) return } - + respHandle.issueCommand(stringArgs, callback: callback) } - + /// Issue a Redis command /// /// - Parameter stringArgs: A list of `RedisString` objects making up the Redis command to issue @@ -216,7 +216,7 @@ public class Redis { public func issueCommand(_ stringArgs: RedisString..., callback: (RedisResponse) -> Void) { issueCommandInArray(stringArgs, callback: callback) } - + /// Issue a Redis command /// /// - Parameter stringArgs: An array of `RedisString` objects making up the Redis command to issue @@ -226,19 +226,19 @@ public class Redis { callback(RedisResponse.Error("Not connected to Redis server")) return } - + guard stringArgs.count > 0 else { callback(RedisResponse.Error("Empty command")) return } - + respHandle.issueCommand(stringArgs, callback: callback) } - + // // MARK: Helper functions // - + func redisBoolResponseHandler(_ response: RedisResponse, callback: (Bool, NSError?) -> Void) { switch(response) { case .IntegerValue(let num): @@ -253,7 +253,7 @@ public class Redis { callback(false, _: createUnexpectedResponseError(response)) } } - + func redisIntegerResponseHandler(_ response: RedisResponse, callback: (Int?, NSError?) -> Void) { switch(response) { case .IntegerValue(let num): @@ -266,7 +266,7 @@ public class Redis { callback(nil, _: createUnexpectedResponseError(response)) } } - + func redisOkResponseHandler(_ response: RedisResponse, nilOk: Bool=true) -> (Bool, NSError?) { switch(response) { case .Status(let str): @@ -283,7 +283,7 @@ public class Redis { return (false, createUnexpectedResponseError(response)) } } - + func redisSimpleStringResponseHandler(response: RedisResponse, callback: (String?, NSError?) -> Void) { switch(response) { case .Status(let str): @@ -296,7 +296,7 @@ public class Redis { callback(nil, _: createUnexpectedResponseError(response)) } } - + func redisStringResponseHandler(_ response: RedisResponse, callback: (RedisString?, NSError?) -> Void) { switch(response) { case .StringValue(let str): @@ -309,11 +309,11 @@ public class Redis { callback(nil, _: createUnexpectedResponseError(response)) } } - + func redisArrayResponseHandler(response: RedisResponse, callback: ([RedisResponse?]?, NSError?) -> Void) { var error: NSError? = nil var result: [RedisResponse?]? - + switch(response) { case .Array(let responses): result = responses @@ -326,7 +326,7 @@ public class Redis { } callback(error == nil ? result : nil, _: error) } - + func getCoordinates(from responses: [RedisResponse?]?, callback: ([(Double, Double)?]?, NSError?) -> Void) { guard let responses = responses else { callback(nil, createError("Could not get coordinates from nil response.", code: 1)) @@ -348,11 +348,11 @@ public class Redis { } callback(result, nil) } - + func redisStringArrayResponseHandler(_ response: RedisResponse, callback: ([RedisString?]?, NSError?) -> Void) { var error: NSError? = nil var result: [RedisString?]? - + switch(response) { case .Array(let responses): var strings = [RedisString?]() @@ -376,11 +376,11 @@ public class Redis { } callback(error == nil ? result : nil, _: error) } - + func redisStringArrayOrIntegerResponseHandler(_ response: RedisResponse, callback: ([RedisString?]?, NSError?) -> Void) { var error: NSError? = nil var result: [RedisString?]? - + switch(response) { case .Array(let responses): var strings = [RedisString?]() @@ -406,12 +406,12 @@ public class Redis { } callback(error == nil ? result : nil, _: error) } - + func redisScanResponseHandler(_ response: RedisResponse, callback: (RedisString?, [RedisString?]?, NSError?) -> Void) { var error: NSError? = nil var cursor: RedisString? var result: [RedisString?]? - + switch(response) { case .Array(let responses): var strings = [RedisString?]() @@ -442,14 +442,14 @@ public class Redis { default: error = self.createUnexpectedResponseError(response) } - + if(error == nil) { callback(cursor, result, nil) } else { callback(nil, nil, error) } } - + func redisDictionaryResponseHandler(_ response: RedisResponse, callback: (RedisInfo?, NSError?) -> Void) { switch(response) { case .StringValue(let str): @@ -462,11 +462,11 @@ public class Redis { callback(nil, _: createUnexpectedResponseError(response)) } } - + func createUnexpectedResponseError(_ response: RedisResponse) -> NSError { return createError("Unexpected result received from Redis \(response)", code: 2) } - + func createError(_ errorMessage: String, code: Int) -> NSError { #if os(Linux) let userInfo: [String: Any] @@ -476,7 +476,7 @@ public class Redis { userInfo = [NSLocalizedDescriptionKey: errorMessage] return NSError(domain: "RedisDomain", code: code, userInfo: userInfo) } - + func createRedisError(_ redisError: String) -> NSError { return createError(redisError, code: 1) } diff --git a/Sources/SwiftRedis/RedisResp.swift b/Sources/SwiftRedis/RedisResp.swift index 6b039ac..c47c29a 100644 --- a/Sources/SwiftRedis/RedisResp.swift +++ b/Sources/SwiftRedis/RedisResp.swift @@ -25,7 +25,7 @@ enum RedisRespStatus { public class RedisResp { /// /// Socket used to talk with the server - public var socket: Socket? + private var socket: Socket? // Mark: Prebuilt constant UTF8 strings (these strings are all proper UTF-8 strings) private static let asterisk = RedisString("*").asData From f085c64f1fdd6ff38c18ae164c8c602beb3ddffa Mon Sep 17 00:00:00 2001 From: Stephen Mitchell Date: Fri, 5 Feb 2021 09:20:25 -0500 Subject: [PATCH 3/3] Comment updates --- Sources/SwiftRedis/Redis.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftRedis/Redis.swift b/Sources/SwiftRedis/Redis.swift index f85a5ab..1c6a4d0 100644 --- a/Sources/SwiftRedis/Redis.swift +++ b/Sources/SwiftRedis/Redis.swift @@ -56,7 +56,6 @@ public class Redis { /// Authenticate against the server /// - /// - Parameter username: String for the username (Redis 6+ only). /// - Parameter pswd: String for the password. /// - Parameter callback: callback function that is called after authenticating, /// NSError will be nil if successful. @@ -68,6 +67,12 @@ public class Redis { } } + /// Authenticate against the server using a username. (Redis 6+) + /// + /// - Parameter username: String for the username. + /// - Parameter pswd: String for the password. + /// - Parameter callback: callback function that is called after authenticating, + /// NSError will be nil if successful. public func auth(_ username: String, _ pswd: String, callback: (NSError?) -> Void) { if username == "" { return auth(pswd, callback: callback)