lo-interfaces

更新时间:
复制 MD 格式

The libpq client library provides a Unix file-system–style interface for accessing large objects in PostgreSQL. The interface mirrors familiar system calls — open, read, write, lseek, and so on — so C application developers can work with large objects using patterns they already know.

Before you start:

  • Include the header file libpq/libpq-fs.h in your application.

  • Link against the libpq library.

  • Execute all large object operations inside an SQL transaction block. Large object descriptors are only valid for the duration of a transaction.

If a function fails, it returns an otherwise-impossible value — typically 0 or -1. Retrieve the error message with PQerrorMessage.

Create a large object

Use lo_create to create a large object with a specific OID:

Oid lo_create(PGconn *conn, Oid lobjId);

Pass a desired OID in lobjId. If that OID is already in use, the function fails. Pass InvalidOid (zero) to let the server assign an unused OID automatically. Returns the assigned OID on success, or InvalidOid on failure.

lo_create was introduced in PostgreSQL 8.1. Running it against an older server returns InvalidOid.

Example:

inv_oid = lo_create(conn, desired_oid);

If you need to work with servers older than PostgreSQL 8.1, use the legacy lo_creat instead:

Oid lo_creat(PGconn *conn, int mode);

lo_creat always assigns an unused OID. The mode parameter is ignored as of PostgreSQL 8.1; for backward compatibility, set it to INV_READ, INV_WRITE, or INV_READ | INV_WRITE. These constants are defined in libpq/libpq-fs.h.

Example:

inv_oid = lo_creat(conn, INV_READ|INV_WRITE);

Import a large object

To import an operating system file as a large object, call:

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

filename is the path to the file on the client file system — the file is read by the client library, not the server. Returns the assigned OID on success, or InvalidOid on failure.

To import a file and assign a specific OID, use:

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

Behavior is the same as lo_import, with the addition that you can specify the OID via lobjId. If that OID is already in use, the function fails. Pass InvalidOid to assign an unused OID automatically.

lo_import_with_oid was introduced in PostgreSQL 8.4 and relies on lo_create internally. Running it against PostgreSQL 8.0 or earlier returns InvalidOid.

Export a large object

To write a large object to an operating system file, call:

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

lobjId is the OID of the large object to export. filename is the output path on the client file system — the file is written by the client library, not the server. Returns 1 on success, -1 on failure.

Open an existing large object

Before reading or writing, open the large object to get a descriptor:

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

Set mode to control access:

ModeAccess
INV_READRead-only
INV_WRITERead/write
INV_READ | INV_WRITERead/write (same as INV_WRITE)

Returns a non-negative descriptor on success, or -1 on failure. The descriptor is valid only for the current transaction and can be used with lo_read, lo_write, lo_lseek, lo_lseek64, lo_tell, lo_tell64, lo_truncate, lo_truncate64, and lo_close.

Read visibility by mode:

  • INV_READ — data reflects the large object's state at the transaction snapshot taken when lo_open was called, regardless of subsequent writes. This is similar to the behavior of REPEATABLE READ.

  • INV_WRITE — data reflects all committed writes from other transactions as well as writes from the current transaction. This is similar to the behavior of READ COMMITTED.

lo_open requires SELECT privilege on the large object. If INV_WRITE is specified, UPDATE privilege is also required. Before PostgreSQL 11, these checks were deferred to the first actual read or write call. To disable the checks, set the lo_compat_privileges run-time parameter.

Example:

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

Write data to a large object

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

Writes len bytes from buf to the large object descriptor fd. fd must be a descriptor returned by lo_open. Returns the number of bytes written (always equal to len in the current implementation), or -1 on error.

Although len is declared as size_t, the function rejects values larger than INT_MAX. Transfer data in chunks of a few megabytes at most.

Read data from a large object

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

Reads up to len bytes from the large object descriptor fd into buf. fd must be a descriptor returned by lo_open. Returns the number of bytes actually read — fewer than len if the end of the large object is reached first — or -1 on error.

Although len is declared as size_t, the function rejects values larger than INT_MAX. Transfer data in chunks of a few megabytes at most.

Seek in a large object

To move the read/write position within a large object, call:

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

offset specifies the new position relative to the anchor set by whence:

whence valueAnchor
SEEK_SETBeginning of the object
SEEK_CURCurrent position
SEEK_ENDEnd of the object

Returns the new position on success, or -1 on error. lo_lseek fails if the resulting position exceeds 2 GB.

For large objects that may exceed 2 GB, use:

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

lo_lseek64 accepts offsets larger than 2 GB and returns positions larger than 2 GB.

lo_lseek64 was introduced in PostgreSQL 9.3. Running it against an older server returns -1.

Get the current position in a large object

int lo_tell(PGconn *conn, int fd);

Returns the current read/write position, or -1 on error. Fails if the position exceeds 2 GB.

For large objects that may exceed 2 GB, use:

pg_int64 lo_tell64(PGconn *conn, int fd);

lo_tell64 returns positions larger than 2 GB.

lo_tell64 was introduced in PostgreSQL 9.3. Running it against an older server returns -1.

Truncate a large object

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

Truncates the large object descriptor fd to len bytes. fd must be a descriptor returned by lo_open. If len is greater than the current length, the object is extended with null bytes ('\0'). The read/write position is not changed. Returns 0 on success, -1 on error.

lo_truncate rejects len values larger than INT_MAX.

For large objects that may exceed 2 GB, use:

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

lo_truncate64 accepts len values exceeding 2 GB.

lo_truncate was introduced in PostgreSQL 8.3; lo_truncate64 was introduced in PostgreSQL 9.3. Running either function against an older server returns -1.

Close a large object descriptor

int lo_close(PGconn *conn, int fd);

Closes the large object descriptor fd returned by lo_open. Returns 0 on success, -1 on error.

Any descriptors still open at the end of a transaction are closed automatically.

Remove a large object

int lo_unlink(PGconn *conn, Oid lobjId);

Removes the large object identified by lobjId from the database. Returns 1 on success, -1 on failure.