C言語でPostgreSQLを使う

#概要
PostgreSQLのCドライバを使って
PostgreSQLにアクセスするサンプルを作りましたので、そのソースと手順などを共有したいと思います。

#開発環境構築
CentOSを想定しています。

```bash
yum -y update
yum -y install gcc vim
yum -y install postgresql-server    # Posgreサーバインストール  
yum -y install postgresql-devel     # ヘッダファイル、ライブラリ  
/etc/rc.d/init.d/postgresql initdb  # データベースクラスタの新規作成
systemctl start postgresql.service  # 起動  
systemctl enable postgresql.service # 自動起動設定  
```

データベースクラスタの新規作成というのは/var/lib/pgsql/data/にデータベース格納領域を
確保する事で最初にやらないといけないらしいです。

##データベースの設定
テスト用のデータベースを作って内容を入れます。

```bash
# LinuxのアカウントとPostgreSQLのアカウントが一致しないとエラーになってしまう。
su - postgres    # ユーザ切り替え(postgresは自動で作成される)
createdb db_test # データベース作成
psql db_test     # データベース接続
create table tb_test(id int,name varchar(256)); # テーブル作成
# テストデータ投入
insert into tb_test(id,name) values(1,'aaa');
insert into tb_test(id,name) values(2,'bbb');
insert into tb_test(id,name) values(3,'ccc');
\q               # データベース切断
exit             # rootへ戻る
```

そのままだとプログラムからアクセスした時に拒否されてしまいました。
なので設定ファイルを編集して誰からアクセスされても通すようにしました。

```diff
vim /var/lib/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
- local   all         all                               ident
+ local   all         all                               trust
# IPv4 local connections:
- host    all         all         127.0.0.1/32          ident
+ host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
- host    all         all         ::1/128               ident
+ host    all         all         ::1/128               trust
```

```bash
systemctl restart postgresql.service  # 設定を反映を忘れずに
```

#PostgreSQLにアクセス
おさわり程度のソースです。。NULLの箇所を埋めると色々細かな設定ができて便利です。
因みにこのソースを大量データの入ったDBで使用すると
PQntuples()の所で処理が止まる可能性があります。

```c:postgres.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <postgres.h>
#include <libpq-fe.h>

#define DPGS_GETRESLT_TEXT   0
#define DPGS_GETRESLT_BINARY 1

int main(void){
  PGconn   *conn      = NULL;
  PGresult *resp      = NULL;
  char      sql_str[255];
  char     *sql_serv  = "localhost";
  char     *user      = "postgres";
  char     *passwd    = "";
  char     *db_name   = "db_test";
  int      resp_cnt   = 0;
  int      loop       = 0;
  memset( &sql_str[0] , 0x00 , sizeof(sql_str) );

  /* DB接続 */
  conn = PQsetdbLogin(
           sql_serv , // 接続先
           NULL ,     // ポート番号
           NULL ,     // デバッグオプション
           NULL ,     //デバッグ出力のためのファイル,またはtty名
           db_name ,  // DB名
           user    ,  // ユーザ名
           passwd     // パスワード
         );
  // エラーチェック
  if( PQstatus( conn ) == CONNECTION_BAD ){
    // error 内容はPQerrorMessage(con)で取得
    printf( "%s" ,PQerrorMessage(conn));
    exit(-1);
  }
  // select文の発行
  snprintf( &sql_str[0] , sizeof(sql_str)-1 , "select * from tb_test" );
  resp = PQexecParams(
           conn                 , // 接続オブジェクト
           &sql_str[0]          , // 発行SQL文
           0                    , // パラメータ数
           NULL                 , // パラメータのデータ型
           NULL                 , // パラメータ値
           NULL                 , // パラメータのデータ長
           NULL                 , // パラメータのフォーマット形式
           DPGS_GETRESLT_BINARY   // 結果をバイナリで取得
         );
  resp = PQexec( conn , &sql_str[0] );
  // エラーチェック
  if( PQresultStatus( resp ) != PGRES_TUPLES_OK ) {
    // error
    printf("error_2");
    exit(-1);
  }

  // レスポンス
  resp_cnt = PQntuples( resp );
  for(loop=0; loop < resp_cnt ;loop++) {
    printf( "%d : %s\n" ,
            atoi( PQgetvalue( resp , loop , 0 ) ) ,
            PQgetvalue( resp , loop , 1 )
          );
  }
  
  // 後片づけ
  PQclear( resp );
  return 0;
}
```

### コンパイル、実行
「usr/lib64」の部分はfind /-name "libpq.so"等で
ライブラリの配置場所を指定します。

```bash
gcc -o postgres postgres.c -Wall -I/usr/include/pgsql/server -L/usr/lib64 -lpq
./posgre
1 : aaa
2 : bbb
3 : ccc
```