libpq は C 言語のアプリケー ションプログラマ用の Postgresインタフェー スです。 libpq は クライアントプログラムから Postgres のバックエンドサーバへ 問い合わせを渡し、その結果を受け取るためのライブラリルーチンの集合 です。 libpq はlibpq++ (C++)や libpgtcl (Tcl)、 Perl、 ecpgなどを含む、他の Postgresのアプリケーションインタフェース を支えるエンジンでもあります。 ですので、libpq が振る舞う様は、これらのインタフェースパッケージを 使用する人にとって重要なものになります。
このセクションの最後には、 libpq の使い方を示す、三つの短いプログラムを載せ ておきました。 また以下に示すディレクトリに、libpqを利用し たアプリケーションプログラムの完全な例があります。
../src/test/regress ../src/test/examples ../src/bin/psql
libpq を使用してフロントエンドプログラムを作成 するには、ヘッダファイル libpq-fe.h のインクル ードと、libpq のライブラリとのリンクが必要 です。
Postgres のバックエンドサーバとの接続を 作成するには、以下のルーチンを使用します。 アプリケーションプログラムは、バックエンドとの接続を一度に複数個開 くことができます。 (一つの理由として、複数のデータベースへのアクセスが挙げられます。) 個々の接続は、PQconnectdb または PQsetdbLogin を呼び出すことで得られる PGconnオブジェクトによって表されます。 なおこれらの関数は、PGconn オブジェクトに割り当てる ほんのわずかなメモリの余裕さえもない場合を除き、NULL ではなく常にオ ブジェクトのポインタを返します。 またこのコネクションオブジェクトを通じて問い合わせを送る前に、 PQstatus を呼び出して、データベースとの接続に成功した かどうかをチェックすべきでしょう。
PQconnectdb データベースサーバとの接続を新たに確立します。
PGconn *PQconnectdb(const char *conninfo)このルーチンは、conninfo 形式の文字列をパラメー タに指定することによって、データベースとの接続を新たに一つ確立しま す。PQsetdbLogin()とは異なり、関数のプロトタイプを変更せずに引数を 拡張できるので、アプリケーションプログラムを作成する際には、このル ーチンか、もしくは非ブロックモードでよく似た処理をする PQconnectStart / PQconnectPoll を使用することをお勧めします。
全てのパラメータは、keyword = valueという形で設 定します。(NULL値やスペースを含む値を書く場合は、シングルクォートで 囲みます。例えば、keyword = 'a value' といった具 合です。値がシングルクォートを含む場合は、 \' と いうように書かなくてはいけません。等号の前後のスペースは、任意で付 けられます。) 有効なパラメータのキーワードは以下に示すとおりです。
接続するホスト名を指定します。 この引数をスラッシュで始めた場合、TCP/IPによる通信ではなく、 Unixドメインの通信を明示することになります。 hostの値はソケットファイルが保存されているデ ィレクトリの名前になります。 デフォルトでは、/tmpにある Unix ドメインの ソケットに接続します。
接続するホストのIPアドレスを指定します。 これは、一般的な数字とピリオドを組み合わせた形になっています。 BSDのinet_aton関数やそれに相当するものが使用するものと同じ形式です。 長さが0でない文字列が指定されると、TCP/IP通信が使用されます。
host の代わりに hostaddr を使用することで、アプリケーションがホ スト名の検索をせずに済みます。特に、時間に制約のあるアプリケーショ ンでは、重要になるでしょう。しかし、Kerberos 認証を行うアプリケー ションでは、ホスト名が必要になります。結局、以下のようになります。 hostaddrを使わず、hostを使用した場合は、ホスト名からのIPアドレス検索が強制的に 実行されます。hostを使わず、hostaddrを使用した場合、hostaddrはリ モートマシンのIPアドレスとなります。この時、Kerberosを使用してい る場合は、IPアドレスからホスト名の逆引きが行われます。 host と hostaddrの両方を使用した場合、 hostaddrがリモートマシンのIPアドレスとなります。 この時、Kerberosが使用されていない場合はhostに与えられた値は無視され、 使用されている場合はKerberos認証にhostの値が使用されます。 libpqに渡されたホスト名が、hostaddrに対応するマシンの名前が一致しない場合は、 認証に失敗する可能性があるので、注意してください。
ホスト名もホストのアドレスも用いない場合、libpqはローカルの UNIX ドメインのソケットを使用して接続します。
サーバホストでの接続用のポート番号、または、UNIXドメイン接続の場 合はソケットファイルの拡張子を指定します。
データベース名を指定します。
データベースへ接続するユーザ名を指定します。
サーバがパスワードによる認証を必要としたときに使用されるパスワー ドを指定します。
サーバに送る、トレース/デバッグオプションを指定します。
バックエンドからのデバッグ出力のためのファイル、またはttyを指定 します。
'1'を設定すると、SSL接続をバックエンドに要求します。 サーバがSSLをサポートしていない場合、libpq は接続を拒否します。 '0'(デフォルト)を指定すると、通常のサーバとの通信になります。
PQsetdbLogin 新たにデータベースサーバとの接続を確立します。
PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)これは、PQconnectdb の前にあったもので、パラメー タの数が固定ですが、機能的には同じものです。
PQsetdb 新たにデータベースサーバとの接続を確立します。
PGconn *PQsetdb(char *pghost, char *pgport, char *pgoptions, char *pgtty, char *dbName)これは PQsetdbLogin() を、ログイン名とパスワー ドに NULL ポインタを指定して呼び出すマクロです。 古いプログラムとの互換性を提供します。
PQconnectStart, PQconnectPoll 非ブロック形式でデータベースサーバとの接続を確立します。
PGconn *PQconnectStart(const char *conninfo)
PostgresPollingStatusType PQconnectPoll(PGconn *conn)これらの二つルーチンを使用すると、 リモートホストで I/O 処理をしている間もアプリケーション実行スレッド がブロックされないように、データベースサーバとの接続を開始する ことができます。
PQconnectStartに渡された conninfo文字列からパラメータを取得し、 データベース接続が生成されます。 この文字列は、PQconnectdbの場合と同じ形式で記述されています。
PQconnectStart と PQconnectPoll は、以下の制限下ではブロックしませ ん。
hostaddr と host パラメータは、ホスト名からのIPアドレス検索やホスト名の逆引き が起こらないように適切に使用されなければなりません。 これらのパラメータについての詳細は、前述の PQconnectdb の節をご 覧ください。
PQtraceを呼び出す場合は、使用するストリームオブジェクトがブロッ クされない事が保証されていなくてはなりません。
プログラマ自身が、後に示すように、PQconnectPollを呼び出す前にソ ケットが適切な状態にあることを保証しなくてはなりません。
まず始めに、 conn=PQconnectStart("<connection_info_string>") を呼び出します。 connが NULLである場合、libpqは新たに PGconn 構造体を割り当てること に失敗したことをあらわします。そうでない場合は、適切な PGconn へのポインタが返され ます (ただし、データベースに正しく接続されていることを表しているわ けではありません)。PQconnectStartから値が帰ってきた段階で、 status=PQstatus(conn)を呼び出します。もし、statusがCONNECTION_BADと 等しい場合には、PQconnectStartが失敗しています。
PQconnectStartが成功したら、次は接続シーケンスを進めるために、libpq を調査します。 以下のくり返しです。 接続はデフォルトでは「非アクティブ」状態だと判断されます。もし、 PQconnectPoll がPGRES_POLLING_ACTIVEを返したら、接続が「アクティブ」 状態だと判断します。PQconnectPollが最終的にPGRES_POLLING_READINGを返 したら、PQsocket(conn)での読み込みをチェックする select を実行して ください。 もし返り値がPGRES_POLLING_WRITINGであれば、PQsocket(conn)での書き込 みをチェックする selectを実行してください。また PQconnectPollをまだ 呼び出していないときは、返り値がPGRES_POLLING_WRITINGの場合と同じよ うにしてください。 select を実行した結果、ソケットの準備ができているようであれば、接続 が「アクティブ」になったと思ってください。接続が「アクティブ」になっ たことが決まったら、もう一度 PQconnectPoll(conn)を呼び出します。 もし、PQconnectPollの返り値が PGRES_POLLING_FAILEDの場合は、接続プ ロシージャは失敗しています。 PGRES_POLLING_OK の場合は、接続に成功 しています。
ソケットの準備が出来たことを保証するために select() が実行されるの は、単純な例(のようなもの)であることに注意してください。他のもの (例えば poll() 呼び出し)が使用できるのであれば、そちらが使用される ことも起こり得ます。
接続している間は、いつでも PQstatus を呼び出すことで、接続の状態を チェックすることができます。もし、CONNECTION_BADであるならば、接続 プロシージャは失敗しており、CONNECTION_OK なら、成功しています。前 に示したように、このいずれの状態も、PQconnectPoll の返り値から、同 じように気づかなければなりません。これ以外の状態は、非同期の接続プ ロシージャの間(やその間だけ)あらわれることがあります。
CONNECTION_STARTED: 接続が確立するのを待っています。
CONNECTION_MADE: 接続は OK です。送信されるのを待っています。
CONNECTION_AWAITING_RESPONSE: postmasterからの応答を待っています。
CONNECTION_AUTH_OK: 認証済です。バックエンドが起動するのを待って います。
CONNECTION_SETENV: 環境とやりとりしています。
switch(PQstatus(conn)) { case CONNECTION_STARTED: feedback = "Connecting..."; break; case CONNECTION_MADE: feedback = "Connected to server..."; break; . . . default: feedback = "Connecting..."; }
PQconnectStartがNULLでないポインタを返した場合、処理を終了する際に は、構造体や関連するメモリブロックを始末するために、PQfinish を呼 び出さなくてはなりません。 この処理は、PQconnectStart や PQconnectPoll の呼び出しに失敗した場 合にも、必ず実行されなければなりません。
libpq が USE_SSL を定義してコンパイルされた場合、現在は PQconnectPoll は使用できません。この制限は、無くなる予定です。
libpq が WIN32_NON_BLOCKING_CONNECTIONS を定義せずにコンパイルされ た場合、現在の PQconnectPoll は Windows 環境下で使用できません。 このコードはまだ Windows 環境下でテストされておらず、そのため、デフォ ルトでは off になっています。この点も、変更される予定です。
これらの関数は、あたかもPQsetnonblockingが呼び 出されたかのように、非ブロック状態のソケットを残します。
PQconndefaults デフォルトの接続オプションを返 します。
PQconninfoOption *PQconndefaults(void) struct PQconninfoOption { char *keyword; /* オプションのキーワード */ char *envvar; /* 代替となる環境変数の名前 */ char *compiled; /* コンパイル時に組み込まれた 代替となるデフォルト値 */ char *val; /* オプションの現在値かNULL */ char *label; /* 接続ダイアログの当該フィールドのラベル */ char *dispchar; /* 接続ダイアログの当該フィールドに表示する文字 値: "" 入力された通りの文字列を表示 "*" パスワードフィールド:値を隠す "D" デバッグ用オプション:デフォルトで は表示されない */ int dispsize; /* ダイアログ上のフィールドの大きさ(文字数) */ }接続オプションの配列を返します。 この関数は、使用可能な PQconnectdb のオプションの全てや、その時点で のデフォルト値を決定するために使用することが出来ます。 返り値は、PQconninfoOption 構造体の配列へのポインタで、NULL文字のポ インタが配列の末尾にきます。 ("val"フィールドの)デフォルト値は、環境変数や他のコンテキストに依存 します。呼び出し側では、接続オプションの情報は、読み込み専用として 取り扱わなければなりません。
オプションの配列を処理した後は、PQconninfoFree()を使用して、開放し ます。この処理をやらないと、PQconndefaults()が呼び出される度に、少 しずつメモリを浪費します。
バージョン 7.0以前の Postgres では、PQconndefaults()は動的に割り当 てられた配列ではなく、静的な配列へのポインタを返していました。 これはスレッドセーフではなかったので、変更されました。
PQfinish バックエンドとの接続を閉じます。同時に PGconn オブジェクトに使われ ていたメモリを開放します。
void PQfinish(PGconn *conn)たとえバックエンドとの接続が失敗したとしても (PQstatusで調べます)、 アプリケーションは PQfinishを呼び出し PGconn オブジェクトが占めるメモリを開放するべきです。 そして PQfinish を呼び出したら、もう PGconn へのポインタを使っては いけません。
PQreset バックエンドとのコミュニケーションポートをリセットします。
void PQreset(PGconn *conn)この関数はバックエンドとの接続を閉じ、それから再度同じ postmaster と新たな接続を確立しようとします。パラメータは前回と同じものを使い ます。これは稼働中の接続が失われた場合のエラーリカバリに役立つでしょ う。
PQresetStart PQresetPoll バックエンドとのコミュニケーションポートを、非ブロック形式でリセッ トします。
int PQresetStart(PGconn *conn);
PostgresPollingStatusType PQresetPoll(PGconn *conn);これらの関数はバックエンドとの接続を閉じ、それから再度同じ postmasterと新たな接続を確立しようとします。パラメータは前回と同じ ものを使います。これらは稼働中の接続が失われた場合のエラーリカバリ に役立つでしょう。 (前述の)PQresetとの違いは、この二つの関数が非ブロック作法で動作す ることです。また、PQconnectStart や PQconnectPoll と同じ制限を受け ます。
PQresetStartを呼び出して、0 を返したら、リセットに失敗しています。 返り値が 1 ならば、PQresetPollを使用して、PQconnectPoll を使って 接続を確立したときと丁度同じように、リセットをします。
libpq アプリケーションプログラマは PGconn による抽象化に注意を払うべき です。 PGconn の内容は以下に挙げるアクセッサ関数を使って取り出してくだ さい。 PGconn 構造体中のフィールドは将来予告なく変更されることがありま す。 ですから直接フィールドを参照することは避けてください。 (Postgresリリース 6.4 の初期の段階から、 PGconn 構造体の定義をlibpq-int.hの中から外しまし た。以前作成したプログラムが PGconn のフィールドを直接操作している場合、 libpq-int.h をインクルードすれば使い続けることが できます。しかしそのプログラムは是非とも修正してください。
PQdb 当該接続のデータベース名を返します。
char *PQdb(const PGconn *conn)PQdbと以下のいくつかの関数は、接続時に確定した値を返します、これらの値 は PGconn オブジェクトの寿命の間一定です。
PQuser 当該接続のユーザ名を返します。
char *PQuser(const PGconn *conn)
PQpass 当該接続のパスワードを返します。
char *PQpass(const PGconn *conn)
PQhost 当該接続のサーバホスト名を返します。
char *PQhost(const PGconn *conn)
PQport 当該接続のポート番号を返します。
char *PQport(const PGconn *conn)
PQtty 当該接続のデバッグ用 tty を返します。
char *PQtty(const PGconn *conn)
PQoptions 当該接続の、バックエンドオプションを返します。
char *PQoptions(const PGconn *conn)
PQstatus 当該接続のステータスを返します。
ConnStatusType PQstatus(const PGconn *conn)
ステータスは、数多くの値の中の一つをとります。 しかし、CONNECTION_OK ないし CONNECTION_BAD二つのステータス値だけは、非同 期の接続プロシージャの側面を見せます。 データベースへの接続が良好なときはステータスがCONNECTION_OKとな ります。 接続の失敗は、普通CONNECTION_BADで通知されま す。OKステータスは、PQfinishが呼び出される まで残りますが、バックエンドとの通信はステータスが途中で CONNECTION_BADに変わった時に、失敗に終ること があります。 そのような場合、アプリケーションの方で PQresetを呼び出すことで、復旧を試すことが できます。
他の表示される可能性のあるステータスコードについては、 PQconnectStart と PQconnectPoll の節をご覧ください。
PQerrorMessage 当該接続上で最後に出力された操作上のエラーメッセージを返します。
char *PQerrorMessage(const PGconn* conn);
ほぼすべての libpq 関数は動作に失敗したとき PQerrorMessage の内容を設定します。 なお PQerrorMessage は libpq の慣習に従い、 空文字列でなければ末尾に改行を含みます。
PQbackendPID 当該接続を維持するバックエンドサーバのプロセス IDを返します。
int PQbackendPID(const PGconn *conn);バックエンドの PID は、デバッグする場合や 通知 (NOTIFY) メッセージ(これは通知を発行したバックエン ドの PID を含んでいます)の比較に便利です。 この PID はデータベースサーバ上で実行されて いるプロセスのものであり、ローカルホスト側のものではありません! 注意してください。
PQgetssl 当該接続で使用されている、SSL 構造体を返します。SSL が使用され ていない場合は、NULLを返します。
SSL *PQgetssl(const PGconn *conn);この構造体は、暗号化のレベルの照合やサーバの認証のチェックなど に役立ちます。この構造体については、OpenSSL のドキュメントを参 照してください。
この関数のプロトタイプを得るには、USE_SSL を定義してください。こうすると、OpenSSLの ssl.hも自動的にインクルードされます。