🐘 非阻塞、事件驱动的 Swift PostgreSQL 客户端,构建于 SwiftNIO 之上。
特性
PostgresConnection
,允许您连接、授权、查询 PostgreSQL 服务器并从中检索结果PostgresClient
,用于池化和管理连接Network.framework
查看 PostgresNIO API 文档,详细了解所有类、结构体、协议等。
对示例感兴趣?我们在 Snippets 文件夹中准备了一个简单的 Birthday example。
将 PostgresNIO
作为依赖项添加到您的 Package.swift
dependencies: [
.package(url: "https://github.com/vapor/postgres-nio.git", from: "1.21.0"),
...
]
将 PostgresNIO
添加到您想要在其中使用的目标
targets: [
.target(name: "MyFancyTarget", dependencies: [
.product(name: "PostgresNIO", package: "postgres-nio"),
])
]
要创建一个 PostgresClient
,它为您池化连接,首先创建一个配置对象
import PostgresNIO
let config = PostgresClient.Configuration(
host: "localhost",
port: 5432,
username: "my_username",
password: "my_password",
database: "my_database",
tls: .disable
)
接下来,您可以使用它创建客户端
let client = PostgresClient(configuration: config)
创建客户端后,您必须 run()
它
await withTaskGroup(of: Void.self) { taskGroup in
taskGroup.addTask {
await client.run() // !important
}
// You can use the client while the `client.run()` method is not cancelled.
// To shutdown the client, cancel its run method, by cancelling the taskGroup.
taskGroup.cancelAll()
}
一旦客户端运行,就可以将查询发送到服务器。这很简单
let rows = try await client.query("SELECT id, username, birthday FROM users")
查询将返回一个 PostgresRowSequence
,它是一个 PostgresRow
的 AsyncSequence。可以逐个迭代行
for try await row in rows {
// do something with the row
}
但是,在大多数情况下,将行的字段请求为一组 Swift 类型要容易得多
for try await (id, username, birthday) in rows.decode((Int, String, Date).self) {
// do something with the datatypes.
}
类型必须实现 PostgresDecodable
协议才能从行中解码。PostgresNIO 为大多数 Swift 内置类型以及 Foundation 提供的一些类型提供了默认实现
Bool
Bytes
、Data
、ByteBuffer
Date
UInt8
、Int16
、Int32
、Int64
、Int
Float
、Double
String
UUID
也支持将参数化查询发送到数据库(以最酷的方式)
let id = 1
let username = "fancyuser"
let birthday = Date()
try await client.query("""
INSERT INTO users (id, username, birthday) VALUES (\(id), \(username), \(birthday))
""",
logger: logger
)
虽然乍一看这看起来像是 SQL 注入 😱 的经典案例,但 PostgresNIO 的 API 确保了这种用法的安全性。query(_:logger:)
方法的第一个参数不是普通的 String
,而是一个 PostgresQuery
,它实现了 Swift 的 ExpressibleByStringInterpolation
协议。PostgresNIO 使用提供的字符串的字面部分作为 SQL 查询,并将每个插值替换为参数绑定。只有实现了 PostgresEncodable
协议的值才能以这种方式进行插值。与 PostgresDecodable
一样,PostgresNIO 为大多数常见类型提供了默认实现。
某些查询不会从服务器接收任何行(最常见的是没有 RETURNING
子句的 INSERT
、UPDATE
和 DELETE
查询,更不用说大多数 DDL 查询)。为了支持这一点,query(_:logger:)
方法被标记为 @discardableResult
,这样如果未使用返回值,编译器就不会发出警告。
有关安全流程的详细信息,请参阅 SECURITY.md。