PostgreSQLのバックエンドサーバとの接続を作成するには、以下のルーチンを使用します。アプリケーションプログラムは、バックエンドとの接続を一度に複数個開くことができます(1つの理由として、複数のデータベースへのアクセスが挙げられます)。個々の接続は、PQconnectdb または PQsetdbLoginを呼び出すことで得られる PGconn オブジェクトによって表されます。なおこれらの関数は、PGconn オブジェクトに割り当てるほんのわずかなメモリの余裕さえもない場合を除き、NULL ではなく常にオブジェクトのポインタを返します。またこの接続オブジェクトを通じて問い合わせを送る前に、PQstatus を呼び出して、データベースとの接続に成功したかどうかをチェックすべきでしょう。
PQconnectdb データベースサーバーとの接続を新たに確立します。
PGconn *PQconnectdb(const char *conninfo)
このルーチンは、conninfo 文字列を引数に指定することによって、データベースとの接続を新たに1つ確立します。後述の PQsetdbLogin とは異なり、関数のプロトタイプを変更せずに引数を拡張できるので、アプリケーションプログラムを作成する際には、このルーチンか、もしくは非ブロックモードでよく似た処理をする PQconnectStart/PQconnectPoll を使用することをお勧めします。空の文字列を渡すことで、全てのパラメータはデフォルトを使用します。また、空白文字で区切ることで1つ以上のパラメータを設定することができます。
すべてのパラメータは、keyword = valueという形で設定します(空の値や空白文字を含む値を書く場合は、単一引用符で囲みます。たとえば、 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(デフォルト)を指定すると、通常のサーバとの通信になります。
どのパラメータも指定されなかった場合、該当する環境変数をチェックします(Section 1.10を参照)。環境変数も設定されていない場合は、環境に組み込みのデフォルト値が使用されます。返り値は、バックエンドとの接続を表した、抽象的な構造体へのポインタです。
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()を、login と pwd に NULL ポインタを指定して呼び出すマクロです。これは主に古いプログラムとの互換性を提供するものです。
PQconnectStart, PQconnectPoll 非ブロック形式でデータベースサーバとの接続を確立します。
PGconn *PQconnectStart(const char *conninfo)
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
これら2つのルーチンを使用すると、ネットワーク経由の入出力処理をしている間もアプリケーションの実行スレッドがブロックされないように、データベースサーバとの接続を開始することができます。
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(conn) が PGRES_POLLING_READING を返したら、PQsocket(conn) での読み込みをチェックする select() を実行します。もし返り値が PGRES_POLLING_WRITING であれば、PQsocket(conn) での書き込みをチェックする select() を実行します。また PQconnectPoll をまだ呼び出していないとき、つまり、 PQconnectStart を呼び出した後は、直前の返り値が PGRES_POLLING_WRITING の場合と同じようにします。select() を実行した結果、ソケットの準備ができているようであれば、接続が "アクティブ" になったと思ってください。接続が "アクティブ" になったことが決まったら、もう一度 PQconnectPoll(conn) を呼び出します。もし、この返り値が PGRES_POLLING_FAILED の場合は、接続プロシージャは失敗しています。 PGRES_POLLING_OKの場合は、接続に成功しています。
ソケットの準備ができたことを保証するために select() が実行されるのは、単純な例(のようなもの)であることに注意してください。他のもの(たとえば poll() 呼び出し)が使用できるのであれば、そちらが使用されることもあり得ます。
接続している間は、いつでも PQstatus を呼び出すことで、接続の状態をチェックすることができます。もし、CONNECTION_BAD であるならば、接続プロシージャは失敗しており、CONNECTION_OK なら、成功しています。前に示したように、このいずれの状態も、PQconnectPoll の返り値から、同じように気づかなければいけません。これ以外の状態は、非同期の接続プロシージャの間(やその間だけ)現れることがあります。これらは、接続プロシージャの現在の段階を示すものであり、例えばユーザへのフィードバックを提供することに使用できます。以下のステータスがあります。
接続が確立するのを待っています。
接続はOKです。送信されるのを待っています。
サーバからの応答を待っています。
認証済みです。バックエンドが起動するのを待っています。
環境とやりとりしています(接続開始処理の一部です)。
これらの定数は消えることはありません(互換性を保つため)が、アプリケーションは、これらが特定の順で出現したり、ドキュメントに書いてある値のどれかに必ずステータス値が該当するということを決して当てにしてはいけません。アプリケーションは、以下に示すようにするべきです。
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 は使用できません。この制限はなくなる予定です。
これらの関数は、あたかも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 構造体の配列へのポインタで、keyword ポインタが NULL となる項目が配列の末尾にきます。( val フィールドの)デフォルト値は、環境変数や他のコンテキストに依存します。呼び出し側では、接続オプションの情報は、読み込み専用として取り扱わなければいけません。
オプションの配列を処理した後は、PQconninfoFreeを使用して解放します。この処理をしないと、PQconndefaultsが呼び出されるたびに少しずつメモリを浪費します。
バージョン7.0以前のPostgreSQL では、 PQconndefaultsは動的に割り当てられた配列ではなく、静的な配列へのポインタを返していました。これはスレッドセーフではなかったので、変更されました。
PQfinish バックエンドとの接続を閉じます。同時にPGconn オブジェクトに使われていたメモリを解放します。
void PQfinish(PGconn *conn)
たとえバックエンドとの接続が失敗したとしても(PQstatus で調べます)、アプリケーションはPQfinishを呼び出し PGconn オブジェクトが占めるメモリを解放するべきです。そして PQfinish を呼び出したら、もう PGconnへのポインタを使ってはいけません。
PQreset バックエンドとの通信用ポートをリセットします。
void PQreset(PGconn *conn)
この関数はバックエンドとの接続を閉じ、それから再度同じサーバと新たな接続を確立しようとします。パラメータは前回と同じものを使います。これは稼働中の接続が失われた場合のエラーリカバリに役立つでしょう。
PQresetStart PQresetPoll ブロックしない方法で、バックエンドとの通信用ポートをリセットします。
int PQresetStart(PGconn *conn);
PostgresPollingStatusType PQresetPoll(PGconn *conn);
これらの関数はバックエンドとの接続を閉じ、それから再度同じサーバと新たな接続を確立しようとします。パラメータは前回と同じものを使います。これらは稼働中の接続が失われた場合のエラーリカバリに役立つでしょう。 PQreset(前述)との違いは、この2つの関数が非ブロック作法で動作することです。また、PQconnectStartやPQconnectPoll と同じ制限を受けます。
PQresetStartを呼び出して、0を返したら、リセットに失敗しています。返り値が1ならば、PQconnectPollを使って接続を確立したときと同じように、PQresetPollを使用してリセットをします。
libpqアプリケーションプログラマは PGconn による抽象化に注意を払うべきです。 PGconn の内容は以下に挙げるアクセッサ関数を使って取り出してください。PGconn構造体中のフィールドは将来予告なく変更されることがあります。ですから直接フィールドを参照することは避けてください(PostgreSQLリリース 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)
ステータスは、数多くの値の中の1つをとります。しかし、 CONNECTION_OK と CONNECTION_BAD の 2 つのステータス値だけは、非同期の接続プロシージャの側面を見せます。データベースへの接続が良好なときはステータスが 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);
この構造体は、暗号化のレベルの照合やサーバーの認証のチェックなどに役立ちます。この構造体については、SSL のドキュメントを参照してください。
この関数のプロトタイプを得るには、USE_SSLを定義してください。こうすると、OpenSSL の ssl.h も自動的にインクルードされます。