29.3. 客户端接口

本节描述 PostgreSQL 客户端接口库提供来访问大对象的设施。 所有使用这些函数进行的大对象操作都必须在一个SQL事务里实现。 (这个要求是自 PostgreSQL 6.5 以来的一个严格的要求,虽然在以前的版本里就隐含这样的要求,如果忽略这一点会导致错误的表现。) PostgreSQL大对象接口是对 Unix 文件系统的模仿,有仿真的 openreadwritelseek,等.

使用 libpq 里面大对象接口的的客户端应用应该包含头文件 libpq/libpq-fs.h 并且和 libpq 库链接。

29.3.1. 创建大对象

函数

Oid lo_creat(PGconn *conn, int mode);

创建一个新的大对象。 返回值是赋予新大对象的 OID,或者是失败的时候是 InvalidOid(零)。 在PostgreSQL 8.1 里,没有再使用 mode,并且它被忽略; 不过,为了和早期的版本向下兼容,我们最好将其设置为 INV_READINV_WRITE,或者 INV_READ | INV_WRITE。 (这些符号常量在头文件 libpq/libpq-fs.h 里定义。)

例子:

inv_oid = lo_creat(conn, INV_READ|INV_WRITE);

函数

Oid lo_create(PGconn *conn, Oid lobjId);

也创建一个大对象。要赋予数值的 OID 可以用 lobjId 声明;如果这么做,那么在该 OID 已经被其他大对象使用的情况下就会生成错误。 如果 lobjId 为 InvalidOid (零), 那么 lo_create 赋予一个未用的 OID(这个和 lo_creat 的行为一致。) 返回值是赋予新的大对象的 OID,或者是失败情况下的 InvalidOid(零)。

lo_createPostgreSQL 8.1里面新增加的; 如果在老的服务器上运行这个函数,它会失败并返回 InvalidOid。

一个例子:

inv_oid = lo_create(conn, desired_oid);

29.3.2. 输入大对象

要把一个操作系统文件输入成为大对象,调用

Oid lo_import(PGconn *conn, const char *filename);

filename 参数指明要被输入成为大对象的操作系统文件路径名。返回值是赋予新大对象的 OID。 如果失败则返回 InvalidOid(零)。请注意这个文件是由客户端接口库读取的, 而不是服务器端;因此它必须存在于客户端文件系统上并且可以被客户应用读取。

29.3.3. 输出大对象

要把一个大对象输出为操作系统文件,调用

int lo_export(PGconn *conn, Oid lobjId, const char *filename);

lobjId参数指明要输出的大对象 OID,filename 参数指明操作系统文件的路径名。请注意这个文件是由客户端接口库写入的, 而不是服务器端。成功时返回 1,失败时返回 -1。

29.3.4. 打开一个现有的大对象

要打开一个现存的大对象读写,调用

int lo_open(PGconn *conn, Oid lobjId, int mode);

参数lobjId指明要打开的大对象的 OID (对象标识)。 mode位控制该对象是用于读 (INV_READ), 写(INV_WRITE)还是读写。 (这些符号常量在头文件 libpq/libpq-fs.h 里定义。) 一个大对象在其创建之前不能被打开。 lo_open 返回一个(非负的)大对象标识用于以后的 lo_readlo_writelo_lseeklo_tell,和 lo_close。这个描述符只是在当前事务中有效。 失败的时候,返回 -1。

服务器目前并不区分 INV_WRITEINV_READ | INV_WRITE 模式: 对于 INV_READ,你不能写入描述符,并且从其中读取的数据将反映执行 lo_open 的时候事务快照对应的大对象的数据,而不会考虑本次事务后面写入的或者其他事务写入的数据。 从一个用 INV_WRITE 打开的描述符里面读取的数据反映所有其他已经提交的事务和当前事务的写操作写入的大对象的数据。 这个行为类似普通 SQL 语句 SELECT 在事务模式 SERIALIZABLEREAD COMMITTED 中的行为。

一个例子:

inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);

29.3.5. 向大对象中写数据

函数

int lo_write(PGconn *conn, int fd, const char *buf, size_t len);

buf中向大对象描述符fd中写len字节. 参数fd必须是前面一个 lo_open 调用的返回。 返回实际写的字节数.出错时返回负数.

29.3.6. 从大对象中读取数据

函数

int lo_read(PGconn *conn, int fd, char *buf, size_t len);

从大对象描述符 fd 中读取len字节数据到buf中。 fd参数必须是前面的一个 lo_open调用的返回。 返回实际读取的字节数。出错时,返回一个负数。

29.3.7. 大对象中数据的查找

要改变与一个大对象描述符相关的读写位置,调用

int lo_lseek(PGconn *conn, int fd, int offset, int whence);

这个过程把当前fd代表的大对象描述符位置指针移动到 offset指明的新的位置。 参数whence的合法的取值是 SEEK_SET(从对象开头开始找),SEEK_CUR(从当前位置开始找),和SEEK_END (从对象结尾开始找)。返回值是新位置指针,如果出错为 -1。

29.3.8. 获取一个大对象的当前搜索位置

要获取一个大对象描述符的当前读或写位置,调用

int lo_tell(PGconn *conn, int fd);

如果有错误,返回值是负数。

29.3.9. 关闭一个大对象描述符

可以通过调用

int lo_close(PGconn *conn, int fd);

关闭一个大对象描述符,这里fdlo_open返回的大对象的描述符.成功时, lo_close 返回零.错误时,返回值是负数.

任何在事务结尾时仍然打开的大对象描述符将在事务结束时自动关闭。

29.3.10. 删除一个大对象

从数据库中删除一个大对象,调用

int lo_unlink(PGconn *conn, Oid lobjId);

lobjId参数声明要删除的大对象的 OID。 成功时返回 1,失败时返回 -1。