本節では、PostgreSQLクライアントインタフェースライブラリで提供されるラージオブジェクトへのアクセス手段について説明します。
これらの関数を使用したラージオブジェクトの操作は全てSQLトランザクションブロック内で行われなければなりません
PostgreSQLラージオブジェクトインタフェースは、Unixファイルシステムインタフェースに因んで設計されており、open
、read
、write
、lseek
など同様のインタフェースを有しています。
libpqのラージオブジェクトインタフェースを使用するクライアントアプリケーションは、libpq/libpq-fs.hヘッダファイルをインクルードし、libpqライブラリとリンクしなければなりません。
Oid lo_creat(PGconn *conn, int mode);
この関数はラージオブジェクトを新規に作成します。 戻り値は新規ラージオブジェクトに割り当てられたOIDで、失敗時にはInvalidOid(0)が返されます。 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(0)の場合、lo_create
は未使用のOIDを割り当てます。
(これはlo_creat
と同じ動作です。)
戻り値は新規ラージオブジェクトに割り当てられたOIDで、失敗時にはInvalidOid(0)が返されます。
lo_create
はPostgreSQL 8.1から導入されました。
個の関数を古いバージョンで実行させると、失敗し、InvalidOidが返されます。
例を示します。
inv_oid = lo_create(conn, desired_oid);
オペレーティングシステム上のファイルをラージオブジェクトとしてインポートするには、以下の関数を呼び出します。
Oid lo_import(PGconn *conn, const char *filename);
filenameには、ラージオブジェクトとしてインポートするオペレーティングシステム上のファイルのパス名を指定します。 戻り値は、新規ラージオブジェクトに割り当てられたOIDです。 失敗時はInvalidOid(0)が返されます。 このファイルがサーバではなく、クライアントインタフェースライブラリから読み取られることに注意してください。 ですから、このファイルはクライアントのファイルシステム上に存在し、クライアントアプリケーションから読み取り可能でなければなりません。
ラージオブジェクトをオペレーティングシステム上のファイルにエクスポートするには、以下の関数を呼び出します。
int lo_export(PGconn *conn, Oid lobjId, const char *filename);
lobjId引数には、エクスポートさせるラージオブジェクトのOIDを指定し、filename引数には、オペレーティングシステム上のファイルのパス名を指定します。 このファイルはサーバではなく、クライアントインタフェースライブラリによって書き込まれることに注意してください。 成功時には1、失敗時には-1が返されます。
読み取りまたは書き込みのために既存のラージオブジェクトを開く場合は、以下の関数を呼び出します。
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_tell
、lo_close
で使用する(非負の)ラージオブジェクト記述子を返します。
この記述子は現在のトランザクション期間のみで有効です。
失敗時には-1が返されます。
現時点では、サーバはINV_WRITEモード、INV_READ | INV_WRITEモードとを区別しません。
どちらの場合でも記述子から読み取り可能です。
しかし、これらのモードとINV_READだけのモードとの間には大きな違いがあります。
INV_READモードでは記述子に書き込むことができません。
そして、読み込んだデータは、このトランザクションや他のトランザクションで後で書き込んだかどうかは関係なく、lo_open
を実行した時に有効だったトランザクションスナップショットの時点のラージオブジェクトの内容を反映したものになります。
INV_WRITEを付けて開いた記述子から読み取ると、現在のトランザクションによる書き込みや他のトランザクションがコミットした書き込みすべてを反映したデータが返されます。
これは、通常のSELECT SQLコマンドにおけるSERIALIZABLEトランザクションの動作とREAD COMMITTEDトランザクションの動作の違いに似ています。
以下に例を示します。
inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
この関数は、len長のバイトを、bufからfdラージオブジェクト記述子に書き込みます。
fd引数は事前に実行したlo_open
の戻り値でなければいけません。
実際に書き込まれたバイト数が返されます。
エラーが発生した場合は、負の値を返します。
int lo_read(PGconn *conn, int fd, char *buf, size_t len);
この関数は、len長のバイトを、fdラージオブジェクト記述子からbufに読み込みます。
fd引数は事前に実行したlo_open
の戻り値でなければいけません。
実際に読み込まれたバイト数が返されます。
エラーが発生した場合は、負の値を返します。
ラージオブジェクト記述子に関連付けされている、現在の読み取りまたは書き込みを行う位置を変更するには、以下の関数を呼び出します。
int lo_lseek(PGconn *conn, int fd, int offset, int whence);
この関数はfdで識別されるラージオブジェクト識別子の現在の位置を指すポインタを、offsetで指定した新しい位置に変更します。 whenceに指定可能な値は、SEEK_SET(オブジェクトの先頭位置からシーク)、SEEK_CUR(現在位置からシーク)、SEEK_END(オブジェクトの末尾位置からシーク)のいずれかです。 戻り値は新しい位置ポインタで、エラー時に-1が返されます。
ラージオブジェクト記述子の現在の読み取り、書き込み位置を入手するには、以下の関数を呼び出します。
int lo_tell(PGconn *conn, int fd);
ラージオブジェクトを指定した長さに切り詰めるには、以下を呼び出します。
int lo_truncate(PGcon *conn, int fd, size_t len);
これはラージオブジェクト記述子fdをlen長に切り詰めます。
fd引数は前もってlo_open
が返したものでなければなりません。
lenが現在のラージオブジェクト長より大きければ、ラージオブジェクトはヌルバイト('\0')で拡張されます。
ファイルのオフセットは変わりません。
成功時lo_truncate
は0を返します。
エラー時は負の値を返します。
lo_truncate
はPostgreSQL 8.3で新規に導入されました。
この関数を古いバージョンのサーバに対して実行した場合は失敗し、負の値が返されます。
以下を呼び出すことでラージオブジェクト記述子を閉ざすことができます。
int lo_close(PGconn *conn, int fd);
ここで、fdはlo_open
の戻り値であるラージオブジェクト記述子です。
成功すると、lo_close
は0を返します。
失敗すると、負の値を返します。
開いたままのラージオブジェクト記述子は全てトランザクションの終了時に自動的に閉ざされます。
データベースからラージオブジェクトを削除するには、以下の関数を呼び出します。
int lo_unlink(PGconn *conn, Oid lobjId);