PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 32. 大对象 | 下一页

# 32.3. 客户端接口

本节描述PostgreSQL的libpq客户端接口库提供来访问大对象的设施。 PostgreSQL大对象接口是对Unix文件系统的模仿， 有仿真的`open`，`read`，`write`， `lseek`等。

使用这些函数的所有大对象操作必须在一个SQL事务块中发生， 由于大对象的文件描述符对事务的整段时间内是唯一有效的。

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

客户端应用程序使用包含`libpq/libpq-fs.h`头文件的这些函数，并且 可以与libpq库连接。

## 32.3.1. 创建大对象

函数

    Oid lo_creat(PGconn *conn, int mode);

创建一个新的大对象。返回值是赋予新大对象的OID， 或者是失败的时候是`InvalidOid`（零）。在PostgreSQL 8.1里， 没有再使用`mode`，并且它被忽略； 不过，为了和早期的版本向下兼容， 我们最好将其设置为`INV_READ`, `INV_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_create`函数是PostgreSQL 8.1里面新增加的； 如果在老的服务器上运行这个函数，它会失败并返回`InvalidOid`。

例子：

    inv_oid = lo_create(conn, desired_oid);

## 32.3.2. 输入大对象

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

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

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

函数

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

也能引入一个新的大对象。要赋予数值的OID可以用`lobjId`声明； 如果这么做，那么在该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`。

## 32.3.3. 输出大对象

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

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

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

## 32.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_read`， `lo_write`，`lo_lseek`， `lo_lseek64`，`lo_tell`， `lo_tell64`，`lo_truncate`， `lo_truncate64`和`lo_close`。 这个描述符只是在当前事务中有效。 失败的时候，返回-1。

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

例子：

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

## 32.3.5. 向大对象中写数据

函数

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

从`buf`中（这个大小必须是`len`） 向大对象描述符`fd`写入`len`字节。 `fd`参数必须是前面的一个`lo_open`调用的返回。 返回实际写入的字节数（当前实现过程中，它总是等于`len`，除非有错误）。 出错时，返回值是-1。

尽管`len`参数被声明为`size_t`， 这个函数将拒绝长度值大于`INT_MAX`。实践中，最好以兆字节传输块中数据。

## 32.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`。实践中，最好以兆字节传输块中数据。

## 32.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`同样的操作，但是它可以接受`offset`大于2GB和/或者 传递大于2GB的一个结果。注意如果新的位置指针大于2GB，那么`lo_lseek`将失败。

`lo_lseek64`是PostgreSQL 9.3中新的。如果这个函数 运行在一个旧的服务器版本上，则将失败并且返回-1。

## 32.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_tell64`是PostgreSQL 9.3中新的。如果 这个函数在一个旧服务器版本上运行，它将失败并且返回-1。

## 32.3.9. 截断一个大对象

截断一个给定长度的大对象，调用

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

截断大对象描述符`fd`到长度`len`的大对象， `fd`参数必须通过先前的`lo_open`返回。 如果`len`大于当前大对象的长度，大对象延长到空字节('\0')。 一旦成功，`lo_truncate`返回零。错误时，返回值是-1。

与描述符`fd`相联系的读/写位置没有被改变。

尽管`len`参数被声明为`size_t`，则`lo_truncate` 将拒绝长度值大于`INT_MAX`。

当处理可能超过2GB大小的大对象时，而是使用

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

这个函数和`lo_truncate`有同样操作，但是它可以接受 超过2GB的`len`值。

`lo_truncate`是PostgreSQL 8.3中新的； 如果这个函数在一个旧的服务器版本上运行，它将失败并且返回-1。

`lo_truncate64`是PostgreSQL 9.3中新的； 如果这个函数在一个旧的服务器版本上运行，它将失败并且返回-1。

## 32.3.10. 关闭一个大对象描述符

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

    int lo_close(PGconn *conn, int fd);

`fd`是通过`lo_open`返回的大对象描述符。 成功时，`lo_close`返回零。失败时，返回值是-1。

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

## 32.3.11. 删除一个大对象

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

    int lo_unlink(PGconn *conn, Oid lobjId);

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

上一页 | 起始页 | 下一页
实现特点 | 上一级 | 服务器端函数