.\" This is -*-nroff-*- .\" XXX standard disclaimer belongs here.... .\" $Header: /usr/local/cvsroot/pgsql/src/man/large_objects.3,v 1.6 1998/03/23 15:09:29 momjian Exp $ .\" .\" Japanese Version Copyright (c) 1998 Michihide Hotta .\" all rights reserved. .\" Translated Wed Jun 3 18:46:34 JST 1998 .\" by Michihide Hotta .\" .TH "LARGE OBJECTS" INTRO 03/18/94 PostgreSQL PostgreSQL .\"0 .SH DESCRIPTION .SH 説明 .PP .\"0 In Postgres, data values are stored in tuples and individual .\"0 tuples cannot span data pages. Since the size of a data page .\"0 is 8192 bytes, the upper limit on the size of a data value .\"0 is relatively low. To support the storage of larger atomic .\"0 values, Postgres provides a large object interface. This .\"0 interface provides file-oriented access to user data that .\"0 has been declared to be a large type. Postgres においては、データ値はタップルに格納され、個々の タップルはデータページの大きさを知ることができません。 データページのサイズが 8192 バイトであるため、データ値の サイズの上限は比較的小さなものになっています。巨大な原子値 の記憶領域をサポートするために、Postgres ではラージオブ ジェクト・インターフェースを提供しています。このインター フェースでは、ラージ型として宣言されたユーザデータへの ファイル志向のアクセスを提供します。 .PP .\"0 This section describes the implementation and the .\"0 programmatic and query language interfaces to Postgres large .\"0 object data. この章では Postgres ラージオブジェクト・データの実装と、 それらに対するプログラミング的な問い合わせ言語インター フェースについて解説します。 .PP .\"0 .SH "Historical Note" .SH 歴史的な特記事項 .PP .\"0 Originally, postgres 4.2 supports three standard .\"0 implementations of large objects: as files external to .\"0 Postgres, as Unix files managed by Postgres, and as .\"0 data stored within the Postgres database. It causes .\"0 considerable confusion among users. As a result, we only .\"0 support large objects as data stored within the Postgres .\"0 database in Postgres. Even though is is slower to access, .\"0 it provides stricter data integrity and time travel. .\"0 For historical reasons, they are called Inversion large .\"0 objects. (We will use Inversion and large objects .\"0 interchangeably to mean the same thing in this section.) Postgres 4.2 では元々、Postgres の外部ファイル、Postgres で管理される Unix ファイル、Postgres データベースに格納される データという 3 つのラージオブジェクトの実装をサポートして いましたが、これらはユーザを戸惑わせる原因になっています。 その結果として我々は、ラージオブジェクトを Postgres における Postgres データベースの内部に格納されたデータとしてサポート します。これによりアクセス速度こそ低下しますが、より厳密な データの統合とタイムトラベルを提供できるようになります。 歴史的な理由により、それらは転置ラージオブジェクトと呼ばれます。 (この章では転置とラージオブジェクトを同じ意味で使います。) .\"0 .SH "Inversion Large Objects" .SH 転置ラージオブジェクト .PP .\"0 The Inversion large .\"0 object implementation breaks large objects up into .\"0 \*(lqchunks\*(rq and stores the chunks in tuples in the .\"0 database. A B-tree index guarantees fast searches for the .\"0 correct chunk number when doing random access reads and writes. 転置ラージオブジェクトの実装は、ラージオブジェクトを \*(lqチャンク\*(rq にまで分散し、タップルの中のチャンク はデータベースに格納されます。ランダムアクセスによる読み書き を行っている時は、B-tree インデックスは正しいチャンク番号の 高速な検索を保証します。 .\"0 .SH "Large Object Interfaces" .SH ラージオブジェクト・インターフェース .PP .\"0 The facilities Postgres provides to access large objects, .\"0 both in the backend as part of user-defined functions or .\"0 the front end as part of an application using the \*(LQ .\"0 interface, are described below. (For users familiar with .\"0 postgres 4.2, Postgres has a new set of functions providing .\"0 a more coherent interface. The interface is the same .\"0 for dynamically-loaded C functions as well as for \*(LQ. ラージオブジェクトにアクセスするために Postgres が提供する 機能として、ユーザ定義の関数としてバックエンドにおいて実行 されるもの、および \*(LQ インターフェースを使ってアプリケー ションの一部として実行されるものの両方を以下で説明します。 (Postgres 4.2 に親しんでいるユーザのために:Postgres では、 新しい、より筋の通ったインターフェースを提供する関数のセット を持っています。このインターフェースは \*(LQ だけでなく、 動的にロードされる C 関数と同じものです。) .PP .\"0 The Postgres large object interface is modeled after the .\"0 Unix file system interface, with analogues of Postgres のラージオブジェクト・インターフェースは、 .I open (2), .I read (2), .I write (2), .I lseek (2), といった Unix ファイルシステム・インターフェースに類似した モデルとなっています。 .\"0 etc. User functions call these routines to retrieve only .\"0 the data of interest from a large object. For example, ラージオブジェクトから特定のデータだけを取り出すために、 ユーザの関数はこれらルーチンをコールします。たとえば、 .\"0 if a large object type called 顔写真を格納している .I mugshot (顔写真、手配写真)と呼ばれるラージオブジェクト型があり、また .\"0 existed that stored photographs of faces, then a function .\"0 called .I beard (ひげ)と呼ばれる関数が .\"0 could be declared on .I mugshot .\"0 data. データに宣言されているとします。 .I Beard .\"0 could look at the lower third of a photograph, and determine .\"0 the color of the beard that appeared there, if any. The .\"0 entire large object value need not be buffered, or even .\"0 examined, by the (ひげ)は写真の下 3 分の 1 を見て、もしそこにひげがあればその 色を測定します。ラージオブジェクト全体の値は .I beard .\"0 function. 関数によりバッファリングされる必要はなく、またチェックされる 必要もありません。 .\"As mentioned above, Postgres supports functional indices on .\"large object data. In this example, the results of the .\".I beard .\"function could be stored in a B-tree index to provide fast searches .\"for people with red beards. .PP .\"0 Large objects may be accessed from dynamically-loaded C .\"0 functions or database client programs that link the Libpq .\"0 library. Postgres provides a set of routines that support .\"0 opening, reading, writing, closing, and seeking on large .\"0 objects. ラージオブジェクトは動的にロードされた C 関数と、Libpq ライブラリとリンクされたデータベース・クライアントプログラム のいずれからアクセスされてもかまいません。Postgres では、 ラージオブジェクトのオープン・読み・書き・クローズ・シーク の各機能を提供しています。 .\"0 .SH "Creating a Large Object" .SH ラージオブジェクトの生成 .PP .\"0 The routine ルーチン .nf Oid lo_creat(PGconn *conn, int mode) .fi .\"0 creates a new large object. The は新しいラージオブジェクトを生成します。 .I mode .\"0 is a bitmask describing several different attributes of the .\"0 new object. The symbolic constants listed here are defined in は新しいオブジェクトの複数の異なった属性を指定するビットマスク です。以下に示されるシンボル化された定数は .nf /usr/local/pgsql/src/backend/libpq/libpq-fs.h .fi で定義されています。 .\"0 The access type (read, write, or both) is controlled by アクセスタイプ(read, write または両方)は .\"0 .SM OR .\"0 ing together the bits .SM INV_READ .\"0 and と .SM INV_WRITE ビットを .SM OR することで指定します。 .\"0 If the large object should be archived - that is, if .\"0 historical versions of it should be moved periodically to a .\"0 special archive relation - then the ラージオブジェクトはアーカイブされていることが必要です。 すなわち、その複数世代のバージョンが定期的に特別なアーカイブ ・リレーションに移動される場合、その後 .SM INV_ARCHIVE .\"0 bit should be set. The low-order sixteen bits of ビットをセットしなければなりません。 .I mask .\"0 are the storage manager number on which the large object .\"0 should reside. For sites other than Berkeley, these bits .\"0 should always be zero. の下位 16 ビットは、ラージオブジェクトが存在する記憶領域の 管理番号です。Berkeley 以外のサイトにおいてはこれらは常に 0 です。 .\"At Berkeley, storage manager zero is magnetic disk, storage .\"manager one is a Sony optical disk jukebox, and storage manager two is .\"main memory. .PP .\"0 The commands below create an (Inversion) large object: 以下のコマンドは(倒置)ラージオブジェクトを生成します。 .nf inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE); .fi .\"0 .SH "Importing a Large Object" .SH "ラージオブジェクトをインポートする" .\"0 To import a UNIX file as a large object, call UNIX ファイルをラージオブジェクトとしてインポートするには、 .nf Oid lo_import(PGconn *conn, text *filename) .fi をコールします。 .\"0 The .I filename .\"0 argument specifies the UNIX pathname of the file to be .\"0 imported as a large object. 引数はラージオブジェクトとしてインポートするファイルの UNIX パス名を指定します。 .\"0 .SH "Exporting a Large Object" .SH "ラージオブジェクトをエクスポートする" .\"0 To export a large object into UNIX file, call ラージオブジェクトを UNIX ファイルにエクスポートするには、 .nf int lo_export(PGconn *conn, Oid lobjId, text *filename) .fi をコールします。 .\"0 The .I lobjId .\"0 argument specifies the Oid of the large object to export .\"0 and the 引数はエクスポートするラージオブジェクトの oid を指定し、 .I filename .\"0 argument specifies the UNIX pathname of the file. はファイルの UNIX パス名を指定します。 .\"0 .SH "Opening an Existing Large Object" .SH 既存のラージオブジェクトをオープンする .PP .\"0 To open an existing large object, call 既存のラージオブジェクトをオープンするには、 .nf int lo_open(PGconn *conn, Oid lobjId, int mode, ...) .fi をコールします。 .\"0 The .I lobjId .\"0 argument specifies the Oid of the large object to open. .\"0 The mode bits control whether the object is opened for reading 引数にはオープンするラージオブジェクトの oid を指定します。 mode ビットには、オブジェクトを読み込みのみ .SM INV_READ ), ( .\"0 writing 書き込みのみ .SM INV_WRITE ), ( .\"0 or both. その両方のどのモードでオープンするかを制御します。 .PP .\"0 A large object cannot be opened before it is created. ラージオブジェクトは生成する前にオープンすることはできません。 .B lo_open .\"0 returns a large object descriptor for later use in は、後に .B lo_read , .B lo_write , .B lo_lseek , .B lo_tell , .\"0 and .B lo_close のいずれかを利用するためのラージオブジェクト識別子を返します。 .\"----------- .\"0 .SH "Writing Data to a Large Object" .SH ラージオブジェクトにデータを書き込む .PP .\"0 The routine ルーチン .nf int lo_write(PGconn *conn, int fd, char *buf, int len) .fi は、 .\"0 writes .\"0 .I len .\"0 bytes from .\"0 .I buf .\"0 to large object .\"0 .I fd . .I buf から .I len バイトをラージオブジェクト .I fd に書き込みます。 .\"0 The .I fd .\"0 argument must have been returned by a previous 引数は、前回の .\"0 .I lo_open からの返り値を指定します。 .PP .\"0 The number of bytes actually written is returned. .\"0 In the event of an error, .\"0 the return value is negative. 実際に書き込まれたバイト数が返ります。エラーが起こった場合は 負数が返ります。 .\"0 .SH "Seeking on a Large Object" .SH ラージオブジェクトをシークする .PP .\"0 To change the current read or write location on a large .\"0 object, call ラージオブジェクトの現在の読み書きの開始位置を変更するには .nf int lo_lseek(PGconn *conn, int fd, int offset, int whence) .fi をコールします。 .\"0 This routine moves the current location pointer for the .\"0 large object described by このルーチンは、 .I fd で指定されたラージオブジェクトの現在の位置ポインタを .\"0 to the new location specified by .I offset で指定された新しい位置に移動します。 .\"0 The valid values for .I whence の有効な値は .\"0 are .SM SEEK_SET .SM SEEK_CUR .\"0 and .SM SEEK_END のいずれかです。 .\"----------- .\"0 .SH "Closing a Large Object Descriptor" ラージオブジェクトをクローズする。 .PP .\"0 A large object may be closed by calling ラージオブジェクトをクローズするには .nf int lo_close(PGconn *conn, int fd) .fi .\"0 where をコールします。ここで、 .I fd は .\"0 is a large object descriptor returned by .I lo_open で返されたラージオブジェクト識別子です。 .\"0 On success, 成功すると .I lo_close .\"0 returns zero. On error, the return value is negative. 0 を返し、エラーの場合負数を返します。 .PP .\"0 .SH "Built in registered functions" .SH 組み込み型で登録された関数 .PP SQL 問い合わせにおいて役立つ、組み込み型で登録された関数 .\"0 There are two built-in registered functions, .I lo_import .\"0 and および .I lo_export .\"0 which are convenient for use in SQL queries. という関数があります。 .PP .\"0 Here is an example of there use これらは以下のようにして使います。 .nf .\"0 CREATE TABLE image ( .\"0 name text, .\"0 raster oid .\"0 ); CREATE TABLE イメージ ( 名前 text, ラスタ oid ); .\"0 INSERT INTO image (name, raster) .\"0 VALUES ('beautiful image', lo_import('/etc/motd')); INSERT INTO イメージ (名前, ラスタ) VALUES ('美しいイメージ', lo_import('/etc/motd')); .\"0 SELECT lo_export(image.raster, '/tmp/motd') from image .\"0 WHERE name = 'beautiful image'; SELECT lo_export(イメージ.ラスタ, '/tmp/motd') from イメージ WHERE 名前 = '美しいイメージ'; .fi .PP .\"0 .SH "Accessing Large Objects from LIBPQ" .SH LIBPQ からラージオブジェクトをアクセスする .\"0 Below is a sample program which shows how the large object .\"0 interface in \*(LP can be used. Parts of the program are .\"0 commented out but are left in the source for the readers .\"0 benefit. This program can be found in 以下に \*(LP におけるラージオブジェクト・インターフェース の使い方に関するサンプル・プログラムを示します。プログラム 中の一部はコメントアウトされていますが、読者に分かりやすい ようにそのまま残してあります。 .nf \&../src/test/examples .fi .PP .\"0 Frontend applications which use the large object interface .\"0 in \*(LP should include the header file \*(LP でラージオブジェクト・インターフェースを使うフロント エンド・アプリケーションは、ヘッダファイル .B "libpq/libpq-fs.h" をインクルードし、 .\"0 and link with the .B libpq .\"0 library. ライブラリをリンクしなければなりません。 .bp .\"0 .SH "Sample Program" .SH サンプル・プログラム .nf /*------------------------------------------------------------------------- * * testlo.c-- * test using large objects with libpq * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /usr/local/cvsroot/pgsql/src/man/large_objects.3,v 1.6 1998/03/23 15:09:29 momjian Exp $ * *------------------------------------------------------------------------- */ #include #include "libpq-fe.h" #include "libpq/libpq-fs.h" #define BUFSIZE 1024 /* * importFile - .\"0 * import file "in_filename" into database as large .\"0 object "lobjOid" * ファイル "in_filename" を、データベースにラージオブジェクト * "lobjOid" としてインポートする * */ Oid importFile(PGconn *conn, char *filename) { Oid lobjId; int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* .\"0 * open the file to be read in * 読み込むファイルをオープンする */ fd = open(filename, O_RDONLY, 0666); if (fd < 0) { /* error */ .\"0 fprintf(stderr, "can't open unix file\\"%s\\"\\n", filename); fprintf(stderr, "UNIX ファイル \\"%s\\" がオープンできない\\n", filename); } /* .\"0 * create the large object * ラージオブジェクトを生成する */ lobjId = lo_creat(conn, INV_READ|INV_WRITE); if (lobjId == 0) { .\"0 fprintf(stderr, "can't create large object"); fprintf(stderr, "ラージオブジェクトを生成できません"); } lobj_fd = lo_open(conn, lobjId, INV_WRITE); /* .\"0 * read in from the Unix file and write to the inversion file * UNIX ファイルから読み込み、倒置ファイルに書き出す */ while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { tmp = lo_write(conn, lobj_fd, buf, nbytes); if (tmp < nbytes) { .\"0 fprintf(stderr, "error while reading \\"%s\\"", filename); fprintf(stderr, "読み込み中にエラー発生 \\"%s\\"", filename); } } (void) close(fd); (void) lo_close(conn, lobj_fd); return lobjId; } void pickout(PGconn *conn, Oid lobjId, int start, int len) { int lobj_fd; char* buf; int nbytes; int nread; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) { .\"0 fprintf(stderr,"can't open large object %d", lobjId); fprintf(stderr,"ラージオブジェクトをオープンできません %d", lobjId); } lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len+1); nread = 0; while (len - nread > 0) { nbytes = lo_read(conn, lobj_fd, buf, len - nread); buf[nbytes] = '\\0'; fprintf(stderr,">>> %s", buf); nread += nbytes; } fprintf(stderr,"\\n"); lo_close(conn, lobj_fd); } void overwrite(PGconn *conn, Oid lobjId, int start, int len) { int lobj_fd; char* buf; int nbytes; int nwritten; int i; lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) { .\"0 fprintf(stderr,"can't open large object %d", lobjId); fprintf(stderr,"ラージオブジェクトをオープンできません %d", lobjId); } lo_lseek(conn, lobj_fd, start, SEEK_SET); buf = malloc(len+1); for (i=0;i 0) { nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); nwritten += nbytes; } fprintf(stderr,"\\n"); lo_close(conn, lobj_fd); } /* * exportFile - * export large object "lobjOid" to file "out_filename" * */ void exportFile(PGconn *conn, Oid lobjId, char *filename) { int lobj_fd; char buf[BUFSIZE]; int nbytes, tmp; int fd; /* .\"0 * create an inversion "object" * 倒置 "オブジェクト" を生成する */ lobj_fd = lo_open(conn, lobjId, INV_READ); if (lobj_fd < 0) { .\"0 fprintf(stderr,"can't open large object %d", lobjId); fprintf(stderr,"ラージオブジェクトをオープンできません %d", lobjId); } /* .\"0 * open the file to be written to * 書き込むファイルをオープンする */ fd = open(filename, O_CREAT|O_WRONLY, 0666); if (fd < 0) { /* error */ .\"0 fprintf(stderr, "can't open unix file\\"%s\\"", filename); fprintf(stderr,"Unix ファイルをオープンできません\\"%s\\"", lobjId); } /* .\"0 * read in from the Unix file and write to the inversion file * Unix ファイルを読み込んで倒置ファイルに書き出す */ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp < nbytes) { .\"0 fprintf(stderr,"error while writing \\"%s\\"", .\"0 filename); fprintf(stderr,"書き込み中にエラー発生 \\"%s\\"", filename); } } (void) lo_close(conn, lobj_fd); (void) close(fd); return; } void exit_nicely(PGconn* conn) { PQfinish(conn); exit(1); } int main(int argc, char **argv) { char *in_filename, *out_filename; char *database; Oid lobjOid; PGconn *conn; PGresult *res; if (argc != 4) { fprintf(stderr, .\"0 "Usage: %s database_name in_filename out_filename\\n", "使用法: %s データベース名 入力ファイル 出力ファイル\\n", argv[0]); exit(1); } database = argv[1]; in_filename = argv[2]; out_filename = argv[3]; /* .\"0 * set up the connection * コネクションを確立する */ conn = PQsetdb(NULL, NULL, NULL, NULL, database); .\"0 /* check to see that the backend connection was .\"0 successfully made */ /* バックエンドへのコネクションが成功したかをチェック */ if (PQstatus(conn) == CONNECTION_BAD) { .\"0 fprintf(stderr,"Connection to database '%s' failed.\\n", database); fprintf(stderr,"データベース '%s' へのコネクション失敗\\n", database); fprintf(stderr,"%s",PQerrorMessage(conn)); exit_nicely(conn); } res = PQexec(conn, "begin work;"); PQclear(res); .\"0 printf("importing file \\"%s\\" ...\\n", in_filename); printf("ファイル \\"%s\\" をインポートしています...\\n", in_filename); /* lobjOid = importFile(conn, in_filename); */ lobjOid = lo_import(conn, in_filename); /* printf("\\tas large object %d.\\n", lobjOid); .\"0 printf("picking out bytes 1000-2000 of the large object\\n"); printf("ラージオブジェクトの 1000-2000 バイト目を 取り出しています\\n"); pickout(conn, lobjOid, 1000, 1000); .\"0 printf("overwriting bytes 1000-2000 of the large object with X's\\n"); printf("ラージオブジェクトの 1000-2000 バイト目を 書き込んでいます\\n"); overwrite(conn, lobjOid, 1000, 1000); */ .\"0 printf("exporting large object to file \\"%s\\" ...\\n", .\"0 out_filename); printf("ラージオブジェクトをファイル \\"%s\\" に書き込んでいます...\\n", out_filename); /* exportFile(conn, lobjOid, out_filename); */ lo_export(conn, lobjOid,out_filename); res = PQexec(conn, "commit;"); PQclear(res); PQfinish(conn); exit(0); } .fi .SH 翻訳者 堀田 倫英