1.8. libpq 跟踪函数
*
PQtrace 打开对前端/后端通讯的跟踪,把调试信息输出到一个文件流里.
void PQtrace(PGconn *conn
FILE *debug_port)
*
PQuntrace 关闭PQtrace打开的跟踪
void PQuntrace(PGconn *conn)
1.9. libpq 控制函数
*
PQsetNoticeProcessor 控制libpq生成的通知和警告信息的汇报.
typedef void (*PQnoticeProcessor) (void *arg, const char *message);
PQnoticeProcessor
PQsetNoticeProcessor(PGconn *conn,
PQnoticeProcessor proc,
void *arg);
缺省时,libpq 在后端往 stderr 上打印“通知”信息和一些它自身生成的错误信息.这个特性可以通过提供一个对信息进行某种加工的回叫函数来更改.我们向这个回叫函数传递错误信息的文本(包括文本结尾的换行符),和一个空(void)指针,该指针与传递给 PQsetNoticeProcessor 的完全一样.(如果需要,这个指针可以用于访问应用相关的状态.)缺省的通知处理器只是简单的
static void
defaultNoticeProcessor(void * arg, const char * message)
{
fprintf(stderr, "%s", message);
}
要使用特殊的通知处理器,在创建完新的PGconn对象后马上调用 PQsetNoticeProcessor。
返回值是指向以前的通知处理器的指针。如果你提供了一个 NULL 做为回调指针,那么不会发生任何动作,只是返回当前的指针。
一旦你设置了一个通知处理器,你就应该预料到该函数可能在PGconn对象或 PGresult对象从开始存在时起就可能被调用.当创建一个PGresult时,PGconn 的当前的通知指针被拷贝到 PGresult里提供给可能需要的过程,如 PQgetvalue 使用.
1.10. 环境变量
下面的环境变量可以用于选择缺省的联接参数值,这些值将被 PQconnectdb 或 PQsetdbLogin 使用--如果调用代码没有直接声明相应值的话.这些(环境变量)可以避免把麻烦的数据库名强加入简单的应用程序的硬代码里面.
*
PGHOST 设置缺省的服务器名.如果它以一个斜扛开头,那么它声明一个 Unix 域套接字而不是 TCP/IP 通讯;其值就是该套接字文件存储的目录(缺省为 /tmp).
*
PGPORT 设置缺省的 TCP 端口号或者设置与 PostgreSQL 的 Unix 域套接字的文件扩展(文件标识符).
*
PGDATABASE 设置缺省的 PostgreSQL 数据库名.
*
PGUSER 设置用于与数据库联接和用于认证的用户名.
*
PGPASSWORD 如果后端要求口令认证,设置使用的口令.因为安全原因,这个功能已经废弃了;请考虑使用 $HOME/.pgpass文件。
*
PGREALM 设置与 PostgreSQL一起使用的 Kerberos 领域--如果该域与本地域不同的话。如果设置了 PGREALM ,PostgreSQL 应用将试图用这个域(realm)与服务器进行认证并且使用独立的门票文件(ticket files)以避免与本地的门票文件冲突.只有在后端选择了 Kerberos 认证时才使用这个环境变量.(译注:门票文件是 Kerberos认证协议中用于交换密钥的一个文件/服务器。)
*
PGOPTIONS 为 PostgreSQL 后端设置附加的运行时选项.
*
PGTTY 设置后端调试信息显示输出的文件或者控制台(tty).
下面的环境变量可以用于为每个PostgreSQL 会话声明用户级别的缺省特性:
*
PGDATESTYLE 设置缺省的日期/时间表现形式.
*
PGTZ 设置缺省的时区.
*
PGCLIENTENCODING 设置缺省的客户端编码(如果配制PostgreSQL 时选择了多字节支持).
下面的环境变量可以用于为每个PostgreSQL 会话声明缺省的内部特性:
*
PGGEQO 为基因优化器设置缺省模式.
参阅 SET SQL 命令获取这些环境变量的正确值的信息.
1.11. 文件
> 家目录中的.pgpass 是一个可以包含口令的文件。如果连接要求口令,那么可以用它。这个文件的格式应该是:
hostname:port:database:username:password
这些行可以是一个文本名字,或者 *,它匹配所有的东西。第一个匹配的东西将得以使用,因此我们应该把最具体的记录放在前面。有 : 或者 \ 的记录应该用 \ 逃逸。
.pgpass 的权限必须不允许任何全局或者同组的用户访问;我们可以用命令 chmod 0600 .pgaccess 实现这个目的。如果权限比这个松,这个文件将被忽略。
1.12. 线程特性
到 PostgreSQL 7.0 时 libpq 是线程安全的, --只要不是两个线程试图同时操作同一个PGconn对象.实际上,你无法从不同的线程向同一个联接对象发出并发的查询.(如果你需要运行并行查询,请启动多个联接.)
PGresult对象在创建后是只读的,因此可以自由地在线程之间传递.
过时了的函数 PQoidStatus 和 fe_setauthsvc 都是线程不安全的,因此不应该在一个多线程的程序里面使用. PQoidStatus 可以由 PQoidValue代替.而我们觉得根本没有调用 fe_setauthsvc 的必要.
Libpq 客户端使用的 crypt 加密方法倚赖 crypt() 系统函数,它通常不是线程安全的.我们最好使用 MD5 加密,它在所有平台上是线程安全的.
1.13. 制作 Libpq 程序
要制作(也就是说编译和链接)你的 libpq 程序,你需要做下面的一些事情∶
*
包含 libpq-fe.h 头文件∶
#include <libpq-fe.h>
如果你没干这件事,那么你通常会看到类似下面这样的来自编译器的信息∶
foo.c: In function `main':
foo.c:34: `PGconn' undeclared (first use in this function)
foo.c:35: `PGresult' undeclared (first use in this function)
foo.c:54: `CONNECTION_BAD' undeclared (first use in this function)
foo.c:68: `PGRES_COMMAND_OK' undeclared (first use in this function)
foo.c:95: `PGRES_TUPLES_OK' undeclared (first use in this function)
*
告诉你的编译器PostgreSQL头文件的安装位置, 方法是给你的编译器提供 -Idirectory 选项. (有些时候编译器会查找缺省的目录,因此你可以忽略这些选项.) 比如,你的命令行看起来象∶
cc -c -I/usr/local/pgsql/include testprog.c
如果你在使用制作文件(makefile),那么向 CPPFLAGS 变量中增加下面的选项∶
CPPFLAGS += -I/usr/local/pgsql/include
如果你的程序可能会被别人编译,那么你应该避免象上面那样把目录路径 写成硬编码.取而代之的是你可以运行 pg_config 工具找出头文件在系统的什么地方∶
$ pg_config --includedir
/usr/local/include
如果没能给编译器提供正确的选项将产生类似下面这样的错误信息
testlibpq.c:8:22: libpq-fe.h: No such file or directory
*
在链接最后的程序的时候,声明选项 -lpq, 这样就可以把 libpq 库链接进来, 还要声明 -Ldirectory 以指向 libpq 所处的目录. (同样,编译器也会搜索一些缺省的目录.) 为了尽可能提高可移植性,你应该把 -L 选项放在 -lpq 选项前面.比如∶
cc -o testprog testprog1.o testprog2.o -L/usr/local/pgsql/lib -lpq
你也可以用 pg_config 找出库目录∶
$ pg_config --libdir
/usr/local/pgsql/lib
指向这类问题的错误信息会是类似下面这个样子.
testlibpq.o: In function `main':
testlibpq.o(.text+0x60): undefined reference to `PQsetdbLogin'
testlibpq.o(.text+0x71): undefined reference to `PQstatus'
testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
这意味着你忘记 -lpq 了.
/usr/bin/ld: cannot find -lpq
这意味着你忘记这-L 或者没有声明正确的路径.
如果你的代码引用了头文件 libpq-int.h, 而且你不原意修补你的代码以避免使用它,那么从 PostgreSQL7.2 开始, 该文件将在 includedir/postgresql/internal/libpq-int.h 里出现, 因此你需要给你的编译器命令行增加合适的 -I 选项.