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を 返します。
アプリケーションでは、新しく読み込んだ行がピリオド一文字(".")であるか どうかの確認を必ず行わなければなりません。この文字は copyコマンドの結果をバックエンドサーバが送信し 終えたことを示すものです。したがって length-1 文字を超える行の受信が想定されるのであれば、アプリケーションは PgDatabase::GetLineが返す値をよく注意して、 確実にチェックを行わなければなりません。
PgDatabase::PutLineは、NULL終端の文字列 string をバックエンドサーバに送信します。
void PgDatabase::PutLine(char* string)
アプリケーションはデータ送信の完了をバックエンドに示すために、 ピリオド一文字(".")を明示的に送信しなければなりません。
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 double precision)"); 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();