34.3. Client 端界面

本节介绍 PostgreSQL 的 libpqClient 端接口库提供的用于访问大对象的功能。 PostgreSQL 大对象接口是在 Unix 文件系统接口之后建模的,类似于openreadwritelseek等。

使用这些功能的所有大对象操作都必须在 SQL 事务块内进行,因为大对象文件 Descriptors 仅在事务期间有效。

如果在执行这些函数中的任何一个函数时发生错误,该函数将返回否则不可能的值,通常为 0 或-1.描述错误的消息存储在连接对象中,可以使用PQerrorMessage进行检索。

使用这些功能的 Client 端应用程序应包括头文件libpq/libpq-fs.h并与 libpq 库链接。

34 .3.1. 创建一个大对象

功能

Oid lo_creat(PGconn *conn, int mode);

创建一个新的大对象。返回值是分配给新大对象的 OID,如果失败则返回InvalidOid(零)。 * mode *自 PostgreSQL 8.1 起未使用并被忽略;但是,为了向后兼容早期版本,最好将其设置为INV_READINV_WRITEINV_READ | INV_WRITE。 (这些符号常量在头文件libpq/libpq-fs.h中定义.)

An example:

inv_oid = lo_creat(conn, INV_READ|INV_WRITE);

功能

Oid lo_create(PGconn *conn, Oid lobjId);

还创建一个新的大对象。可以通过* lobjId 指定要分配的 OID;如果是这样,如果该 OID 已用于某些大型对象,则会发生故障。如果 lobjId *为InvalidOid(零),则lo_create分配未使用的 OID(这与lo_creat相同)。返回值是分配给新大对象的 OID,如果失败,则返回InvalidOid(零)。

lo_create是 PostgreSQL 8.1 的新功能;如果此功能在较旧的服务器版本上运行,它将失败并返回InvalidOid

An example:

inv_oid = lo_create(conn, desired_oid);

34 .3.2. 导入大对象

要将 os 文件导入为大对象,请调用

Oid lo_import(PGconn *conn, const char *filename);
  • filename *指定要作为大对象导入的文件的 os 名称。返回值是分配给新大对象的 OID,如果失败则返回InvalidOid(零)。注意,该文件是由 Client 端接口库而不是服务器读取的;因此它必须存在于 Client 端文件系统中,并且可由 Client 端应用程序读取。

功能

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

还导入一个新的大对象。可以通过* lobjId 指定要分配的 OID;如果是这样,如果该 OID 已用于某些大型对象,则会发生故障。如果 lobjId *为InvalidOid(零),则lo_import_with_oid分配未使用的 OID(这与lo_import相同)。返回值是分配给新大对象的 OID,如果失败,则返回InvalidOid(零)。

lo_import_with_oid是 PostgreSQL 8.4 的新功能,内部使用lo_create,这是 8.1 的新功能;如果此函数针对 8.0 或更早版本运行,它将失败并返回InvalidOid

34 .3.3. 导出大对象

要将大对象导出到 os 文件中,请调用

int lo_export(PGconn *conn, Oid lobjId, const char *filename);
  • lobjId 参数指定要导出的大对象的 OID, filename *参数指定文件的 os 名称。请注意,该文件是由 Client 端接口库而不是服务器编写的。成功返回 1,失败返回-1.

34 .3.4. 打开一个现有的大对象

要打开现有的大对象进行读取或写入,请致电

int lo_open(PGconn *conn, Oid lobjId, int mode);
  • lobjId *参数指定要打开的大对象的 OID。 * mode *位控制是否打开对象以读取(INV_READ),写入(INV_WRITE)或同时打开两者。 (这些符号常量在头文件libpq/libpq-fs.h中定义.)lo_open返回(非负)大对象 Descriptors,以供以后在lo_readlo_writelo_lseeklo_lseek64lo_telllo_tell64lo_truncatelo_truncate64lo_close中使用。Descriptors 仅在当前事务期间有效。失败时,返回-1.

服务器当前无法区分模式INV_WRITEINV_READ | INV_WRITE:在任何一种情况下都允许您从 Descriptors 中读取。但是,这些模式与单独使用INV_READ之间存在显着差异:使用INV_READ不能在 Descriptors 上进行写操作,并且从其读取的数据将反映执行lo_open时处于活动状态的事务快照时大对象的内容。 ,而不考虑此事务或其他事务以后的写入。从以INV_WRITE打开的 Descriptors 中进行读取将返回反映其他已提交事务的所有写入以及当前事务的写入的数据。这类似于普通 SQL SELECT命令的REPEATABLE READREAD COMMITTED事务模式的行为。

An example:

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

34 .3.5. 将数据写入大对象

功能

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

将* len 字节从 buf (其大小必须为 len )写入大对象 Descriptors fd *。 * fd 参数必须由先前的lo_open返回。返回实际写入的字节数(在当前实现中,除非有错误,否则它将始终等于 len *)。如果发生错误,则返回值为-1.

尽管* len *参数声明为size_t,但是此函数将拒绝大于INT_MAX的长度值。实际上,无论如何,最好以最大几兆字节的数据块传输数据。

34 .3.6. 从大对象读取数据

功能

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

从大对象 Descriptors* fd 读取最多 len 个字节到 buf (其大小必须为 len *)。 * fd 参数必须由先前的lo_open返回。返回实际读取的字节数;如果首先到达大对象的末尾,它将小于 len *。如果发生错误,则返回值为-1.

尽管* len *参数声明为size_t,但是此函数将拒绝大于INT_MAX的长度值。实际上,无论如何,最好以最大几兆字节的数据块传输数据。

34 .3.7. 寻找大物体

要更改与大对象 Descriptors 关联的当前读取或写入位置,请调用

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

此函数将* fd 标识的大对象 Descriptors 的当前位置指针移动到 offset *指定的新位置。 * whence *的有效值为SEEK_SET(从对象起始位置搜索),SEEK_CUR(从当前位置起始位置)和SEEK_END(从对象起始位置起始)。返回值是新的位置指针,如果出错则返回-1.

处理大小可能超过 2GB 的大型对象时,请改用

pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);

此函数的行为与lo_lseek相同,但是可以接受大于 2GB 的* offset *和/或提供大于 2GB 的结果。请注意,如果新的位置指针大于 2GB,则lo_lseek将失败。

lo_lseek64是 PostgreSQL 9.3 的新功能。如果在较旧的服务器版本上运行此功能,它将失败并返回-1.

34 .3.8. 获取大对象的寻找位置

要获取大对象 Descriptors 的当前读取或写入位置,请调用

int lo_tell(PGconn *conn, int fd);

如果有错误,则返回值为-1.

处理大小可能超过 2GB 的大型对象时,请改用

pg_int64 lo_tell64(PGconn *conn, int fd);

此函数的行为与lo_tell相同,但是可以提供大于 2GB 的结果。请注意,如果当前的读/写位置大于 2GB,则lo_tell将失败。

lo_tell64是 PostgreSQL 9.3 的新功能。如果在较旧的服务器版本上运行此功能,它将失败并返回-1.

34 .3.9. 截断大对象

要将大对象截断为给定长度,请调用

int lo_truncate(PGcon *conn, int fd, size_t len);

此函数将大对象 Descriptors* fd 截短为长度 len *。 * fd 参数必须由先前的lo_open返回。如果 len *大于大对象的当前长度,则将大对象扩展为具有空字节(' 0')的指定长度。成功时,lo_truncate返回零。错误时,返回值为-1.

与 Descriptors* fd *关联的读/写位置未更改。

尽管* len *参数声明为size_t,但lo_truncate将拒绝大于INT_MAX的长度值。

处理大小可能超过 2GB 的大型对象时,请改用

int lo_truncate64(PGcon *conn, int fd, pg_int64 len);

此函数的行为与lo_truncate相同,但是可以接受* len *超过 2GB 的值。

lo_truncate是 PostgreSQL 8.3 的新功能;如果此功能在较旧的服务器版本上运行,它将失败并返回-1.

lo_truncate64是 PostgreSQL 9.3 的新功能;如果此功能在较旧的服务器版本上运行,它将失败并返回-1.

34 .3.10. 关闭大对象 Descriptors

大对象 Descriptors 可以通过调用来关闭

int lo_close(PGconn *conn, int fd);

其中* fd *是lo_open返回的大对象 Descriptors。成功时,lo_close返回零。错误时,返回值为-1.

在事务结束时保持打开状态的任何大对象 Descriptors 将自动关闭。

34 .3.11. 移除大物件

要从数据库中删除大对象,请调用

int lo_unlink(PGconn *conn, Oid lobjId);