30.1. データベース接続制御関数

PostgreSQLのバックエンドサーバとの接続を作成するには、以下の関数を使用します。 アプリケーションプログラムは、バックエンドとの接続を一度に複数個開くことができます。(1つの理由として、複数のデータベースへのアクセスが挙げられます。) 個々の接続は、PQconnectdbまたはPQsetdbLogin関数を呼び出すことで得られるPGconnオブジェクトによって表されます。 なお、これらの関数は、PGconnオブジェクトに割り当てるほんのわずかなメモリの余裕さえもない場合を除き、NULLではなく常にオブジェクトのポインタを返します。 また、この接続オブジェクトを通じて問い合わせを送る前に、PQstatus関数を呼び出して、データベースとの接続に成功したかどうかをチェックされなければなりません。

警告

Unix上で、開いたlibpq接続でのプロセスの分岐(フォーク)は、親と子のプロセスが同じソケットとオペレーティングシステムの資源を共有するため、予期せぬ結果を招くことがあります。この理由により、新規実行形式を子プロセスが読み込むためexecを行なうことが安全と言っても、このような使用法は推奨されません。

注意: Windowsでは、単一のデータベース接続が反復して開始と終了を繰り返す場合、性能を向上させる方法があります。内部的には、接続開始と終了に対して、それぞれlibpqはWSAStartup()とWSACleanup()を呼び出します。WSAStartup()はWSACleanup()で値が減少させられた内部Windowsライブラリ参照カウントを増加させます。参照カウントがたった1の場合、WSACleanup()呼び出しは全てのリソースを解放し、全てのDLLはアンロードされます。これは高価な操作です。これを回避するには、最後のデータベース接続が閉じられる時、リソースが開放されないようにアプリケーションが手動でWSAStartup()を呼び出すことができます。

PQconnectdb

新たにデータベースサーバへの接続を作成します。

        PGconn *PQconnectdb(const char *conninfo);
       

この関数は、conninfo文字列から取得したパラメータを使用して、データベースとの接続を新たに1つ確立します。 後述のPQsetdbLoginとは異なり、関数のプロトタイプを変更せずにパラメータを拡張できますので、アプリケーションプログラムを作成する際には、このルーチン(もしくは非ブロックモードでよく似た処理をするPQconnectStartPQconnectPoll)を使用することをお勧めします。

空の文字列を渡すことで、全てのパラメータはデフォルトを使用できます。 また、空白文字で区切ることで1つまたはそれ以上のパラメータを設定することができます。 それぞれのパラメータは、keyword = valueという形で設定します。 等号の前後の空白文字は、任意で付けられます。 空の値や空白文字を含む値を書く場合は、単一引用符で囲みます。 例えば、keyword = 'a value'といった具合です。 値中の単一引用符とバックスラッシュは\'\\というように、バックスラッシュでエスケープしなければなりません。

現時点で有効なパラメータのキーワードは以下に示す通りです。

host

hostaddr

接続するホストのIPアドレスを指定します。これは、172.28.40.9といった標準的なIPv4アドレス書式でなければなりません。 使用するマシンでIPv6をサポートする場合は、そのアドレスを使用することもできます。 このパラメータに非空の文字列が指定されると、TCP/IP通信が常に使用されます。

hostの代わりにhostaddrを使用することで、アプリケーションがホスト名の検索を行なわずに済みます。 特に、時間の制約があるアプリケーションでは、重要になるでしょう。 しかし、KerberosおよびGSSAPI認証を行うアプリケーションでは、ホスト名が必要になります。 結局、以下のようになります。 hostaddrを使わずにhostを指定した場合は、ホスト名の検索が発生します。 hostを使わず、hostaddrを指定した場合、hostaddrはリモートマシンのアドレスとなります。 この時、Kerberosを使用している場合は、IPアドレスからホスト名の逆引きが行われます。 hosthostaddrの両方を指定した場合、hostaddrがリモートマシンのアドレスとなります。 この時、Kerberosが使用されていない場合はhostに与えられた値は無視され、使用されている場合はKerberos認証にhostの値が使用されます。(libpqに渡されたホスト名が、hostaddrに対応するマシンの名前と一致しない場合は、認証に失敗する可能性があるので注意してください。) また、hostaddrではなくhost~/.pgpass(項30.14を参照)での接続の識別に使用されます。

ホスト名もホストのアドレスも用いない場合、libpqはローカルのUnixドメインソケットを使用して接続します。 ただし、Unixドメインソケットを持たないマシンでは、localhostへの接続を試みます。

port

サーバホストでの接続用のポート番号、または、Unixドメイン接続の場合は、ソケットファイルの拡張子を指定します。

dbname

データベース名を指定します。 デフォルトはユーザ名と同じです。

user

データベースへ接続するPostgreSQLユーザ名を指定します。 デフォルトは、そのアプリケーションを実行しているユーザのオペレーティングシステム上の名前と同じです。

password

サーバがパスワードによる認証を必要とした場合に使用されるパスワードを指定します。

connect_timeout

接続用の最大待機時間を秒単位で指定します。 (10進数整数で表した文字列として記述してください。) ゼロもしくは未設定は、無限時間の待機を意味します。 2秒未満の待機時間を使用することは勧めません。

options

実行時にサーバに送信するコマンドラインオプションを追加します。 例えば、これを-c geqo=offに設定すると、-c geqo=offパラメータのセッション値はoffになります。有効なオプションに関する詳細は第18章を調べてください。

tty

無視されます。 (以前は、これはサーバデバッグ出力を送信する場所を指定するものでした。)

sslmode

このオプションは、どのSSL TCP/IP接続の優先度でサーバと調停するかを決定します。 6つのモードがあります。

表 30-1. sslmodeオプション

オプション説明
disableSSL接続のみ試行
allow最初に非SSL接続を試行。 失敗の場合SSL接続を試行
prefer(デフォルト)最初にSSL接続を試行。 失敗の場合、非SSL接続を試行
requireSSL接続のみ試行
verify-caSSL接続のみ試行し、サーバ証明書が信用されたCAから発行されたかを検証
verify-fullSSL接続のみ試行し、サーバ証明書が信用されたCAから発行されたか、およびそのサーバホスト名が証明書内のものと一致するかを検証

これらオプションがどのように動くのかの詳細は項30.17を参照してください。

sslmodeはUnixドメインソケット通信では無視されます。 SSLサポートなしでPostgreSQLがコンパイルされた場合に、requireを使用するとエラーになります。 一方、allowpreferは使用できますが、実際にlibpqSSL接続を受け付けません。

requiressl

このオプションはsslmode設定を支持する観点から廃止予定になっています。

1に設定することで、サーバへのSSL接続が必要になります。 (これはsslmoderequireと同じです。) サーバがSSL接続を受け付けない場合、Libpqは接続を拒絶します。 0(デフォルト)に設定することで、サーバと調停を行います。 (sslmodepreferと同じです。) SSLサポート付きでPostgreSQLをコンパイルした場合にのみ、このオプションが利用できます。

sslcert

このパラメータはクライアントSSL証明書のファイル名を指定します。

sslkey

このパラメータはクライアント証明書に対して使用される秘密鍵の場所を指定します。デフォルトの~/.postgresql/postgresql.keyの変わりに使用されるファイル名、または外部エンジン(エンジンはOpenSSLロード可能なもの)を指定することも可能です。外部エンジンの仕様書にはコロンで分割されたエンジン名とエンジン特有の鍵識別子を含んでいなければなりません。

sslrootcert

このパラメータはルートSSL証明書のファイル名を指定します。

sslcrl

このパラメータはSSL証明書失効リスト(CRL)のファイル名を指定します。

krbsrvname

Kerberos5またはGSSAPIの認証時に使われるKerberosサービス名です。 これはサーバのKerberos認証設定のサービス名と一致していなければなりません。 (項19.3.5および項19.3.3も参照してください。)

gsslib

GSSAPI認証で使用されるGSSライブラリです。 Windows上のみで使用されます。 libpqの認証がデフォルトのSSPIではなく、強制的にGSSAPIライブラリを使用するようにさせるにはgssapi を設定してください。

service

他のパラメータ用に使用されるサービス名です。 pg_service.conf内の追加的な接続パラメータを保持するサービス名を指定します。 これによりアプリケーションはサービス名だけを指定でき、接続パラメータを集中的に保守できるようになります。詳しくは 項30.15 を参照してください。

パラメータが指定されなかった場合には、対応する環境変数がチェックされます(項30.13を参照してください)。 環境変数も設定されていない場合は、指定された組み込みのデフォルト値が使用されます。

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プロシージャです。 設定できないパラメータが常に固定値になる点を除き、同一の機能を持ちます。 固定したパラメータに対してNULLもしくは空文字列とすると、それはデフォルトを使用することになります。

dbName内に=記号が含まれる場合、PQconnectdbに渡された場合とまったく同じ扱いでconninfo文字列として扱われます。 その後残りのパラメータが上のように適用されます。

PQsetdb

新たにデータベースサーバへの接続を作成します。

PGconn *PQsetdb(char *pghost,
                char *pgport,
                char *pgoptions,
                char *pgtty,
                char *dbName);

これは、loginpwdにNULLポインタを設定するPQsetdbLoginを呼び出すマクロです。 非常に古いプログラムへの後方互換性のために提供されています。

PQconnectStart
PQconnectPoll

ブロックしない方法で、データベースサーバへの接続を作成します。

        PGconn *PQconnectStart(const char *conninfo);
       

        PostgresPollingStatusType PQconnectPoll(PGconn *conn);
       

これら2つの関数を使用して、リモートI/Oの実行時にアプリケーションスレッドの実行がブロックされないように、データベースサーバへの接続を作成します。 このアプローチのポイントは、I/O の終了待ちがPQconnectdb内部ではなく、アプリケーションプログラムのメインループで出来ることにあります。 これによって、アプリケーションは他の処理と並行してこの処理を管理することができます。

PQconnectStartに渡されたconninfo文字列からパラメータを取得し、データベース接続が確立されます。 この文字列は、上述のPQconnectdbの場合と同じ形式で記述されています。

PQconnectStartPQconnectPollのどちらも以下の制限に適合する場合ブロックしません。

  • hostaddrhostパラメータは、ホスト名からのIPアドレス検索やホスト名の逆引きが起こらないように適切に使用されなければいけません。 これらのパラメータについての詳細は、前述のPQconnectdbの節を参照してください。

  • PQtraceを呼び出す場合は、トレースに使用するストリームオブジェクトがブロックされないことが保証されていなくてはなりません。

  • プログラマ自身が、後に示すように、PQconnectPollを呼び出す前にソケットが適切な状態にあることを保証しなくてはいけません。

非ブロック接続を始めるにはまず、conn=PQconnectStart("connection_info_string")を呼び出します。 connがNULLの場合、libpqが新たにPGconn構造体を割り当てられなかったことを表します。 そうでない場合は、適切なPGconnへのポインタが返されます (ただし、データベースに正しく接続されていることを表しているわけではありません)。 PQconnectStartから値が返ってきた段階で、status=PQstatus(conn)を呼び出します。 もし、statusCONNECTION_BADと等しい場合には、PQconnectStartが失敗しています。

PQconnectStartが成功したら、次は接続シーケンスを進めるために、libpqをポーリングします。 データベース接続の背後にあるソケットの記述子を取り出すには、PQsocket(conn)を使用します。 以下の繰り返しです。 直前のPQconnectPoll(conn)PGRES_POLLING_READINGの場合、ソケットの読み込み準備が整うまで待機します。 (select()poll()などのシステム関数で示されます。) そして、再度PQconnectPoll(conn)を呼び出します。 反対に直前のPQconnectPoll(conn)PGRES_POLLING_WRITINGの場合、ソケットの書き込み準備が整うまで待機し、その後、PQconnectPoll(conn)を再度呼び出します。 まだPQconnectPollを呼び出していない場合、つまり、PQconnectStartの呼び出し直後では、直前がPGRES_POLLING_WRITINGであった場合と同様の処理を行ないます。 この繰り返しをPQconnectPoll(conn)が、接続手続きの失敗を示すPGRES_POLLING_FAILED、もしくは、接続確立に成功したことを示すPGRES_POLLING_OKを返すまで継続します。

接続している間は、いつでもPQstatusを呼び出すことで、接続の状態をチェックすることができます。 この関数がCONNECTION_BADを返す場合、接続手続きは失敗しており、CONNECTION_OKを返す場合、接続が確立しています。 上述のように、このいずれの状態も、PQconnectPollの戻り値から同様に検出できます。 これ以外の状態は、非同期の接続手続きの間(のみに)現れることがあります。 これらは、接続プロシージャの現在の段階を示すものであり、例えばユーザへのフィードバックを提供することに使用できます。 以下の状態があります。

CONNECTION_STARTED

接続の確立待ち状態です。

CONNECTION_MADE

接続はOKです。 送信待ち状態です。

CONNECTION_AWAITING_RESPONSE

サーバからの応答待ち状態です。

CONNECTION_AUTH_OK

認証済みです。 バックエンドの起動待ち状態です。

CONNECTION_SSL_STARTUP

SSL暗号化の調停状態です。

CONNECTION_SETENV

環境が提供するパラメータ設定の調停状態です。

これらの定数は(互換性を保つため)なくなることはありませんが、アプリケーションは、これらが特定の順で出現したり、本書に書いてある値のどれかに必ずステータス値が該当するということを決して当てにしてはいけません。 アプリケーションは、以下に示すようにするべきです。

switch(PQstatus(conn))
{
    case CONNECTION_STARTED:
        feedback = "Connecting...";
        break;

    case CONNECTION_MADE:
        feedback = "Connected to server...";
        break;
.
.
.
    default:
        feedback = "Connecting...";
}

PQconnectPollを使用する場合、connect_timeout接続パラメータは無視されます。 経過時間が長過ぎるかどうかの判定はアプリケーションの責任で行ないます。 さもないと、PQconnectStartの後のPQconnectPollの繰り返しがPQconnectdbと同じになります。

PQconnectStartが非NULLポインタを返した場合、処理を終了する際には、構造体や関連するメモリブロックを始末するために、PQfinishを呼び出さなくてはいけません。 この処理は、接続試行が失敗した場合やその試行を中断する場合にも、必ず実行されなければいけません。

PQconndefaults

デフォルトの接続オプションを返します。

PQconninfoOption *PQconndefaults(void);

typedef struct
{
    char   *keyword;   /* このオプションのキーワード */
    char   *envvar;    /* 代替となる環境変数の名前 */
    char   *compiled;  /* 代替となるコンパイル時に組み込まれたデフォルト値 */
    char   *val;       /* オプションの現在値、もしくは、NULL */
    char   *label;     /* 接続ダイアログ内の当該フィールドのラベル */
    char   *dispchar;  /* 接続ダイアログ内の当該フィールドをどのように表示するかの指示
                          値:
                          ""        入力された値をそのまま表示
                          "*"       値を隠すパスワードフィールド用
                          "D"       デバッグオプション。デフォルトで何も表示しません */
    int     dispsize;  /* ダイアログ用のフィールドの大きさ(文字数単位) */
} PQconninfoOption;

接続オプションの配列を返します。 これは、使用可能なPQconnectdb用オプションの全てや、その時点でのデフォルト値を決定するために使用することができます。 戻り値は、PQconninfoOption構造体の配列へのポインタで、keywordポインタがNULLとなる項目が配列の末尾にきます。 メモリが確保出来なかった場合にはNULLポインタを返します。 現在のデフォルト値(val フィールド)は、環境変数や他のコンテキストに依存します。 呼び出し側では、接続オプションの情報は、読み込み専用として取り扱わなければいけません。

オプションの配列を処理した後は、PQconninfoFreeを使用して解放します。 この処理をしないと、PQconndefaultsが呼び出されるたびに少しずつメモリリークが発生します。

PQconninfoParse

提供された接続文字列から構文解析された接続オプションを返します。

PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);

接続文字列の構文解析を行い、配列として結果オプションを返すか、または接続文字列に問題があった場合にNULLを返します。これは提供された接続文字列の中のPQconnectdbオプションを決定するのに使用することができます。戻り値はPQconninfoOption構造の配列を指し示し、それはNULLkeywordポインタを所有している項目で終結します。

文字列内で明示的に指定されたオプションのみ結果配列の中で値集合を持ちます。いかなるデフォルトも挿入されません。

errmsgが非NULLであれば、成功した場合*errmsgはNULLに設定され、そうでなければ、問題を説明したエムロック(malloc)されたエラー文字列になります。(*errmsgがNULLが返されたときであってもNULLに設定されることも可能です。これはメモリー不足状態を意味します。)

オプションの配列処理の後、それをPQconninfoFreeに渡すことで開放します。これが行われない場合、PQconninfoParseへのそれぞれの呼び出しに対してメモリーリークが起こります。反対に、エラーが起こり、そしてerrmsgが非NULLであれば、PQfreememを使用してエラー文字列を必ず開放してください。

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つの関数が非ブロック方式で動作することです。 また、これらの関数はPQconnectStartPQconnectPollと同じ制限を受けます。

接続リセットを始めるには、PQresetStartを呼び出します。 この関数が0を返す場合、リセットに失敗しています。 戻り値が1ならば、PQconnectPollを使って接続を確立した時と同じように、PQresetPollを使用してリセットのポーリングを行います。