↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.4 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 27 章 libpq - C 库

libpq 是 PostgreSQL 的 C 应用程序员接口。libpq 是一组库函数,客户端程序通过它们可以向 PostgreSQL 后端服务器传送查询并接收这些查询的结果。libpq 也是其他几个 PostgreSQL 应用接口的底层引擎, 包括 libpq++(C++)、libpgtcl(Tcl)、Perl 和 ECPG。因此,即使你使用的是上述某个软件包,libpq行为的某些方面对你来说也很重要。

本章末尾(第 27.14 节)包含一些简短程序,展示如何编写使用libpq的程序。源代码发行包的src/test/examples目录中还提供了几个完整的libpq应用程序示例。

使用libpq的客户端程序必须包含头文件libpq-fe.h,并且必须与libpq库链接。

27.1. 数据库连接控制函数 #

下面的函数用于建立与 PostgreSQL 后端服务器的连接。一个应用程序可以同时打开多个后端连接(原因之一是需要访问多个数据库)。每个连接由一个 PGconn 对象表示,该对象通过 PQconnectdb 或 PQsetdbLogin 函数获得。注意,除非内存太少以至于连 PGconn 对象都无法分配,这些函数总是返回一个非空的对象指针。在通过连接对象发送查询之前,应当调用 PQstatus 函数检查连接是否成功建立。

PQconnectdb

与数据库服务器建立一个新连接。

PGconn *PQconnectdb(const char *conninfo);

此函数使用从字符串 conninfo 中取得的参数打开一个新的数据库连接。与下面的 PQsetdbLogin 不同,该函数的参数集可以在不改变函数签名的情况下扩展,因此新的应用程序编程首选使用此函数(或其非阻塞版本 PQconnectStart 和 PQconnectPoll)。

传入的字符串可以为空以使用全部默认参数,也可以包含一个或多个用空白分隔的参数设置。每个参数设置的形式为 keyword = value。(要写入空值或包含空格的值,请用单引号包围,例如 keyword = 'a value'。值中的单引号和反斜杠必须用反斜杠转义,即 \' 和 \\。)等号两边的空格是可选的。

目前可识别的参数关键字有:

host

要连接的主机名。 如果它以斜杠开头,则表示使用 Unix 域通信而非 TCP/IP 通信;该值是存放套接字文件的目录名。默认连接到 /tmp 中的 Unix 域套接字。

hostaddr

要连接的主机的数字 IP 地址。其格式应为标准 IPv4 地址格式,例如 172.28.40.9。如果你的机器支持 IPv6,也可以使用 IPv6 地址。为此参数指定非空字符串时总是使用 TCP/IP 通信。

使用 hostaddr 代替 host 允许应用 程序避免主机名查找,这对于有时间约束的应用可能很重要。但 Kerberos 认证需要主机名。因此适用以下规则:如果只指定了 host 而没有指定 hostaddr,则进行主机名查找。如果只指定了 hostaddr 而没有指定 host,则 hostaddr 的值给出远程地址。使用 Kerberos 时,会进行反向名称查询以获得 Kerberos 所需的主机名。如果 host 和 hostaddr 都被指定,hostaddr 的值给出远程地址; host 的值被忽略;但使用 Kerberos 时例外,此时该值用于 Kerberos 认证。(注意,如果传给 libpq 的主机名不是位于 hostaddr 的机器的名称,认证很可能失败。)此外,在 $HOME/.pgpass 中标识连接使用的是 host 而不是 hostaddr。

既没有主机名也没有主机地址时,libpq 将使用本地 Unix 域套接字连接。

port

服务器主机上要连接的端口号,或 Unix 域连接的套接字文件名扩展。

dbname

数据库名。默认与用户名相同。

user

要以哪个 PostgreSQL 用户名连接。

password

如果服务器要求密码认证则使用的密码。

connect_timeout

连接的最大等待时间,以秒为单位(写成十进制整数字符串)。零或未指定表示无限等待。不建议使用小于 2 秒的超时。

options

要发送给服务器的命令行选项。

tty

忽略(以前此参数指定服务器调试输出发送到哪里)。

sslmode

此选项决定是否或以何种优先级与服务器协商 SSL 连接。共有四种模式:disable 只尝试非 SSL 加密连接;allow 协商时先尝试非 SSL 连接,失败后再尝试 SSL 连接;prefer(默认值)协商时先尝试 SSL 连接,失败后再尝试常规非 SSL 连接;require 只尝试 SSL 连接。

如果 PostgreSQL 编译时未包含 SSL 支持,使用选项 require 将导致错误,选项 allow 和 prefer 可以被接受,但 libpq 无法协商建立 SSL 连接。

requiressl

此选项已废弃,由 sslmode 设置取代。

设为 1 时,要求与服务器的 SSL 连接(等价于 sslmode require)。如果服务器不接受 SSL 连接,libpq 将拒绝连接。设为 0(默认值)时,libpq 将与服务器协商连接类型(等价于 sslmode prefer)。仅当 PostgreSQL 编译时包含 SSL 支持时此选项才可用。

service

用于附加参数的服务名。它指定 pg_service.conf 中一个持有附加连接参数的服务名。这样应用只需指定一个服务名,连接参数便可以集中维护。有关如何设置该文件,参见 PREFIX/share/pg_service.conf.sample。

如果任何参数未指定,则检查相应的环境变量(见 第 27.10 节)。如果环境变量也未设置,则使用内建默认值。

PQsetdbLogin

与数据库服务器建立一个新连接。

PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);

这是 PQconnectdb 的前身,带有一组固定参数。除缺失的参数总是取默认值外,功能相同。对任何一个要取默认值的固定参数,可写 NULL 或空字符串。

PQsetdb

与数据库服务器建立一个新连接。

PGconn *PQsetdb(char *pghost,
                char *pgport,
                char *pgoptions,
                char *pgtty,
                char *dbName);

这是一个宏,以空指针作为 login 和 pwd 参数调用 PQsetdbLogin。它只是为了与很老的程序保持向后兼容而保留。

PQconnectStart
PQconnectPoll

以非阻塞方式建立与数据库服务器的连接。

PGconn *PQconnectStart(const char *conninfo);
PostgresPollingStatusType PQconnectPoll(PGconn *conn);

这两个函数用于打开到数据库服务器的连接,同时应用程序的执行线程不会在远程 I/O 上阻塞。这种做法的意义在于,对 I/O 完成的等待可以发生在应用的主循环中,而不是在 PQconnectdb 内部,因此应用可以将此操作与其他活动并行管理。

数据库连接使用传给 PQconnectStart 的字符串 conninfo 中的参数建立。该字符串的格式与上面 PQconnectdb 中描述的相同。

只要满足若干限制条件,PQconnectStart 和 PQconnectPoll 都不会阻塞:

  • 恰当地使用 hostaddr 和 host 参数,确保不进行(正向)名称和反向名称查询。详情见上面 PQconnectdb 下对这些参数的说明。

  • 如果调用 PQtrace,确保要写入跟踪信息的流对象不会阻塞。

  • 在调用 PQconnectPoll 之前,确保套接字处于适当的状态,如下所述。

要开始一个非阻塞连接请求,调用 conn = PQconnectStart("connection_info_string")。如果 conn 为空,说明 libpq 无法分配新的 PGconn 结构。否则返回一个有效的 PGconn 指针(尽管它尚未表示一个有效的数据库连接)。从 PQconnectStart 返回后,调用 status = PQstatus(conn)。如果 status 等于 CONNECTION_BAD,则 PQconnectStart 失败。

如果 PQconnectStart 成功,下一阶段是轮询 libpq,使其继续进行连接序列。使用 PQsocket(conn) 获取数据库连接底层套接字的描述符。循环如下:如果 PQconnectPoll(conn) 上次返回 PGRES_POLLING_READING,则等待套接字可读(由 select()、poll() 或类似的系统函数指示),然后再次调用 PQconnectPoll(conn)。反之,如果 PQconnectPoll(conn) 上次返回 PGRES_POLLING_WRITING,则等待套接字可写,然后再次调用 PQconnectPoll(conn)。如果尚未调用过 PQconnectPoll(即刚调用完 PQconnectStart 之后),则视同它上次返回的是 PGRES_POLLING_WRITING。持续此循环,直到 PQconnectPoll(conn) 返回 PGRES_POLLING_FAILED(表示连接过程失败)或 PGRES_POLLING_OK(表示连接成功建立)为止。

在连接期间的任何时刻,都可以调用 PQstatus 检查连接状态。如果返回 CONNECTION_BAD,则连接过程已失败;如果返回 CONNECTION_OK,则连接已就绪。这两种状态同样可以从上面描述的 PQconnectPoll 的返回值中检测到。其他状态只在(且仅会在)异步连接过程中出现,它们指示连接过程的当前阶段,例如可用于向用户提供反馈。这些状态是:

CONNECTION_STARTED

等待建立连接。

CONNECTION_MADE

连接成功;等待发送。

CONNECTION_AWAITING_RESPONSE

等待来自服务器的响应。

CONNECTION_AUTH_OK

已通过认证;等待后端启动完成。

CONNECTION_SSL_STARTUP

正在协商 SSL 加密。

CONNECTION_SETENV

正在协商环境驱动的参数设置。

注意,尽管这些常量会保留(为了维护兼容性),应用程序绝不应依赖它们按特定顺序出现、依赖它们全都出现,或依赖状态总是这些已记录的值之一。应用程序可以这样做:

switch(PQstatus(conn))
{
    case CONNECTION_STARTED:
        feedback = "Connecting...";
        break;

    case CONNECTION_MADE:
        feedback = "Connected to server...";
        break;
.
.
.
    default:
        feedback = "Connecting...";
}

使用 PQconnectPoll 时会忽略 connect_timeout 连接参数;由应用负责判断是否已经耗时过长。除此之外,PQconnectStart 加上 PQconnectPoll 循环等价于 PQconnectdb。

注意,如果 PQconnectStart 返回非空指针,使用完毕后必须调用 PQfinish,以释放该结构和所有关联的内存块。即使连接尝试失败或被放弃,也必须这样做。

PQconndefaults

返回默认的连接选项。

PQconninfoOption *PQconndefaults(void);

typedef struct
{
    char   *keyword;   /* The keyword of the option */
    char   *envvar;    /* Fallback environment variable name */
    char   *compiled;  /* Fallback compiled in default value */
    char   *val;       /* Option's current value, or NULL */
    char   *label;     /* Label for field in connect dialog */
    char   *dispchar;  /* Character to display for this field
                          in a connect dialog. Values are:
                          ""        Display entered value as is
                          "*"       Password field - hide value
                          "D"       Debug option - don't show by default */
    int     dispsize;  /* Field size in characters for dialog */
} PQconninfoOption;

返回一个连接选项数组。它可用来确定 PQconnectdb 的所有可用选项及其当前默认值。返回值指向一个 PQconninfoOption 结构数组,该数组以一个 keyword 指针为空的条目结尾。注意,当前默认值( val 字段)依赖于环境变量和其他上下文。调用者必须将连接选项数据视为只读。

处理完选项数组后,将它传递给 PQconninfoFree 释放。如果不这样做,每次调用 PQconndefaults 都会泄漏少量内存。

PQfinish

关闭与服务器的连接,同时释放 PGconn 对象使用的内存。

void PQfinish(PGconn *conn);

注意,即使与服务器的连接尝试失败(由 PQstatus 指示),应用也应调用 PQfinish 释放 PGconn 对象使用的内存。在调用过 PQfinish 之后,不得再使用该 PGconn 指针。

PQreset

重置与服务器的通信通道。

void PQreset(PGconn *conn);

此函数将关闭与服务器的连接,并尝试使用先前使用的全部相同参数与同一服务器重新建立新连接。如果工作中的连接丢失,这可用于错误恢复。

PQresetStart
PQresetPoll

以非阻塞方式重置与服务器的通信通道。

int PQresetStart(PGconn *conn);
PostgresPollingStatusType PQresetPoll(PGconn *conn);

这些函数将关闭与服务器的连接,并尝试使用先前使用的全部相同参数与同一服务器重新建立新连接。如果工作中的连接丢失,这可用于错误恢复。它们与上面的 PQreset 的不同之处在于以非阻塞方式运作。这些函数受到与 PQconnectStart 和 PQconnectPoll 相同的限制。

要发起连接重置,调用 PQresetStart。如果返回 0,重置失败。如果返回 1,用与使用 PQconnectPoll 建立连接完全相同的方式,使用 PQresetPoll 对重置进行轮询。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。