Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

35.3. 客户端接口 #

35.3.1. 创建大对象
35.3.2. 导入大对象
35.3.3. 导出大对象
35.3.4. 打开现有大对象
35.3.5. 向大对象写入数据
35.3.6. 从大对象读取数据
35.3.7. 在大对象中查找
35.3.8. 获取大对象的查找位置
35.3.9. 截断大对象
35.3.10. 关闭大对象描述符
35.3.11. 删除大对象

本节介绍 PostgreSQLlibpq 客户端接口库为访问大对象提供的功能。PostgreSQL 大对象接口模仿 Unix 文件系统接口,具有 openreadwritelseek 等类似项。

使用这些函数的所有大对象操作必须在 SQL 事务块中进行,因为大对象文件描述符仅在事务期间有效。在只读事务中不允许进行写入操作,包括带有 INV_WRITE 模式的 lo_open

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

使用这些函数的客户端应用程序应包含头文件 libpq/libpq-fs.h 并链接到 libpq 库。

当 libpq 连接处于管道模式时,客户端应用程序无法使用这些函数。

35.3.1. 创建大对象 #

该函数

Oid lo_create(PGconn *conn, Oid lobjId);

创建一个新的大型对象。可通过 lobjId 指定要分配的 OID;如果指定,则在该 OID 已被某些大型对象使用的情况下会发生故障。如果 lobjIdInvalidOid(零),则 lo_create 会分配一个未使用的 OID。返回值是分配给新大型对象或故障时的 InvalidOid(零)的 OID。

一个示例

inv_oid = lo_create(conn, desired_oid);

旧函数

Oid lo_creat(PGconn *conn, int mode);

也创建一个新的大型对象,始终分配一个未使用的 OID。返回值是分配给新大型对象或故障时的 InvalidOid(零)的 OID。

PostgreSQL 8.1 及更高版本中,mode 被忽略,因此 lo_creat 完全等同于第二个参数为零的 lo_create。但是,除非需要使用早于 8.1 版本的服务器,否则几乎没有理由使用 lo_creat。要使用如此旧的服务器,必须使用 lo_creat 而不是 lo_create,并且必须将 mode 设置为 INV_READINV_WRITEINV_READ | INV_WRITE 之一。(这些符号常量在头文件 libpq/libpq-fs.h 中定义。)

一个示例

inv_oid = lo_creat(conn, INV_READ|INV_WRITE);

35.3.2. 导入大型对象 #

要将操作系统文件导入为大型对象,请调用

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

filename 指定要作为大型对象导入的文件的操作系统名称。返回值是分配给新大型对象或故障时的 InvalidOid(零)的 OID。请注意,该文件由客户端接口库读取,而不是由服务器读取;因此,它必须存在于客户端文件系统中,并且客户端应用程序可读。

函数

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

还导入一个新的大型对象。可通过 lobjId 指定要分配的 OID;如果指定,则在该 OID 已被某些大型对象使用的情况下会发生故障。如果 lobjIdInvalidOid(零),则 lo_import_with_oid 会分配一个未使用的 OID(此行为与 lo_import 相同)。返回值是分配给新大型对象或故障时的 InvalidOid(零)的 OID。

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

35.3.3. 导出大对象 #

要将大对象导出到操作系统文件,请调用

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

lobjId 参数指定要导出的对象的大对象 OID,filename 参数指定文件的操作系统名称。请注意,该文件由客户端接口库编写,而不是由服务器编写。成功返回 1,失败返回 -1。

35.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_lseek64lo_telllo_tell64lo_truncatelo_truncate64lo_close 中使用。该描述符仅在当前事务的持续时间内有效。如果失败,则返回 -1。

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

lo_open 将在以下情况下失败:如果大对象没有 SELECT 权限,或者如果指定了 INV_WRITE 而没有 UPDATE 权限。(在 PostgreSQL 11 之前,这些权限检查是在使用描述符的第一次实际读取或写入调用时执行的。)这些权限检查可以使用 lo_compat_privileges 运行时参数禁用。

一个示例

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

35.3.5. 向大对象写入数据 #

该函数

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

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

虽然 len 参数被声明为 size_t,但此函数将拒绝大于 INT_MAX 的长度值。实际上,最好将数据以最多几兆字节的块传输。

35.3.6. 从大对象读取数据 #

该函数

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

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

虽然 len 参数被声明为 size_t,但此函数将拒绝大于 INT_MAX 的长度值。实际上,最好将数据以最多几兆字节的块传输。

35.3.7. 在大对象中搜索 #

要更改与大对象描述符相关联的当前读写位置,请调用

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

此函数将由 fd 标识的大对象描述符的当前位置指针移动到由 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_lseek64PostgreSQL 9.3 中的新增功能。如果此函数针对较旧的服务器版本运行,它将失败并返回 -1。

35.3.8. 获取大对象的搜索位置 #

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

int lo_tell(PGconn *conn, int fd);

如果出现错误,返回值为 -1。

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

pg_int64 lo_tell64(PGconn *conn, int fd);

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

lo_tell64PostgreSQL 9.3 中的新增功能。如果此函数针对较旧的服务器版本运行,它将失败并返回 -1。

35.3.9. 截断大对象 #

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

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

此函数截断大对象描述符 fd,长度为 lenfd 参数必须由先前的 lo_open 返回。如果 len 大于大对象的当前长度,则大对象将使用空字节 ('\0') 扩展到指定长度。如果成功,lo_truncate 将返回零。如果出错,则返回值为 -1。

与描述符 fd 关联的读/写位置不会更改。

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

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

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

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

lo_truncatePostgreSQL 8.3 中为新功能;如果针对较旧的服务器版本运行此函数,它将失败并返回 -1。

lo_truncate64PostgreSQL 9.3 中为新功能;如果针对较旧的服务器版本运行此函数,它将失败并返回 -1。

35.3.10. 关闭大对象描述符 #

可以通过调用关闭大对象描述符

int lo_close(PGconn *conn, int fd);

其中 fd 是由 lo_open 返回的大对象描述符。如果成功,lo_close 将返回零。如果出错,则返回值为 -1。

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