Postgres の COPY コマンドは, libpq++ が使っているネットワーク接続に対して読み込み, あるいは書き込みを選ぶことができるようになっています. そこでこのネットワーク接続に直接アクセスするための関数が必要になります. もちろんアプリケーションもこの機能によって十分な恩恵を受けるでしょう.
PgDatabase::GetLine は改行で終端する文字列(バックエンドから送信されたもの)を長さ length のバッファ string に読み込みます.
int PgDatabase::GetLine(char* string, int length)
Unix システムルーチン fgets(3) と同様, このルーチンは string に最大 (length-1) 個の文字をコピーします.しかし終端の改行が NULL 文字に置き換えられる点では gets(3) に似ています.
PgDatabase::GetLine はファイル終端で EOF を, 行全体が読み込まれれば 0 を返します. そして,まだ終端の改行が読み込まれていないうちにバッファがいっぱいに なってしまった場合は 1 を返します.
アプリケーションは新しく読み込んだ行が, ピリオド一文字 (".") であるかどうか確認しなければなりません. [1] この文字は COPY コマンドの結果をバックエンドサーバが送信し終えたことを示すものです. したがって (length-1) 文字を超える行の受信が想定されるのであれば, アプリケーションは PgDatabase::GetLine が返す値をよく注意して,確実にチェックしなければなりません.
PgDatabase::PutLine NULL 終端の文字列 string をバックエンドサーバに送信します.
void PgDatabase::PutLine(char* string)
アプリケーションはデータ送信の完了をバックエンドに示すために, ピリオド一文字 (".") を明示的に送信しなければなりません. [1]
PgDatabase::EndCopy バックエンドと同期します.
int PgDatabase::EndCopy()この関数はバックエンドが COPY 処理を完了するのを待ちます. この関数は PgDatabase::PutLine を使ったバックエンドへの文字列送信が完了した時点, あるいは PgDatabase::GetLine を使ったバックエンドからの文字列受信が完了した時点の, いずれでも呼び出さなければなりません. さもないと,バックエンドがフロントエンドとの「同期ずれ」 を起こしてしまうかもしれません. この関数から戻った時点で,バックエンドの次の問い合わせを受ける準備が整います.
同期が成功すれば 0 を,そうでなければ 0 以外の値を返します.
一例です:
PgDatabase.data; data.Exec("create table foo (a int4, b char(16), d float8)"); data.Exec("copy foo from stdin"); data.PutLine("3\tHello World\t4.5\n"); data.PutLine("4\tGoodbye World\t7.11\n"); &... data.PutLine(".\n"); data.EndCopy();
[1] | 訳注: 6.5.3 では libpq と同じ "\." で実際には完了するようです. example ディレクトリの testlibpq6.cc 参照. |