34.2. 连接状态功能

这些功能可用于询问现有数据库连接对象的状态。

Tip

libpq 应用程序程序员应小心维护PGconn抽象。使用下面描述的访问器函数获取PGconn的内容。不建议使用libpq-int.h引用内部PGconn字段,因为它们将来可能会更改。

以下函数返回在连接时构建的参数值。这些值在连接寿命内是固定的。如果使用多主机连接字符串,则如果使用相同的PGconn对象构建新连接,则PQhostPQportPQpass的值可以更改。在PGconn对象的生存期内,其他值是固定的。

  • PQdb
    • 返回连接的数据库名称。
char *PQdb(const PGconn *conn);
  • PQuser
    • 返回连接的用户名。
char *PQuser(const PGconn *conn);
  • PQpass
    • 返回连接的密码。
char *PQpass(const PGconn *conn);

PQpass将返回连接参数中指定的密码,或者如果没有密码且密码是从password file获得的,它将返回该密码。在后一种情况下,如果在连接参数中指定了多个主机,则在构建连接之前不可能依靠PQpass的结果。可以使用功能PQstatus检查连接状态。

  • PQhost
    • 返回活动连接的服务器主机名。如果通过 Unix 套接字进行连接,则可以是主机名,IP 地址或目录路径。 (可以区分路径大小写,因为它始终是从/开始的绝对路径.)
char *PQhost(const PGconn *conn);

如果连接参数同时指定了hosthostaddr,则PQhost将返回host信息。如果仅指定hostaddr,则返回该值。如果在连接参数中指定了多个主机,则PQhost返回实际连接的主机。

如果* conn *参数为NULL,则PQhost返回NULL。否则,如果生成主机信息时发生错误(可能是连接尚未完全构建或发生错误),则它将返回一个空字符串。

如果在连接参数中指定了多个主机,则在构建连接之前不可能依靠PQhost的结果。可以使用功能PQstatus检查连接状态。

  • PQport
    • 返回活动连接的端口。
char *PQport(const PGconn *conn);

如果在连接参数中指定了多个端口,则PQport返回实际连接到的端口。

如果* conn *参数为NULL,则PQport返回NULL。否则,如果在生成端口信息时发生错误(可能是连接尚未完全构建或发生错误),则它将返回一个空字符串。

如果在连接参数中指定了多个端口,则在构建连接之前不可能依靠PQport的结果。可以使用功能PQstatus检查连接状态。

  • PQtty
    • 返回连接的调试 TTY。 (这已经过时了,因为服务器不再关注 TTY 设置,但是保留该功能是为了向后兼容.)
char *PQtty(const PGconn *conn);
  • PQoptions
    • 返回在连接请求中传递的命令行选项。
char *PQoptions(const PGconn *conn);

以下函数返回状态数据,这些状态数据可以随着在PGconn对象上执行操作而改变。

  • PQstatus
    • 返回连接状态。
ConnStatusType PQstatus(const PGconn *conn);

状态可以是多个值之一。但是,在异步连接过程之外只能看到其中两个:CONNECTION_OKCONNECTION_BAD。与数据库的良好连接状态为CONNECTION_OK。状态CONNECTION_BAD指示连接尝试失败。通常,OK 状态将一直保持到PQfinish,但是通信失败可能会导致状态过早变为CONNECTION_BAD。在这种情况下,应用程序可以尝试通过调用PQreset进行恢复。

有关可能返回的其他状态代码,请参见PQconnectStartParamsPQconnectStartPQconnectPoll的条目。

  • PQtransactionStatus
    • 返回服务器的当前 Transaction 中状态。
PGTransactionStatusType PQtransactionStatus(const PGconn *conn);

状态可以是PQTRANS_IDLE(当前处于空闲状态),PQTRANS_ACTIVE(命令正在执行中),PQTRANS_INTRANS(在有效事务块中为空闲)或PQTRANS_INERROR(在失败事务块中为空闲)。如果连接不良,则报告PQTRANS_UNKNOWN。仅当查询已发送到服务器但尚未完成时才报告PQTRANS_ACTIVE

  • PQparameterStatus
    • 查找服务器的当前参数设置。
const char *PQparameterStatus(const PGconn *conn, const char *paramName);

服务器会在连接启动时或每当其值更改时自动报告某些参数值。 PQparameterStatus可用于询问这些设置。如果已知,则返回参数的当前值;如果未知,则返回NULL

从当前版本开始报告的参数包括server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 (8.0 之前的版本未报告server_encodingTimeZoneinteger_datetimes; 8.1 之前的版本未报告standard_conforming_strings; 8.4 之前的版本未报告IntervalStyle; 9.0 之前的版本未报告application_name.)请注意server_versionserver_encodinginteger_datetimes启动后无法更改。

3.0 协议之前的服务器不报告参数设置,但 libpq 包括无论如何都要获取server_versionclient_encoding的值的逻辑。鼓励应用程序使用PQparameterStatus而不是* ad *代码来确定这些值。 (但是请注意,在 3.0 之前的 Connecting,PQparameterStatus不会反映在连接启动后通过SET更改client_encoding的情况.)对于server_version,另请参见PQserverVersion,它以易于比较的数字形式返回信息。

如果未报告standard_conforming_strings的值,则应用程序可以假定其为off,即,反斜杠被视为字符串 Literals 中的转义符。同样,此参数的存在可以视为接受转义字符串语法(E'...')的指示。

尽管返回的指针被声明为const,但实际上它指向与PGconn结构关联的可变存储。假设指针将在所有查询中保持有效是不明智的。

  • PQprotocolVersion
    • 询问正在使用的前端/后端协议。
int PQprotocolVersion(const PGconn *conn);

应用程序可能希望使用此功能来确定是否支持某些功能。当前,可能的值为 2(2.0 协议),3(3.0 协议)或零(连接不良)。协议版本在连接启动完成后将不会更改,但是理论上在连接重置期间可能会更改。与 PostgreSQL 7.4 或更高版本的服务器通信时,通常会使用 3.0 协议。 7.4 之前的服务器仅支持协议 2.0. (Protocol 1.0 已过时,libpq 不支持.)

  • PQserverVersion
    • 返回表示服务器版本的整数。
int PQserverVersion(const PGconn *conn);

应用程序可能使用此功能来确定它们连接到的数据库服务器的版本。通过将服务器的主要版本号乘以 10000 并加上次要版本号来形成结果。例如,版本 10.1 将返回为 100001,版本 11.0 将返回为 110000.如果连接不良,则返回零。

在主要版本 10 之前,PostgreSQL 使用三部分的版本号,其中前两个部分一起代表主要版本。对于这些版本,PQserverVersion的每个部分使用两位数字;例如,版本 9.1.5 将返回为 90105,版本 9.2.0 将返回为 90200.

因此,为了确定功能兼容性,应用程序应将PQserverVersion的结果除以 100 而不是 10000,以确定逻辑主版本号。在所有发行版系列中,次要发行版(错误修复发行版)之间只有后两位不同。

  • PQerrorMessage
    • 返回由连接操作最近生成的错误消息。
char *PQerrorMessage(const PGconn *conn);

如果它们失败,几乎所有的 libpq 函数都会为PQerrorMessage设置一条消息。请注意,按照 libpq 约定,非空PQerrorMessage结果可以包含多行,并且将包含尾随换行符。调用方不应直接释放结果。当关联的PGconn句柄传递给PQfinish时,它将被释放。不应期望结果字符串在PGconn结构上的所有操作之间保持相同。

  • PQsocket
    • 获取服务器连接套接字的文件 Descriptors 号。有效的 Descriptors 将大于或等于 0;否则为 0.结果为-1 表示当前没有打开服务器连接。 (这在正常操作期间不会更改,但是在连接设置或重置期间可能会更改.)
int PQsocket(const PGconn *conn);
  • PQbackendPID
    • 返回处理此连接的后端进程的进程 ID(PID)
int PQbackendPID(const PGconn *conn);

后端 PID 对于调试目的以及与NOTIFY消息(包括通知后端进程的 PID)进行比较很有用。请注意,PID 属于在数据库服务器主机而不是 localhost 上执行的进程!

  • PQconnectionNeedsPassword
    • 如果连接身份验证方法需要密码,但没有密码,则返回 true(1)。如果不是,则返回 false(0)。
int PQconnectionNeedsPassword(const PGconn *conn);

在尝试失败的连接以确定是否提示用户 Importing 密码后,可以应用此功能。

  • PQconnectionUsedPassword
    • 如果连接身份验证方法使用密码,则返回 true(1)。如果不是,则返回 false(0)。
int PQconnectionUsedPassword(const PGconn *conn);

在尝试失败或成功的连接以检测服务器是否需要密码之后,可以应用此功能。

以下函数返回与 SSL 相关的信息。构建连接后,此信息通常不会更改。

  • PQsslInUse
    • 如果连接使用 SSL,则返回 true(1),否则返回 false(0)。
int PQsslInUse(const PGconn *conn);
  • PQsslAttribute
    • 返回有关连接的 SSL 相关信息。
const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);

可用属性的列表取决于所使用的 SSL 库和连接类型而有所不同。如果属性不可用,则返回 NULL。

通常可以使用以下属性:

  • library

    • 正在使用的 SSL 实现的名称。 (当前仅实现"OpenSSL")

    • protocol

      • 正在使用 SSL/TLS 版本。通用值为"TLSv1""TLSv1.1""TLSv1.2",但是如果使用其他协议,则实现可能会返回其他字符串。
    • key_bits

      • 加密算法使用的密钥位数。
    • cipher

      • 所用密码套件的简称,例如"DHE-RSA-DES-CBC3-SHA"。这些名称特定于每个 SSL 实现。
    • compression

      • 如果使用 SSL 压缩,则返回压缩算法的名称;如果使用压缩,但算法未知,则返回“ on”。如果未使用压缩,则返回“ off”。
  • PQsslAttributeNames

    • 返回可用的 SSL 属性名称数组。该数组由 NULL 指针终止。
const char * const * PQsslAttributeNames(const PGconn *conn);
  • PQsslStruct
    • 返回一个指针,该指针指向描述连接的特定于 SSL 实现的对象。
void *PQsslStruct(const PGconn *conn, const char *struct_name);

可用的结构取决于所使用的 SSL 实现。对于 OpenSSL,有一个名称为“ OpenSSL”的结构,它返回一个指向 OpenSSL SSL结构的指针。要使用此功能,可以使用以下几行代码:

#include <libpq-fe.h>
#include <openssl/ssl.h>

...

    SSL *ssl;

    dbconn = PQconnectdb(...);
    ...

    ssl = PQsslStruct(dbconn, "OpenSSL");
    if (ssl)
    {
        /* use OpenSSL functions to access ssl */
    }

此结构可用于验证加密级别,检查服务器证书等。有关此结构的信息,请参考 OpenSSL 文档。

  • PQgetssl
    • 返回 Connecting 使用的 SSL 结构;如果未使用 SSL,则返回 null。
void *PQgetssl(const PGconn *conn);

此功能等效于PQsslStruct(conn, "OpenSSL")。不应在新应用程序中使用它,因为返回的结构是 OpenSSL 特有的,如果使用其他 SSL 实现,则该结构将不可用。要检查连接是否使用 SSL,请调用PQsslInUse,有关该连接的更多详细信息,请使用PQsslAttribute