适配器
@dataplan/pg
可以使用任何客户端与您的数据库通信,只要存在合适的适配器。每个适配器都为 @dataplan/pg
提供了一套基本的功能。您可以将多个适配器与同一个模式一起使用。
在规划时,当一个步骤确定需要 PgExecutor 与数据库通信时,会调用 PgExecutor 的 context()
方法。此方法应返回一个步骤,该步骤描述一个包含 withPgClient
和(可选)pgSettings
条目的对象。在大多数情况下,这些条目将来自 GraphQL 上下文。定义 PgExecutors 上下文的常见模式是
import { context, object } from "grafast";
import { PgExecutor } from "@dataplan/pg";
const executor = new PgExecutor({
name: "default",
context() {
return object({
withPgClient: context().get("withPgClient"),
pgSettings: context().get("pgSettings"),
});
},
});
在这里,我们通过从 context()
步骤获取对 GraphQL 上下文的引用,然后提取 withPgClient
和 pgSettings
键来构建 PgExecutor 上下文。请注意,这些键的命名并不重要,您需要为每个适配器使用不同的键名。
在运行时,我们必须确保这些属性在 GraphQL 上下文中提供,以便 PgExecutor 可以运行。适配器负责提供合适的 withPgClient
回调,而用户则可以选择是否提供 pgSettings
对象。
withPgClient
每个适配器都必须提供一种构建或检索 withPgClient
函数的方法(请参阅适配器文档)。此函数通常存储在 GraphQL 上下文中,并在运行时由资源(通过执行器)调用,以与数据库通信。该函数接受两个参数(pgSettings
和 callback
),并且它
- 创建或检索与数据库连接的
PgClient
(见下文), - 如果设置,则应用
pgSettings
对象中的任何设置(如果需要,则创建事务), - 调用回调,并将客户端作为唯一参数传递,
- 成功后释放客户端(如果需要,则提交事务)并返回回调的结果,
- 错误时释放客户端(如果需要,则回滚事务)并引发错误。
PgClient
每个适配器都能够生成符合 PgClient
的对象。这意味着它至少将具有以下方法
query(opts)
- 使用占位符值opts.values
(数组)针对数据库运行 SQL 查询opts.text
(字符串),并返回结果withTransaction(callback)
- 1. 开始一个事务,2. 调用并等待回调函数(传递客户端),3. 发生错误时回滚事务;成功时提交事务并返回结果
请注意,withTransaction
可以嵌套使用,在这种情况下,通常使用保存点来实现子事务。
根据适配器,PgClient 可能具有其他可用的方法和属性 - 这是在 Grafast 计划中使用 ORM 功能的一种常见方法。
pgSettings
pgSettings
是一个可选的字符串-字符串映射。如果设置,这些值将作为临时会话变量设置在数据库连接中。这在使用 PostgreSQL 的行级安全时通常很有用。如果您不使用行级安全,您可能不需要它。
PgSubscriber
PgSubscriber 可用于利用 PostgreSQL 数据库的 LISTEN/NOTIFY 功能,为您的模式提供实时(发布/订阅)功能。并非所有适配器都支持 PgSubscriber,并且它们各自都有自己的构建方式。
PgSubscriber
实例通常从 GraphQL 上下文(例如,通过 context().get('pgSubscriber')
)引用,然后通过 listen()
步骤使用。PgSubscriber 具有标准的监听方法 subscribe(topic)
,它返回一个异步可迭代对象,从主题中生成事件。可以通过终止异步可迭代对象来终止订阅。
@dataplan/pg/adaptors/pg
此适配器使用 pg
模块 与数据库通信。
createWithPgClient
要创建适合在运行时使用的 withPgClient
函数,可以调用 createWithPgClient
,并传递一个包含以下属性的对象
pool
- 一个pg.Pool
实例connectionString
- 一个 PostgreSQL 连接字符串 (postgres://user:pass@host/dbname
),用于创建连接池poolConfig
-pg.Pool
的配置选项(不包括connectionString
),在使用connectionString
内部创建连接池时使用
必须设置 pool
或 connectionString
中的其中一个,其他所有选项都是可选的。
new PgSubscriber(pool)
使用给定的 pg.Pool
实例创建一个新的 PgSubscriber 实例,准备存储到 GraphQL 上下文中。
示例
import * as pg from "pg";
import { createWithPgClient, PgSubscriber } from "@dataplan/pg/adaptors/pg";
const pool = new pg.Pool({ connectionString: "postgres:///pagila" });
const withPgClient = createWithPgClient({ pool });
const pgSubscriber = new PgSubscriber(pool);
const graphqlContext = { withPgClient, pgSubscriber };
// await grafast({ query: `...`, contextValue: graphqlContext });
编写自己的适配器
待办事项:记录此内容。