ITADN
vapor/postgres-nio
vapor/postgres-nio · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

PostgresNIO

Documentation MIT License Continuous Integration Swift 6.0+ SSWG Incubation Level: Graduated

🐘 基于 SwiftNIO 构建的用于 PostgreSQL 的非阻塞、事件驱动 Swift 客户端。

特性:

  • 一个 PostgresConnection,允许您连接、授权、查询并从 PostgreSQL 服务器获取结果
  • 一个 PostgresClient,用于池化和连接管理
  • 支持背压的 async/await 接口
  • Swift 基本类型与 Postgres 线格式之间的自动转换
  • 与 Swift 服务器生态系统集成,包括使用 SwiftLogServiceLifecycle
  • 设计为在所有受支持的平台上高效运行(在 Linux 和 Darwin 系统上进行了广泛测试)
  • 在可用时支持 Network.framework(例如在 Apple 平台上)
  • 支持在 Unix 域套接字上运行

API 文档

查看 PostgresNIO API 文档,以详细了解所有类、结构体、协议等。

入门

想要一个示例?我们在 Snippets 文件夹中准备了一个简单的 生日示例

添加依赖项

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
}

从 PostgresRow 解码

然而,在大多数情况下,将行的字段请求为一组 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 子句的 INSERTUPDATEDELETE 查询,更不用说大多数 DDL 查询了)。为了支持这一点,query(_:logger:) 方法被标记为 @discardableResult,以便在返回值未被使用时,编译器不会发出警告。

安全

有关安全流程的详细信息,请参阅 SECURITY.md