跳至主要内容

适配器

@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 上下文的引用,然后提取 withPgClientpgSettings 键来构建 PgExecutor 上下文。请注意,这些键的命名并不重要,您需要为每个适配器使用不同的键名。

在运行时,我们必须确保这些属性在 GraphQL 上下文中提供,以便 PgExecutor 可以运行。适配器负责提供合适的 withPgClient 回调,而用户则可以选择是否提供 pgSettings 对象。

withPgClient

每个适配器都必须提供一种构建或检索 withPgClient 函数的方法(请参阅适配器文档)。此函数通常存储在 GraphQL 上下文中,并在运行时由资源(通过执行器)调用,以与数据库通信。该函数接受两个参数(pgSettingscallback),并且它

  1. 创建或检索与数据库连接的 PgClient(见下文),
  2. 如果设置,则应用 pgSettings 对象中的任何设置(如果需要,则创建事务),
  3. 调用回调,并将客户端作为唯一参数传递,
  4. 成功后释放客户端(如果需要,则提交事务)并返回回调的结果,
  5. 错误时释放客户端(如果需要,则回滚事务)并引发错误。

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 内部创建连接池时使用

必须设置 poolconnectionString 中的其中一个,其他所有选项都是可选的。

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 });

编写自己的适配器

待办事项:记录此内容。