GDBMを使ってみる2
GDBMを使ってみる1 - 日進月歩の続き.
今回はgdbmのデータベースに対してデータの挿入と読み込みについて考えていく.
まずデータベースとのやり取りにはdatum構造体を用いる.
定義は以下.
typedef struct {keyとvalue共にこの構造体を用いてやりとりが行われる.
char *dptr;
int dsize;
} datum;
- データの挿入
次にデータの挿入を考えていく.
データの挿入は以下の関数を通して行う.
int gdbm_store (引数dbfデータを挿入するデータベースを指定.
GDBM FILE dbf,
datum key,
datum content,
int flag )
key, contentは挿入データのkeyとkeyに結びつけるvalueの値をdatum構造体を用いてそれぞれ指定する.
flagの値にはGDBM_REPLACEまたはGDBM_INSERTを指定する.
既にKey値が重複するデータがあった場合の動作が異なり,
GDBM_REPLACEを指定したときは上書きを行い,一方GDBM_INSERTを指定した場合には上書きは行わずエラーを返す.
また関数の戻り値は正常時には'0',GDBM_INSERTによるエラーの場合は'1',それ以外は'-1'を返す.
- データの検索
次に,データベースから特定のkeyを元にデータを読み出すことを行う.
これは以下の関数で可能
datum gdbm_fetch (GDBM FILE dbf , datum key )引数のdbfは検索対象のオープン済みのデータベースを指定.
keyには検索を行うキーの値を格納する.
検索を行い一致するデータご見つかった場合にはキーに対応するデータを戻り値として返す.
一方,データが存在しない場合には戻り値のdatum構造体のメンバーdptrにNULLがセットされる.
- データの確認
指定したキーがデータベース内に存在するかの確認が以下の関数で行える.
int gdbm_exists (GDBM FILE dbf , datum key )引数の対応はgdbm_fetch関数と同じ.
キーに対応するデータが存在する場合は'1'を,存在しないは'0'を,それぞれ戻り値として返す.
- データの削除
データベースに格納されているデータの削除は以下の関数で行う.
int gdbm_delete (GDBM FILE dbf , datum key )こちらも引数の対応はgdbm_fetch関数と同じである.
キーに一致するデータがある場合には削除し,'0'を戻り値として返す.
また一致するデータが存在しない場合や,その他のエラーは戻り値として'-1'を返す.
今回も最後にサンプルコードを記載.
![Linuxプログラミング―例題で学ぶUNIXプログラミング環境のすべて Linuxプログラミング―例題で学ぶUNIXプログラミング環境のすべて](https://images-fe.ssl-images-amazon.com/images/I/51JR8N9XWQL._SL160_.jpg)
Linuxプログラミング―例題で学ぶUNIXプログラミング環境のすべて
- 作者: ニールマシュー,リチャードストーンズ,Neil Matthew,Richard Stones,葛西重夫
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 1999/03
- メディア: 単行本
- 購入: 1人 クリック: 9回
- この商品を含むブログ (4件) を見る
#include
#include
#include
#include
#include
#include#define TEST_DB_FILE "dbm1_test"
#define ITEMS_USED 3
#define BLOCK_SIZE (4096)struct test_data{
char misc_chars[15];
int any_integer;
char more_chars[21];
};int main(){
struct test_data items_to_store[ITEMS_USED];
struct test_data item_retrieved;
char key_to_use[20];
int i, result;
datum key_datum;
datum data_datum;
GDBM_FILE dbm_ptr;
dbm_ptr = gdbm_open(TEST_DB_FILE, BLOCK_SIZE, GDBM_WRCREAT, 0666, NULL);
if(!dbm_ptr){
fprintf(stderr, "Failed to open database\n");
exit(EXIT_FAILURE);
}
memset(items_to_store, '\0', sizeof(items_to_store));
strcpy(items_to_store[0].misc_chars, "First!");
items_to_store[0].any_integer = 47;
strcpy(items_to_store[0].more_chars, "foo");
strcpy(items_to_store[1].misc_chars, "bar");
items_to_store[1].any_integer = 13;
strcpy(items_to_store[1].more_chars, "unlucky?");
strcpy(items_to_store[2].misc_chars, "Third");
items_to_store[2].any_integer = 3;
strcpy(items_to_store[2].more_chars, "baz");
for(i = 0; i < ITEMS_USED; i++){
sprintf(key_to_use, "%c%c%d",
items_to_store[i].misc_chars[0],
items_to_store[i].more_chars[0],
items_to_store[i].any_integer);
key_datum.dptr = (void *)key_to_use;
key_datum.dsize = strlen(key_to_use);
data_datum.dptr = (void *)&items_to_store[i];
data_datum.dsize = sizeof(struct test_data);
result = gdbm_store(dbm_ptr, key_datum, data_datum, GDBM_REPLACE);
if(result != 0){
fprintf(stderr, "gdbm_store failed on key %s", key_to_use);
exit(2);
}
}
sprintf(key_to_use, "bu%d", 13);
key_datum.dptr = key_to_use;
key_datum.dsize = strlen(key_to_use);
data_datum = gdbm_fetch(dbm_ptr, key_datum);
if(data_datum.dptr){
printf("Data retrieved\n");
memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize);
printf("Retrieved tem - %s %d %s\n",
item_retrieved.misc_chars,
item_retrieved.any_integer,
item_retrieved.more_chars);
}
else{
printf("No data found for key %s\n", key_to_use);
}
gdbm_close(dbm_ptr);
exit(EXIT_SUCCESS);
}