当前位置: 首页 > 工具软件 > dbm-orm > 使用案例 >

linux dbm数据库

严信瑞
2023-12-01

大多数主流的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);
}

 类似资料: