大多數主流的Linux發行版都會預設安裝gdbm,但在一些發行版中,你可能需要使用軟體包管理器來安裝相應的開發庫。例如,在
ubuntu中,你可能需要使用Synaptic軟體包管理器來安裝libgdbm-dev軟體包,因為它一般不會被預設安裝。
dbm的資料區塊datum是一個用typedef語句定義的類型。它至少包含下面兩個成員:
void *dptr;
size_t dsize;
dbm訪問函數包括下面四個:
#include<ndbm.h>DBM *dbm_open(const char *filename, int file_open_flags , mode_t mode);int dbm_store(DBM *database_descriptor , datum key, datum content, int store_mode);datum datum_fetch(DBM *database_descriptor , datum key);void dbm_close(DBM *database_descriptor);
1.dbm_open函數
這個函數用來開啟已有的資料庫,也可以用來建立新資料庫。filename參數是一個基本檔案名稱,它不包含.dir或.pag尾碼。
其餘的參數與open函數的第二個和第三個參數一樣。
dbm_open返回一個指向DBM類型的指標。它被用於所有後續對資料庫的訪問,如果失敗,它將返回(DBM *)0。
2.dbm_store函數
你用這個函數把資料存放區到資料庫中,如前所述,所有資料在儲存時都必須有一個唯一的索引。
為了定義你想要儲存的資料和用來應用他的索引,你必須設定兩個datum類型的參數:一個用於引用索引,一個用於實際
資料。最後一個參數store_mode用於控制當試圖以一個已有的關鍵字來儲存資料時發生的情況。如果它被設定為dbm_insert
,儲存操作將失敗並且dbm_store返回1.如果它被設定為dbm_replace,則新資料將覆蓋已有資料並且dbm_store返回0.當發生
其他錯誤時,dbm_store將返回一個負值。
3.dbm_fetch函數
dbm_fetch函數用於從資料庫中檢索資料,它使用一個先前dbm_open調用返回的指標和一個指向關鍵字datum類型結構作為參數。
它返回一個datum類型的結構。如果在資料庫中找到與這個與這個關鍵字關聯的資料,但會的datum結構的dptr和dsize成員的
值將被設為相應資料的值。如果沒有找到關鍵字,dptr將被設定為NULL;
4.dbm_close函數
這個函數用於關閉dbm_open函數開啟的資料庫。它的參數是先前dbm_open調用返回的dbm指標。
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <ndbm.h>/* On some systems you need to replace the above with#include <gdbm-ndbm.h>*/#include <string.h>#define TEST_DB_FILE "/tmp/dbm1_test"#define ITEMS_USED 3/* A struct to use to test dbm */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; DBM *dbm_ptr; dbm_ptr = dbm_open(TEST_DB_FILE, O_RDWR | O_CREAT, 0666); if (!dbm_ptr) { fprintf(stderr, "Failed to open database\n"); exit(EXIT_FAILURE); } /* put some data in the structures */ 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++) { /* build a key to use */ 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); /* build the key datum strcture */ 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 = dbm_store(dbm_ptr, key_datum, data_datum, DBM_REPLACE); if (result != 0) { fprintf(stderr, "dbm_store failed on key %s\n", key_to_use); exit(2); } } /* for */ /* now try and retrieve some data */ sprintf(key_to_use, "bu%d", 13); /* this is the key for the second item */ key_datum.dptr = key_to_use; /*提供測試*/ key_datum.dsize = strlen(key_to_use); data_datum = dbm_fetch(dbm_ptr, key_datum); if (data_datum.dptr) { printf("Data retrieved\n"); memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize); printf("Retrieved item - %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); } dbm_close(dbm_ptr); exit(EXIT_SUCCESS);}
其他dbm函數
int dbm_delete(DBM *database_descriptor , datum key);
這個函數用於從資料庫中刪除資料項目,與dbm_fetch一樣,它也使用一個指向關鍵字的datum類型結構作為其參數,但不同的是,它是用於
刪除資料而不是用於檢索資料。它在成功時返回0.
int dbm_error(DBM *database_descriptor );
函數用於測試資料庫中是否有錯誤發生,如果沒有就返回0.
int dbm_clearerr(DBM *database_descriptor);
函數用於清除資料庫中所有已被置位的錯誤條件標誌。
datum dbm_firstkey(DBM *database_descriptor);
datum dbm_nextkey(DBM *database_descriptor);
這個兩個函數一般成對來對資料庫中的所有關鍵字進行掃描。他們需要的迴圈結構如下所示:
DBM *db_ptr;
datum key;
for(key=dbm_firstkey(db_ptr); key.dptr ; key = dbm_nextkey(db_ptr));
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <ndbm.h>/* On some systems you need to replace the above with#include <gdbm-ndbm.h>*/#include <string.h>#define TEST_DB_FILE "/tmp/dbm2_test"#define ITEMS_USED 3/* A struct to use to test dbm */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; DBM *dbm_ptr; dbm_ptr = dbm_open(TEST_DB_FILE, O_RDWR | O_CREAT, 0666); if (!dbm_ptr) { fprintf(stderr, "Failed to open database\n"); exit(EXIT_FAILURE); } /* put some data in the structures */ 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++) { /* build a key to use */ 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); /* build the key datum strcture */ key_datum.dptr = 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 = dbm_store(dbm_ptr, key_datum, data_datum, DBM_REPLACE); if (result != 0) { fprintf(stderr, "dbm_store failed on key %s\n", key_to_use); exit(2); } } /* for */ /* now try and delete some data */ sprintf(key_to_use, "bu%d", 13); /* this is the key for the second item */ key_datum.dptr = key_to_use; key_datum.dsize = strlen(key_to_use); if (dbm_delete(dbm_ptr, key_datum) == 0) { printf("Data with key %s deleted\n", key_to_use); } else { printf("Nothing deleted for key %s\n", key_to_use); } for (key_datum = dbm_firstkey(dbm_ptr); key_datum.dptr; key_datum = dbm_nextkey(dbm_ptr)) { data_datum = dbm_fetch(dbm_ptr, key_datum); if (data_datum.dptr) { printf("Data retrieved\n"); memcpy(&item_retrieved, data_datum.dptr, data_datum.dsize); printf("Retrieved item - %s %d %s\n", item_retrieved.misc_chars, item_retrieved.any_integer, item_retrieved.more_chars); } else { printf("Woops - no data found for key %s\n", key_to_use); } } /* for each key */ dbm_close(dbm_ptr); exit(EXIT_SUCCESS);}