SwiftAge 是 PostgresNIO 的一个扩展,它使得可以使用 PostgreSQL 的 Apache AGE 扩展来查询和解析图数据库的响应。
对于使用 Package.swift
文件的 Vapor 或其他项目,可以将 SwiftAge 作为依赖项添加。
dependencies: [
.package(url: "https://github.com/joshjacob/SwiftAge", from: "1.0.0-alpha.1"),
...
]
...
targets: [
.target(name: "MyTarget", dependencies: [
...
.product(name: "SwiftAge", package: "SwiftAge"),
])
]
对于在 Xcode 中开发的开发者,可以在目标的 “General” 选项卡中的 “Frameworks and Libraries” 部分添加依赖项。
SwiftAge 在 PostgresNIO 的 PostgresConnection
之上添加了查询扩展,因此连接的创建方式遵循 PostgresNIO 文档。
let connection = try await PostgresConnection.connect(
on: eventLoopGroup.next(),
configuration: config,
id: 1,
logger: logger
).get()
每个连接都需要运行命令来设置 AGE。 为此提供了一个便利的方法。
try await connection.setUpAge(logger: logger)
// will run:
// LOAD 'age';
// SET search_path = ag_catalog, "$user", public;
// "SELECT cast(typelem as INTEGER) FROM pg_type WHERE typname='_agtype'"
最后一个调用会获取 _agtype
的 Postgres OID,并配置 PostgresNIO 解码。
之后,就可以进行图查询了。
// with EventLoop...
let agRows = try connection.execCypher(
"SELECT * FROM cypher('test_graph_1', $$ MATCH (v:Person) RETURN v $$) as (v agtype);",
logger: logger).wait()
// ...or Async/Await
let agRows = try await connection.execCypher(
"SELECT * FROM cypher('test_graph_1', $$ MATCH (v:Person) RETURN v $$) as (v agtype);",
logger: logger)
返回的 CypherQueryResult
结构体包含类似于 PostgresQueryResult
的 PostgresQueryMetadata
数据,但 rows
字段是一个 AGValue
数组。 AGValue
类型可以是 Apache AGE 定义的标量类型之一,也可以是一个表示顶点、边或路径的结构体。
除了使用 execCypher()
调用之外,您还可以使用常规的 PostgresNIO 方法进行查询和获取结果。 SwiftAge 将在 AGValueWrapper
中返回 agtype
数据,其值可以强制转换为适当的类型。
let rows = try await connection.query(
"SELECT * FROM cypher('test_graph_1', $$ MATCH (v:Person) RETURN v $$) as (v agtype);",
logger: logger)
for try await (agValue) in rows.decode((AGValueWrapper).self, context: .default) {
if let vertex = agValue.value as? Vertex {
print(vertex.label)
}
}
AGValueWrapper
结构体也可以用于正确编码 Postgres 绑定参数。
let params: Dictionary<String,AGValue> = ["newName": "Little'Bobby'Tables"]
let paramsWrapper: AGValueWrapper = AGValueWrapper.init(value: params)
let agRows = try await connection.execCypher(
"SELECT * FROM cypher('test_graph_1', $$ CREATE (v:Person {name: $newName}) RETURN v $$, \( paramsWrapper )) as (v agtype);",
logger: logger)
在 PostgresNIO 和 SwiftAge 之间,这将导致查询被转换为
SELECT * FROM cypher('test_graph_1', $$ CREATE (v:Person {name: $newName}) RETURN v $$, $1) as (v agtype);
并且 $1
参数是 Dictionary 的 jsonb 编码。
请参阅 SwiftAgeExamples 获取更多示例。