34.2. 连接状态函数#
这些函数可用于查询现有数据库连接对象的连接状态。
提示
libpq应用程序员应注意维护PGconn抽象。使用下面描述的访问器函数来获取PGconn的内容。不建议使用libpq-int.h引用内部PGconn字段,因为它们在将来可能会发生变化。
以下函数返回在连接时建立的参数值。这些值在连接的生命周期内是固定的。如果使用多主机连接字符串,则在使用同一PGconn对象建立新连接时,PQhost、PQport和PQpass的值可能会发生变化。其他值在PGconn对象的生命周期内是固定的。
PQdb#返回连接的数据库名称。
char *PQdb(const PGconn *conn);
PQuser#返回连接的用户名。
char *PQuser(const PGconn *conn);
PQpass#返回连接的密码。
char *PQpass(const PGconn *conn);
PQpass将返回连接参数中指定的密码,或者如果没有密码且密码是从 密码文件 中获取的,它将返回该密码。在后一种情况下,如果在连接参数中指定了多个主机,则在建立连接之前无法依赖PQpass的结果。可以使用函数PQstatus检查连接的状态。PQhost#返回活动连接的服务器主机名。这可以是主机名、IP 地址或目录路径(如果连接是通过 Unix 套接字进行的)。(路径情况可以区分,因为它始终是绝对路径,以
/开头。)char *PQhost(const PGconn *conn);
如果连接参数同时指定了
host和hostaddr,那么PQhost将返回host信息。如果只指定了hostaddr,那么将返回该信息。如果在连接参数中指定了多个主机,PQhost将返回实际连接到的主机。PQhost返回NULL,如果conn参数为NULL。否则,如果产生主机信息时出错(可能是在连接尚未完全建立或出现错误时),它将返回一个空字符串。如果在连接参数中指定了多个主机,在连接建立之前无法依赖
PQhost的结果。可以使用函数PQstatus检查连接状态。PQhostaddr#返回活动连接的服务器 IP 地址。这可以是主机名解析到的地址,也可以是通过
hostaddr参数提供的 IP 地址。char *PQhostaddr(const PGconn *conn);
PQhostaddr返回NULL,如果conn参数为NULL。否则,如果产生主机信息时出错(可能是在连接尚未完全建立或出现错误时),它将返回一个空字符串。PQport#返回活动连接的端口。
char *PQport(const PGconn *conn);
如果在连接参数中指定了多个端口,
PQport将返回实际连接到的端口。PQport返回NULL,如果conn参数为NULL。否则,如果产生端口信息时出错(可能是在连接尚未完全建立或出现错误时),它将返回一个空字符串。如果在连接参数中指定了多个端口,在连接建立之前无法依赖
PQport的结果。可以使用函数PQstatus检查连接状态。PQtty#此函数不再执行任何操作,但保留此函数是为了向后兼容。此函数始终返回一个空字符串,如果
conn参数为NULL,则返回NULL。char *PQtty(const PGconn *conn);
PQoptions#返回连接请求中传递的命令行选项。
char *PQoptions(const PGconn *conn);
以下函数返回状态数据,这些数据会在对PGconn对象执行操作时发生更改。
PQstatus#返回连接的状态。
ConnStatusType PQstatus(const PGconn *conn);
状态可以是多个值之一。但是,只有两个值出现在异步连接过程之外:
CONNECTION_OK和CONNECTION_BAD。与数据库的良好连接具有CONNECTION_OK状态。失败的连接尝试由状态CONNECTION_BAD发出信号。通常,一个好的状态将保持不变,直到PQfinish,但是通信故障可能会导致状态过早地更改为CONNECTION_BAD。在这种情况下,应用程序可以通过调用PQreset来尝试恢复。请参阅
PQconnectStartParams、PQconnectStart和PQconnectPoll的条目,了解可能返回的其他状态代码。PQtransactionStatus#返回服务器当前的事务中状态。
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_version、server_encoding、client_encoding、application_name、default_transaction_read_only、in_hot_standby、is_superuser、session_authorization、DateStyle、IntervalStyle、TimeZone、integer_datetimes和standard_conforming_strings。(server_encoding、TimeZone和integer_datetimes未在 8.0 之前的版本中报告;standard_conforming_strings未在 8.1 之前的版本中报告;IntervalStyle未在 8.4 之前的版本中报告;application_name未在 9.0 之前的版本中报告;default_transaction_read_only和in_hot_standby未在 14 之前的版本中报告。)请注意,server_version、server_encoding和integer_datetimes在启动后无法更改。如果没有报告
standard_conforming_strings的值,应用程序可以假定它是off,即反斜杠在字符串字面量中被视为转义符。此外,此参数的存在可以被视为接受转义字符串语法(E'...')的标志。虽然返回的指针声明为
const,但它实际上指向与PGconn结构关联的可变存储。假设指针在查询中保持有效是不明智的。PQprotocolVersion#查询正在使用的前端/后端协议。
int PQprotocolVersion(const PGconn *conn);
应用程序可能希望使用此函数来确定是否支持某些功能。目前,可能的值为 3(3.0 协议)或零(连接不良)。协议版本在连接启动完成后不会更改,但理论上它可以在连接重置期间更改。3.0 协议受 PostgreSQL 服务器版本 7.4 及更高版本支持。
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#获取与服务器的连接套接字的文件描述符号。有效描述符将大于或等于 0;结果为 -1 表示当前未打开服务器连接。(这在正常操作期间不会改变,但在连接设置或重置期间可能会改变。)
int PQsocket(const PGconn *conn);
PQbackendPID#int PQbackendPID(const PGconn *conn);
后端 对于调试目的和与
NOTIFY消息(其中包括通知后端进程的 )进行比较非常有用。请注意, 属于在数据库服务器主机上执行的进程,而不是本地主机!PQconnectionNeedsPassword#如果连接认证方法需要密码,但没有可用密码,则返回 true (1)。如果没有,则返回 false (0)。
int PQconnectionNeedsPassword(const PGconn *conn);
在连接尝试失败后,可以应用此函数来决定是否提示用户输入密码。
PQconnectionUsedPassword#如果连接认证方法使用密码,则返回 true (1)。如果没有,则返回 false (0)。
int PQconnectionUsedPassword(const PGconn *conn);
在连接尝试失败或成功后,可以应用此函数来检测服务器是否要求输入密码。
PQconnectionUsedGSSAPI#如果连接认证方法使用 GSSAPI,则返回 true (1)。如果没有,则返回 false (0)。
int PQconnectionUsedGSSAPI(const PGconn *conn);
可以应用此函数来检测连接是否已通过 GSSAPI 进行认证。
以下函数返回与 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 库和连接类型而异。如果连接不使用 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”。
作为特殊情况,
library属性可以在不通过 NULL 作为conn参数的情况下,在没有连接的情况下进行查询。结果将是默认 SSL 库名称,或者如果在没有 SSL 支持的情况下编译 libpq,则为 NULL。(在 PostgreSQL 15 版本之前,将 NULL 作为conn参数传递始终会导致 NULL。需要区分此情况的较新和较旧实现的客户端程序可以检查LIBPQ_HAS_SSL_LIBRARY_DETECTION特性宏。)PQsslAttributeNames#返回可在
PQsslAttribute()中使用的 SSL 属性名称数组。该数组以 NULL 指针结尾。const char * const * PQsslAttributeNames(const PGconn *conn);
如果
conn为 NULL,则返回可用于默认 SSL 库的属性,或者如果在没有 SSL 支持的情况下编译 libpq,则返回空列表。如果conn不为 NULL,则返回可用于连接中使用的 SSL 库的属性,或者如果连接未加密,则返回空列表。PQsslStruct#返回一个指向描述连接的 SSL 实现特定对象的指针。如果连接未加密或连接的 SSL 实现中不可用请求的类型对象,则返回 NULL。
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#返回连接中使用的 SSL 结构,如果未使用 SSL,则返回 NULL。
void *PQgetssl(const PGconn *conn);
此函数等效于
PQsslStruct(conn, "OpenSSL")。它不应在新的应用程序中使用,因为返回的结构特定于 OpenSSL,并且如果使用其他 实现,则不可用。要检查连接是否使用 SSL,请调用PQsslInUse,有关连接的更多详细信息,请使用PQsslAttribute。
