/* g++ -c ca-pgsql.cpp */ /* [前処理] データベースの作成 C:\Users\yrl-user>psql -h localhost -U postgres ← ログイン postgres=# \l postgres=# create database ca_db; 以下をコピペする create table person_od ( counter int primary key, generation_t1 real, delete_t1 real, generation_t2 real, delete_t2 real, generation_t3 real, delete_t3 real, orig_x real, orig_y real, dest_x real, dest_y real, orig_station int, dest_station int ); ca_db=# \dt リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+-----------+----------+---------- public | person_od | テーブル | postgres (1 行) ca_db=# \d person_od テーブル "public.person_od" 列 | 型 | 修飾語 ---------------+---------+---------- counter | integer | not null generation_t1 | real | delete_t1 | real | generation_t2 | real | delete_t2 | real | generation_t3 | real | delete_t3 | real | orig_x | real | orig_y | real | dest_x | real | dest_y | real | orig_station | integer | dest_station | integer | インデックス: "person_od_pkey" PRIMARY KEY, btree (counter) */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <sys/types.h> #include "libpq-fe.h" typedef enum step{ STEP1 = 1, STEP2 = 2, STEP3 = 3 }STEP; // 駅の情報を格納する構造体 typedef struct station{ int serial_number; }STATION; typedef struct person_od{ int counter; double generation_t1; // 発生時刻(STEP1) double delete_t1; // 消滅時刻(STEP1) double generation_t2; // 発生時刻(STEP2) double delete_t2; // 消滅時刻(STEP2) double generation_t3; // 発生時刻(STEP3) double delete_t3; // 消滅時刻(STEP3) double orig_x; // 出発x座標 double orig_y; // 出発y座標 double dest_x; // 到着x座標 double dest_y; // 到着y座標 STATION orig_station; // 出発駅 STATION dest_station; // 到着駅 } PERSON_OD; const char *conninfo = "host=localhost user=postgres password=c-anemone dbname=ca_db"; PGconn *conn; int ca_pgsql_init() { // データベースとの接続を確立する conn = PQconnectdb(conninfo); /* バックエンドとの接続確立に成功したかを確認する */ if (PQstatus(conn) != CONNECTION_OK){ fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); } } int ca_pgsql_add_person(PERSON_OD *p_person_od) { char stringSQL[500] = {0}; sprintf(stringSQL, "INSERT INTO person_od(counter, generation_t1, orig_x, orig_y, dest_x, dest_y, orig_station, dest_station) VALUES(%d, %f, %f, %f, %f, %f, %d, %d);", p_person_od->counter, p_person_od->generation_t1, p_person_od->orig_x, p_person_od->orig_y, p_person_od->dest_x, p_person_od->dest_y, p_person_od->orig_station.serial_number, p_person_od->dest_station.serial_number); PGresult *res = PQexec(conn, stringSQL); // INSERT等値を返さないコマンドの場合戻り値は PGRES_COMMAND_OK if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK) { // SQLコマンドが失敗した場合 fprintf(stderr, "INSERT COMMAND IS FAILED.", PQerrorMessage(conn)); } // 値セットが無い場合でも必ず結果をクリアする PQclear(res); } int ca_pgsql_write(STEP step, PERSON_OD *p_person_od) { char stringSQL2[500] = {0}; if (step == STEP1){ sprintf(stringSQL2, "UPDATE person_od SET generation_t1 = %f, delete_t1 = %f WHERE counter = %d;", p_person_od->generation_t1, p_person_od->delete_t1, p_person_od->counter); } else if (step == STEP2){ sprintf(stringSQL2, "UPDATE person_od SET generation_t2 = %f, delete_t2 = %f WHERE counter = %d;", p_person_od->generation_t2, p_person_od->delete_t2, p_person_od->counter); } else if (step == STEP3){ sprintf(stringSQL2, "UPDATE person_od SET generation_t3 = %f, delete_t3 = %f WHERE counter = %d;", p_person_od->generation_t3, p_person_od->delete_t3, p_person_od->counter); } else { printf("error in ca_pgsql_write() in ca-pgsql.cpp\n"); } PGresult *res = PQexec(conn, stringSQL2); // INSERT等値を返さないコマンドの場合戻り値は PGRES_COMMAND_OK if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK) { // SQLコマンドが失敗した場合 fprintf(stderr, "INSERT COMMAND IS FAILED.", PQerrorMessage(conn)); } // 値セットが無い場合でも必ず結果をクリアする PQclear(res); } int ca_pgsql_close() { // 最後必ずデータベースとの接続を閉じる PQfinish(conn); } ======================================= /* ca-pgsql.cpp用のテストプログラム */ /* g++ -g ca-pgsql-test.cpp ca-pgsql.cpp -o ca-pgsql-test.exe -I"D:\PostgreSQL\pg96\include" -L"D:\PostgreSQL\pg96\lib" -llibpq */ #include <stdlib.h> #include <stdint.h> #include <string.h> #include <sys/types.h> #include "libpq-fe.h" typedef enum step{ STEP1 = 1, STEP2 = 2, STEP3 = 3 }STEP; // 駅の情報を格納する構造体 typedef struct station{ int serial_number; }STATION; typedef struct person_od{ int counter; double generation_t1; // 発生時刻(STEP1) double delete_t1; // 消滅時刻(STEP1) double generation_t2; // 発生時刻(STEP2) double delete_t2; // 消滅時刻(STEP2) double generation_t3; // 発生時刻(STEP3) double delete_t3; // 消滅時刻(STEP3) double orig_x; // 出発x座標 double orig_y; // 出発y座標 double dest_x; // 到着x座標 double dest_y; // 到着y座標 STATION orig_station; // 出発駅 STATION dest_station; // 到着駅 } PERSON_OD; extern int ca_pgsql_init(); extern int ca_pgsql_add_person(PERSON_OD *p_person_od); extern int ca_pgsql_write(STEP step, PERSON_OD *p_person_od); extern int ca_pgsql_close(); int main() { ca_pgsql_init(); PERSON_OD person_od[10]; for (int i = 0; i < 10; i++){ person_od[i].counter = i; person_od[i].generation_t1 = 8.5; // 発生時刻(STEP1) person_od[i].delete_t1 = 9.5; // 消滅時刻(STEP1) person_od[i].generation_t2 = 8.5; // 発生時刻(STEP2) person_od[i].delete_t2 =10.2; // 消滅時刻(STEP2) person_od[i].generation_t3 = 8.5; // 発生時刻(STEP3) person_od[i].delete_t3 = 9.9; // 消滅時刻(STEP3) person_od[i].orig_x = 139.480841; // 出発x座標 person_od[i].orig_y = 35.700123; // 出発y座標 person_od[i].dest_x = 139.766103; // 到着x座標 person_od[i].dest_y = 35.681391; // 到着y座標 person_od[i].orig_station.serial_number = 0; // 出発駅 person_od[i].dest_station.serial_number = 10; // 到着駅 ca_pgsql_add_person(&(person_od[i])); } ca_pgsql_write(STEP3, &(person_od[4])); ca_pgsql_close(); return 0; }