曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6109|回复: 1
打印 上一主题 下一主题

[数据库] dbm 数据库相关函数

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-4-25 21:28:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
四个基本函数原型
DBM *dbm_open(const char *filename, int file_open_flags, mode_t file_mode);
int dbm_store(DBM *database_descriptor, datum_key, datum content, int store_mode);
datum dbm_fetch(DBM *database_descriptor, datum key);
void dbm_close(DBM *database_descriptor);
分述
dbm_open()
此函数用来打开一个已经存在的数据库,也可以用来创建一个新的数据库。其中参数 filename 基于文件名,并没有 .dir 或者 .pag 扩展名。
file_open_flagsfile_mode 两个参数和 open 函数里后两个参数定义一样。
该函数返回一个 DBM 类型指针。此指针在后续的需要访问数据库操作中要用到( 和文件流 FILE 指针类似);若函数执行失败,就返回 (DBM *)0

dbm_store()
通过此函数把要存储的数据存储到数据库中。存储的时候,所有的数据都必须带有一个唯一的索引!为了存储数据和索引,必须设置两个 datum 类型的结构:一个执行索引,另外一个指向数据。
store_mode 参数控制存储时所采取的模式:
设为 DBM_INSERT 时,如果当时所用索引值已经存在,那么存储失败,函数返回 1;
设为 DBM_REPLACE 时,新数据会覆盖掉已经存在的数据,函数返回 0。

当 dbm_store() 遇到非“无法存储失败”时,返回负数。

dbm_fetch()
此函数用来从数据库中取回数据,共需要两个参数:
一个是从 dbm_open 所返回的 DBM 指针;一个是必须为 datum 类型的数据,也就是依此寻找数据的索引。
函数的返回值是一个 datum 类型数据。如果数据库中要寻找的数据正好和给出的索引相关联,那么所返回的 datum 结构里的 dptr 和 dsize 将指向所返回的数据。如果无法找到索引值,那么 dptr 将被设为 null。

注意: dbm_fetch 返回的仅仅是一个包含着指向所要寻找数据指针的 datum 类型结构。实际的数据仍然还是存储在 dbm 库中,在调用 dbm 相关函数之前必须将这些数据拷贝出来到相关的变量中。

dbm_close()
此函数将 dbm_open 打开的数据库关闭,这里必须给它传递一个从 dbm_open() 返回的 DBM 指针作为参数。

测试代码
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#include <ndbm.h>

#include <string.h>
#define TEST_DB_FILE "/tmp/dbm1_test"
#define ITEMS_USED 3

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);
    }
    /* 数据存储区初始化 */
    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 = 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);
            }
    }
    /* 尝试用 bu13 作为索引进行查找 */
      sprintf(key_to_use, "bu%d", 13);
      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);
}

运行与输出
beyes@linux-beyes:~/C/dbm> ./dbm1.exe
Data retrieved
Retrieved item - bar 13 unlucky?

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-4-26 22:00:33 | 只看该作者

其它相关函数

int dbm_delete(DBM *database_descriptor, datum key);
int dbm_error(DBM *database_descriptor);
int dbm_clearerr(DBM *database_descriptor);
datum dbm_firstkey(DBM *database_descriptor);
datum dbm_nextkey(DBM *database_descriptor);

dbm_delete()
此函数用来删除数据库中的条目,成功时返回 0

dbm_error()
简单的测试数据库中是否有错误发生,如果没有就返回 0

dbm_clearerr()
清除数据库中任何一个可能被置位的错误条件标志

dbm_firstkey() 和 dbm_next_key()
此函数对一般用来扫描数据库中所有条目的所有索引,需要来一个循环操作:

DBM *db_ptr;
datum key;
for (key = dbm_firstkey(db_ptr); key.dptr; key = dbm_nextkey(db_ptr));
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 16:35 , Processed in 0.066110 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表