31.2. 连接状态函数

这些函数可以用于询问现存数据库连接对象的状态。

提示: libpq应用程序员应该仔细维护PGconn结构。 使用下面的访问函数来获取PGconn的内容。不建议使用libpq-int.h 引用PGconn内部的字段,因为这些字段在今后可能被改变。

下面的函数返回连接建立时的参数值。这些参数在PGconn对象的生命期期间是固定的。

PQdb

返回连接的数据库名。

char *PQdb(const PGconn *conn);

PQuser

返回连接的用户名。

char *PQuser(const PGconn *conn);

PQpass

返回连接的口令。

char *PQpass(const PGconn *conn);

PQhost

返回连接的服务器主机名。

char *PQhost(const PGconn *conn);

PQport

返回连接的端口号。

char *PQport(const PGconn *conn);

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

返回服务器的当前事务内状态。

PGTransactionStatusType PQtransactionStatus(const PGconn *conn);

状态可以是PQTRANS_IDLE(当前空闲),PQTRANS_ACTIVE (正在处理一个命令),PQTRANS_INTRANS(空闲,在一个合法的事务块内), 或者PQTRANS_INERROR(空闲,在一个失败的事务块内)。如果连接有问题, 则返回PQTRANS_UNKNOWN。只有在一个查询发送给了服务器并且还没有完成的时候才返回 PQTRANS_ACTIVE

小心

当使用参数autocommit设置为关闭的PostgreSQL 7.3服务器时, PQtransactionStatus将给出不正确的结果。服务器端自动提交特性已经废弃了, 并且在后来的服务器版本中不再存在。

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 hoc 代码来检测这些值。(不过要注意,在3.0之前的连接协议里,启动后通过SET 改变了client_encoding将不会被PQparameterStatus反映出来。) 对于server_version,又见PQserverVersion, 它返回数值形式,更容易进行比较。

如果没有为standard_conforming_strings报告数值,应用可以假设它是off, 也就是说,在字符串文本里,把反斜杠当做转义。同样,如果出现了这个参数, 就可以当作一个指示,表示接受转义字符串(E'...')的语法。

尽管返回的指针声明为const,它实际上指向一个和PGconn 结构关联的可变存储区。因此假设这个指针跨查询保持有效是不明智的。

PQprotocolVersion

查询使用的前/后端协议。

int PQprotocolVersion(const PGconn *conn);

应用可能希望使用这个函数来判断某些特性是否被支持。目前,可能的数值是2 (2.0协议),3(3.0协议)或0(连接错误)。在连接启动完成之后,这个数值将不会改变, 但是在连接重置的过程中,理论上是可能改变的。在与PostgreSQL 7.4 或更高版本沟通时,通常使用3.0协议;7.4以前的服务器只支持协议2.0。 (协议1.0过时了,不被libpq支持。)

PQserverVersion

返回一个整数,代表后端版本。

int PQserverVersion(const PGconn *conn);

应用可以使用这个函数判断它们连接的数据库服务器的版本。数字是通过把主、 次及版本号转换成两位十进制数并且把它们连接在一起组成的。例如, 版本8.1.5将被返回80105,版本8.2将被返回80200(前导零没有显示)。 如果连接失败,则返回零。

PQerrorMessage

返回连接中操作产生的最近的错误消息。

char *PQerrorMessage(const PGconn *conn);

几乎所有libpq函数在失败时都会为PQerrorMessage 设置一个信息。注意,libpq的传统是,一个非空的 PQerrorMessage结果会由多行组成,并且将包含一个结尾的新行。 调用者不应该直接释放结果。结果的释放是在将PGconn句柄传递给 PQfinish的时候自动进行的。我们不能假设在不同的PGconn 结构操作中,结果字串都是一样的。

PQsocket

获取与服务器连接的套接字的文件描述符编号。一个有效的描述符应该是大于或等于0; 结果为-1表示当前没有与服务器的连接打开。(在正常的操作中,这个结果不会改变, 但是可能在连接启动或者重置的过程中变化。)

int PQsocket(const PGconn *conn);

PQbackendPID

返回后端进程处理此连接的进程号ID (PID)

int PQbackendPID(const PGconn *conn);

这个后端PID在调试和对比NOTIFY 信息(包括发出通知的后端进程的PID)时很有用。 注意该PID属于运行数据库服务器主机的进程, 而不是本地主机!

PQconnectionNeedsPassword

如果连接的认证方法需要一个密码则返回true (1),但是没有可用的。 如果没有则返回false (0)。

int PQconnectionNeedsPassword(const PGconn *conn);

此功能可用于连接尝试失败后决定是否提示用户输入密码。

PQconnectionUsedPassword

如果连接的认证方法使用密码则返回true (1)。否则返回false (0)。

int PQconnectionUsedPassword(const PGconn *conn);

此功能可应用于失败或成功连接后尝试检测服务器是否要求密码。

PQgetssl

返回连接中使用的SSL结构,或者没有使用SSL则返回null。

void *PQgetssl(const PGconn *conn);

这个结构可以用于核实加密级别,检查服务器认证等信息。参考OpenSSL 文档获取关于这个结构的更多信息。

实际返回值的类型是SSL *,而SSL的类型是由 OpenSSL库定义的,但是没有用这种方式声明, 以避免请求OpenSSL头文件。要使用这个函数, 可以使用下面的代码行:

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

...

    SSL *ssl;

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

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