Edited at

C言語でPostgreSQLを使う

More than 1 year has passed since last update.


概要

PostgreSQLのCドライバを使って

PostgreSQLにアクセスするサンプルを作りましたので、そのソースと手順などを共有したいと思います。


開発環境構築

CentOSを想定しています。

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/にデータベース格納領域を

確保する事で最初にやらないといけないらしいです。


データベースの設定

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

# 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へ戻る

そのままだとプログラムからアクセスした時に拒否されてしまいました。

なので設定ファイルを編集して誰からアクセスされても通すようにしました。

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

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


PostgreSQLにアクセス

おさわり程度のソースです。。NULLの箇所を埋めると色々細かな設定ができて便利です。

因みにこのソースを大量データの入ったDBで使用すると

PQntuples()の所で処理が止まる可能性があります。


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"等で

ライブラリの配置場所を指定します。

gcc -o postgres postgres.c -Wall -I/usr/include/pgsql/server -L/usr/lib64 -lpq

./posgre
1 : aaa
2 : bbb
3 : ccc