A Swift client for Redis.

Overview

Perfect-Redis 简体中文

Get Involed with Perfect!

Star Perfect On Github Stack Overflow Follow Perfect on Twitter Join the Perfect Slack

Swift 4.0 Platforms OS X | Linux License Apache PerfectlySoft Twitter Slack Status

Redis client support for Perfect

Quick Start

Get a redis client with defaults (localhost, default port):

let client = RedisClient.getClient(withIdentifier: RedisClientIdentifier())

Ping the server:

let response = client.ping()
guard case .simpleString(let s) = response else {
	return
}
XCTAssert(s == "PONG", "Unexpected response \(response)")

Set/get a value:

let (key, value) = ("mykey", "myvalue")
var response = client.set(key: key, value: .string(value))
guard case .simpleString(let s) = response else {
	...
	return
}
response = client.get(key: key)
guard case .bulkString = response else {
	...
	return
}
let s = response.toString()
XCTAssert(s == value, "Unexpected response \(response)")

Pub/sub with two clients using async API:

RedisClient.getClient(withIdentifier: RedisClientIdentifier()) {
	c in
	do {
		let client1 = try c()
		RedisClient.getClient(withIdentifier: RedisClientIdentifier()) {
			c in
			do {
				let client2 = try c()
				client1.subscribe(channels: ["foo"]) {
					response in
					client2.publish(channel: "foo", message: .string("Hello!")) {
						response in
						client1.readPublished(timeoutSeconds: 5.0) {
							response in
							guard case .array(let array) = response else {
								...
								return
							}
							XCTAssert(array.count == 3, "Invalid array elements")
							XCTAssert(array[0].toString() == "message")
							XCTAssert(array[1].toString() == "foo")
							XCTAssert(array[2].toString() == "Hello!")
						}
					}
				}
			} catch {
				...
			}
		}
	} catch {
		...
	}
}

Building

Add this project as a dependency in your Package.swift file.

.package(url: "https://github.com/PerfectlySoft/Perfect-Redis.git", from: "3.2.3")

Further Information

For more information on the Perfect project, please visit perfect.org.

Comments
  • Add sendCommandAsRESP func

    Add sendCommandAsRESP func

    The library currently sends commands in the 'inline' format rather than using the REdis Serialization Protocol (see docs ). The 'inline' approach has a much smaller limit than RESP in terms of the size of the data that can be sent in for example a SET command.

    By adding public func sendCommandAsRESP these limits can be avoided when necessary.

    Perhaps in time the library can be refactored internally to use sendCommandAsRESP throughout, but I don't currently have time to do this.

    opened by sportlabsMike 1
  • ISS 551 LARGE STRING

    ISS 551 LARGE STRING

    ISS-551 Fixed. Description: When LRANGE a large bulk, for example, 80 char per line, then if fetching over 100 lines then LRANGE will raise a BAD_ACCESS exception. 
Reason: recursive bytes extraction causes thread unsafe buffer access.

    Fixed by threading with recv(fd) without recursive exactBytesFromBuffer().

    bug 
    opened by RockfordWei 1
  • - Added

    - Added "public" modifier to RedisValue and sendCommand to work aroun…

    Issue encountered:

    When transmitting json strings to redis (via LPUSH/LPUSHX) after using jsonEncodedString(), the values were being rejected. The situation was remedied by encoding the string with a leading and trailing single quote character instead of double quotes. To accomplish this, I needed extensions[1]. However, toString() in RedisValue and the sendCommand used within listPrepend and listPrependX were subject to "internal protection level" compilation errors.

    Proposed solution: Add "public" to sendCommand() and toString() so downstream users can make tweaks in edge cases such as mine.

    [1] Example extensions (mild tweaks on top of existing implementations):

    extension RedisClient.RedisValue { func toStringForRedis() -> String { switch self { case .string(let s): return "'(s)'" default: return self.toString() } } }

    extension RedisClient { func listPrepend(key: String, jsonRedisValues: [RedisValue], callback: @escaping redisResponseCallback) { self.sendCommand(name: "LPUSH (key) (jsonRedisValues.map { $0.toStringForRedis() }.joined(separator: " "))", callback: callback) } }

    opened by ptumati 1
  • Implementing hash functions

    Implementing hash functions

    • I've used XCTFail instead of XCTEqual(false..., due to this now the the two test classes are not consistent. I'm not sure what's the preferred way of failing the tests, but as soon as I get a comment I can change it to be consistent one way or the other.
    • Please review it carefully, this is my first swift code.
    • If the size of the PR is too big I can break it up into several smaller ones
    opened by jkrnak 1
  • update package dependency

    update package dependency

    Version ranges "Version(0,0,0)..<Version(10,0,0)" were generating exceptions when building:

    Package.swift:28:85: error: no '..<' candidates produce the expected contextual result type 'Version'

    Package.swift:28:85: note: overloads for '..<' exist with these result types: Range, CountableRange

    opened by marckula 0
  • Refactor internally to use sendCommandAsRESP throughout

    Refactor internally to use sendCommandAsRESP throughout

    from @sportlabsMike

    "Perhaps in time the library can be refactored internally to use sendCommandAsRESP throughout"

    "The library currently sends commands in the 'inline' format rather than using the REdis Serialization Protocol (see docs ). The 'inline' approach has a much smaller limit than RESP in terms of the size of the data that can be sent in for example a SET command.

    By adding public func sendCommandAsRESP these limits can be avoided when necessary.

    Perhaps in time the library can be refactored internally to use sendCommandAsRESP throughout, but I don't currently have time to do this."

    opened by kjessup 0
Owner
PerfectlySoft Inc.
Server-side Swift
PerfectlySoft Inc.
A stand-alone Swift wrapper around the MySQL client library, enabling access to MySQL servers.

Perfect - MySQL Connector This project provides a Swift wrapper around the MySQL client library, enabling access to MySQL database servers. This packa

PerfectlySoft Inc. 118 Jan 1, 2023
A stand-alone Swift wrapper around the libpq client library, enabling access to PostgreSQL servers.

Perfect - PostgreSQL Connector This project provides a Swift wrapper around the libpq client library, enabling access to PostgreSQL servers. This pack

PerfectlySoft Inc. 51 Nov 19, 2022
A PostgreSQL client library for Swift. Does not require libpq.

PostgresClientKit PostgresClientKit provides a friendly Swift API for operating against a PostgreSQL database. Features Doesn't require libpq. Postgre

codewins.com 107 Dec 1, 2022
A stand-alone Swift wrapper around the SQLite 3 client library.

Perfect - SQLite Connector This project provides a Swift wrapper around the SQLite 3 library. This package builds with Swift Package Manager and is pa

PerfectlySoft Inc. 47 Nov 19, 2022
A fast, pure swift MongoDB driver based on Swift NIO built for Server Side Swift

A fast, pure swift MongoDB driver based on Swift NIO built for Server Side Swift. It features a great API and a battle-tested core. Supporting both MongoDB in server and embedded environments.

null 646 Dec 10, 2022
SQLite.swift - A type-safe, Swift-language layer over SQLite3.

SQLite.swift provides compile-time confidence in SQL statement syntax and intent.

Stephen Celis 8.7k Jan 3, 2023
🧡 SQLiteOrm-Swift is an ORM library for SQLite3 built with Swift 5

?? Easy to use SQLite ORM library written with Swift

Yevgeniy Zakharov 25 Oct 6, 2022
ObjectBox Swift - persisting your Swift objects superfast and simple

ObjectBox Swift ObjectBox is a superfast, light-weight object persistence framework. This Swift API seamlessly persists objects on-device for iOS and

ObjectBox 380 Dec 19, 2022
Shows the issue with swift using an ObjC class which has a property from a swift package.

SwiftObjCSwiftTest Shows the issue with swift using an ObjC class which has a property from a swift package. The Swift class (created as @objc derived

Scott Little 0 Nov 8, 2021
Ios-App-ication-Swift - A simple iOS application made in Xcode using Swift

?? iPhone Calculator A simple iOS application made in Xcode using Swift. This ap

Kushal Shingote 1 Feb 2, 2022
Save-the-dot-project-swift - Save the dot project with swift

Save the Dot Apple introduced UIViewPropertyAnimator for iOS 10. We can use this

Kushal Shingote 2 Feb 8, 2022
The Swift Package Index is the place to find Swift packages!

The Swift Package Index helps you make better decisions about the dependencies you use in your apps. The Swift Package Index is a search engine for pa

Swift Package Index 389 Dec 22, 2022
Elegant library to manage the interactions between view and model in Swift

An assistant to manage the interactions between view and model ModelAssistant is a mediator between the view and model. This framework is tailored to

Seyed Samad Gholamzadeh 28 Jan 29, 2022
CRUD is an object-relational mapping (ORM) system for Swift 4+.

CRUD is an object-relational mapping (ORM) system for Swift 4+. CRUD takes Swift 4 Codable types and maps them to SQL database tables. CRUD can create tables based on Codable types and perform inserts and updates of objects in those tables. CRUD can also perform selects and joins of tables, all in a type-safe manner.

PerfectlySoft Inc. 61 Nov 18, 2022
CoreXLSX is a Excel spreadsheet (XLSX) format parser written in pure Swift

CoreXLSX Excel spreadsheet (XLSX) format parser written in pure Swift CoreXLSX is a library focused on representing the low-level structure of the XML

null 684 Dec 21, 2022
Solutions to LeetCode by Swift

LeetCode by Swift LeetCode Online Judge is a website containing many algorithm questions. Most of them are real interview questions of Google, Faceboo

Soap 4.5k Jan 5, 2023
Super lightweight DB written in Swift.

Use of value types is recommended and we define standard values, simple structured data, application state and etc. as struct or enum. Pencil makes us store these values more easily.

Naruki Chigira 88 Oct 22, 2022
YapDB is a collection/key/value store with a plugin architecture. It's built atop sqlite, for Swift & objective-c developers.

YapDatabase is a collection/key/value store and so much more. It's built atop sqlite, for Swift & Objective-C developers, targeting macOS, iOS, tvOS &

Yap Studios 3.3k Dec 29, 2022
CoreData/Realm sweet wrapper written in Swift

What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

Modo 2.1k Dec 9, 2022