免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5348 | 回复: 3
打印 上一主题 下一主题

[C] 请教Berkeley DB的游标操作 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-29 21:34 |显示全部楼层 |倒序浏览
网上翻了下,没有找到完整的测试代码,即使有c的api相关介绍也是列了一下流程,贴了少许代码,测试下不行。郁闷啊,请大家帮我看看。

版本是libdb4.6-dev

测试代码如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <db.h>

  5. #define DBNAME "test.db"

  6. typedef struct emp {
  7.         int empid;
  8.         char lastname[50];
  9.         char firstname[50];
  10.         float salary;
  11. } emp_t;

  12. DB *openDB(const char *dbFile)
  13. {
  14.         DB *dbp = NULL;
  15.         int ret = 0;

  16.         ret = db_create(&dbp, NULL, 0);
  17.         if (ret != 0) {
  18.                 printf("ERROR: %s\n",db_strerror(ret));
  19.                 return NULL;
  20.         }
  21.         ret = dbp->open(dbp, NULL, dbFile, NULL, DB_BTREE, DB_CREATE, 0);
  22.         if (ret != 0) {
  23.                 printf("ERROR: %s\n",db_strerror(ret));
  24.                 return NULL;
  25.         }
  26.         return dbp;
  27. }

  28. int main(int argc, char* argv[])
  29. {
  30.         DB *dbp;
  31.         DBC *cursor;
  32.         int ret = 0;
  33.     DBT key, data;
  34.         emp_t emp;
  35.         if ((dbp = openDB(DBNAME)) == NULL) {
  36.                 printf("open failed\n");
  37.                 return 1;
  38.         }

  39.         /* insert */
  40.         while (1) {
  41.                 printf("Enter Employee ID: ");
  42.                 scanf("%d", &emp.empid);
  43.                 if (emp.empid == 0)
  44.                         break;
  45.                 printf("Enter Last name: ");
  46.                 scanf("%s", emp.lastname);
  47.                 printf("Enter first name: ");
  48.                 scanf("%s", emp.firstname);
  49.                 printf("Enter Salary: ");
  50.                 scanf("%f", &emp.salary);

  51.                 memset(&key, 0, sizeof(DBT));
  52.                 memset(&data, 0, sizeof(DBT));

  53.                 key.data = &(emp.empid);
  54.                 key.size = sizeof(emp.empid);
  55.                 data.data = &emp;
  56.                 data.size = sizeof(emp_t);

  57.                 ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
  58.                 if (ret != 0) {
  59.                         printf("Employee ID exists\n");
  60.                         continue;
  61.                 }
  62.         }

  63.         /* search */
  64.         while (1) {
  65.                 printf("Enter Employee ID you wana search: ");
  66.                 scanf("%d", &emp.empid);
  67.                 if (emp.empid == 0)
  68.                         break;
  69.                 memset(&key, 0, sizeof(DBT));
  70.                 memset(&data, 0, sizeof(DBT));

  71.                 key.data = &(emp.empid);
  72.                 key.size = sizeof(emp.empid);
  73.                 data.data = &emp;
  74.                 data.ulen = sizeof(emp_t);
  75.                 data.flags = DB_DBT_USERMEM;
  76.                 ret = dbp->get(dbp, NULL, &key, &data, 0);
  77.                 if (ret != 0) {
  78.                         printf("Employee ID doesn't exist\n");
  79.                 } else {
  80.                         printf("  Employee: %d - %s, %s\n  Salary: $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
  81.                 }
  82.         }

  83.         /* delete */
  84.         while (1) {
  85.                 printf("Enter Employee ID you wana delete: ");
  86.                 scanf("%d", &emp.empid);
  87.                 if (emp.empid == 0)
  88.                         break;
  89.                 memset(&key, 0, sizeof(DBT));
  90.                 memset(&data, 0, sizeof(DBT));

  91.                 key.data = &(emp.empid);
  92.                 key.size = sizeof(emp.empid);

  93.                 ret = dbp->del(dbp, NULL, &key, 0);
  94.                 if (ret != 0) {
  95.                         if (ret == DB_NOTFOUND)
  96.                                 printf("Employee ID doesn't exist\n");
  97.                 } else {
  98.                         printf("  Employee %d deleted.\n", emp.empid);
  99.                 }

  100.         }

  101.         /* cursor */
  102.         ret = dbp->cursor(dbp, NULL, &cursor, 0);
  103.         if (ret != 0) {
  104.                 printf("ERROR: %s\n",db_strerror(ret));
  105.                 return 1;
  106.         }
  107.         memset(&key, 0, sizeof(DBT));
  108.         memset(&data, 0, sizeof(DBT));
  109.         data.data = &emp;
  110.         data.size = sizeof(emp);
  111.         /* data.flags = DB_DBT_USERMEM; */

  112.         while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) {
  113.                 printf("ret = %d\n", ret);
  114.                 printf("%d - %s, %s    $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
  115.                 memset(&key, 0, sizeof(DBT));
  116.                 memset(&data, 0, sizeof(DBT));
  117.         }
  118.         if (ret < 0) {
  119.                 printf("ERROR: %s\n",db_strerror(ret));
  120.         }
  121.         cursor->close(cursor);

  122.         dbp->close(dbp, 0);

  123.         return 0;
  124. }
复制代码
gcc -Wall test.c -ldb即可
首先提示你输入一些数据,id, 用户名,薪水。然后是测试查找,删除,这些都是没有问题。输入0可以退出一个测试项目
关键是下面的游标,加上DB_DBT_USERMEM,还报“ERROR: DB_BUFFER_SMALL: User memory too small for return value”
游标还不能打出数据,请教到底何处写错了?

论坛徽章:
0
2 [报告]
发表于 2010-08-30 21:56 |显示全部楼层
已经从老外的dba网站上看到原因了,没有设置data的ulen成员大小,ulen我猜想是user memory的大小,具体可以参考手册,有空看看,
重新贴出coursor部分代码
/* cursor */
        ret = dbp->cursor(dbp, NULL, &cursor, 0);
        if (ret != 0) {
                printf("ERROR: %s\n",db_strerror(ret));
                return 1;
        }
        memset(&key, 0, sizeof(DBT));
        memset(&data, 0, sizeof(DBT));
        data.data = &emp;
        data.ulen = sizeof(emp);
        data.flags = DB_DBT_USERMEM;

        while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) {
                printf("%d - %-8s,%8s    $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
        }
        cursor->close(cursor);

论坛徽章:
0
3 [报告]
发表于 2010-08-30 21:58 |显示全部楼层
另外,我是参考<<  Professional Linux programming>>里的,那里的代码真不敢恭维,难道是翻译版给整错了?代码写出好多毛病啊,而且还不对。

论坛徽章:
0
4 [报告]
发表于 2010-08-30 22:01 |显示全部楼层
125行,没有对
key.data
key.size
进行赋值,设置吧
ddgfff 发表于 2010-08-30 19:26


cursor是遍历整个数据key/value对,应该不需要给定key的,只要给value存储空间就可以了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP