Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds username AUTH, disconnect methods. #84

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 69 additions & 48 deletions Sources/SwiftRedis/Redis.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
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.
Expand All @@ -48,40 +48,61 @@ public class Redis {
callback(nil)
}
}


/// Disconnects from a redis server
public func disconnect(){
respHandle?.disconnect()
}

/// Authenticate against the server
///
/// - Parameter pswd: String for the password.
/// - 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)
}
}


/// 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)
}
issueCommand("AUTH", username, pswd) {(response: RedisResponse) in
let (_, error) = self.redisOkResponseHandler(response, nilOk: false)
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)
Expand All @@ -107,19 +128,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
Expand All @@ -129,7 +150,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
Expand All @@ -140,7 +161,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,
Expand All @@ -151,30 +172,30 @@ 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
/// - Parameter callback: a function returning the response in the form of a `RedisResponse`
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
Expand All @@ -184,23 +205,23 @@ 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
/// - Parameter callback: a function returning the response in the form of a `RedisResponse`
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
Expand All @@ -210,19 +231,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):
Expand All @@ -237,7 +258,7 @@ public class Redis {
callback(false, _: createUnexpectedResponseError(response))
}
}

func redisIntegerResponseHandler(_ response: RedisResponse, callback: (Int?, NSError?) -> Void) {
switch(response) {
case .IntegerValue(let num):
Expand All @@ -250,7 +271,7 @@ public class Redis {
callback(nil, _: createUnexpectedResponseError(response))
}
}

func redisOkResponseHandler(_ response: RedisResponse, nilOk: Bool=true) -> (Bool, NSError?) {
switch(response) {
case .Status(let str):
Expand All @@ -267,7 +288,7 @@ public class Redis {
return (false, createUnexpectedResponseError(response))
}
}

func redisSimpleStringResponseHandler(response: RedisResponse, callback: (String?, NSError?) -> Void) {
switch(response) {
case .Status(let str):
Expand All @@ -280,7 +301,7 @@ public class Redis {
callback(nil, _: createUnexpectedResponseError(response))
}
}

func redisStringResponseHandler(_ response: RedisResponse, callback: (RedisString?, NSError?) -> Void) {
switch(response) {
case .StringValue(let str):
Expand All @@ -293,11 +314,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
Expand All @@ -310,7 +331,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))
Expand All @@ -332,11 +353,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?]()
Expand All @@ -360,11 +381,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?]()
Expand All @@ -390,12 +411,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?]()
Expand Down Expand Up @@ -426,14 +447,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):
Expand All @@ -446,11 +467,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]
Expand All @@ -460,7 +481,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)
}
Expand Down
6 changes: 5 additions & 1 deletion Sources/SwiftRedis/RedisResp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum RedisRespStatus {
case connected
}

class RedisResp {
public class RedisResp {
mbarnach marked this conversation as resolved.
Show resolved Hide resolved
///
/// Socket used to talk with the server
private var socket: Socket?
Expand All @@ -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 }

Expand Down