适应不同版本的bdb的代码

使用BDB

 

前段时间准备将以前程序里的gdbm替换成bdb,所以写了一些代码,如何使用bdb,现在将代码贴出来:

#ifndef EYOU_DBT_H

#define EYOU_DBT_H

 

#include <db.h>

 

/* Set all fields of DBT to zero.  Return DBT.  */

DBT *affirm_clear_dbt (DBT *dbt);

 

 

/* Set DBT to retrieve no data.  This is useful when you're just

   probing the table to see if an entry exists, or to find a key, but

   don't care what the value is.  Return DBT.  */

DBT *affirm_nodata_dbt (DBT *dbt);

 

 

/* Set DBT to refer to the SIZE bytes at DATA.  Return DBT.  */

DBT *affirm_set_dbt (DBT *dbt, const void *data, u_int32_t size);

 

void init_DBT(DBT *key, DBT *data);

 

#endif /* EYOU_DBT_H */

dbt.h

 

 

/*

 * bdb_error.h : interface to routines for returning Berkeley DB errors

 */

 

#ifndef EYOU_BDB_ERR_H

#define EYOU_BDB_ERR_H

 

#include <db.h>

 

#ifdef __cplusplus

extern "C" {

#endif /* __cplusplus */

 

 

#define BDB_ERR(expr)                           /

  do {                                          /

    int db_err__temp = (expr);                      /

    if (db_err__temp)                             /

      return db_err__temp;                        /

  } while (0)

 

 

#ifdef __cplusplus

}

#endif /* __cplusplus */

 

#endif /* EYOU_BDB_ERR_H */

bdb_error.h

 

 

 

 

 

Bdb_compat.h 主要是同时可以在不同版本的bdb中使用,因为open函数参数一样

#ifndef EYOU_BDB_COMPAT_H

#define EYOU_BDB_COMPAT_H

 

#include <db.h>

 

 

/* BDB 4.1 introduced the DB_AUTO_COMMIT flag. Older versions can just

   use 0 instead. */

#ifdef DB_AUTO_COMMIT

#define AFFIRM_BDB_AUTO_COMMIT (DB_AUTO_COMMIT)

#else

#define AFFIRM_BDB_AUTO_COMMIT (0)

#endif

 

/* DB_INCOMPLETE is obsolete in BDB 4.1. */

#ifdef DB_INCOMPLETE

#define AFFIRM_BDB_HAS_DB_INCOMPLETE 1

#else

#define AFFIRM_BDB_HAS_DB_INCOMPLETE 0

#endif

 

/* In BDB 4.3, "buffer too small" errors come back with

   DB_BUFFER_SMALL (instead of ENOMEM, which is now fatal). */

#ifdef DB_BUFFER_SMALL

#define AFFIRM_BDB_DB_BUFFER_SMALL DB_BUFFER_SMALL

#else

#define AFFIRM_BDB_DB_BUFFER_SMALL ENOMEM

#endif

 

/* BDB 4.4 introdiced the DB_REGISTER flag for DBEnv::open that allows

   for automatic recovery of the databases after a program crash. */

#ifdef DB_REGISTER

#define AFFIRM_BDB_AUTO_RECOVER (DB_REGISTER | DB_RECOVER)

#else

#define AFFIRM_BDB_AUTO_RECOVER (0)

#endif

 

/* Parameter lists */

 

/* In BDB 4.1, DB->open takes a transaction parameter. We'll ignore it

   when building with 4.0. */

#if (DB_VERSION_MAJOR > 4) /

    || (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 1)

#define AFFIRM_BDB_OPEN_PARAMS(env,txn) (env), (txn)

#else

#define AFFIRM_BDB_OPEN_PARAMS(env,txn) (env)

#endif

 

/* In BDB 4.3, the error gatherer function grew a new DBENV parameter,

   and the MSG parameter's type changed. */

#if (DB_VERSION_MAJOR > 4) /

    || (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 3)

/* Prevents most compilers from whining about unused parameters. */

#define AFFIRM_BDB_ERROR_GATHERER_IGNORE(varname) ((void)(varname))

#else

#define bdb_error_gatherer(param1, param2, param3) /

  bdb_error_gatherer (param2, char *msg)

#define AFFIRM_BDB_ERROR_GATHERER_IGNORE(varname) ((void)0)

#endif

 

 

/* Before calling db_create, we must check that the version of the BDB

   libraries we're linking with is the same as the one we compiled

   against, because the DB->open call is not binary compatible between

   BDB 4.0 and 4.1. This function returns DB_OLD_VERSION if the

   compile-time and run-time versions of BDB don't match. */

int affirm_bdb_check_version (void);

 

 

#endif /* EYOU_BDB_COMPAT_H */

bdb_compat.h

 

 

 

 

 

#ifndef EYOU_AFFIRM_TABLE_H

#define EYOU_AFFIRM_TABLE_H

 

#include <db.h>

 

int bdb_open(DB** dbp, char *db_name);

int bdb_get(DB* dbp, DBT* key, DBT* data, char* db_name);

int bdb_put(DB* dbp, DBT* key, DBT* data, char* db_name);

int bdb_del(DB* dbp, DBT* key, char* db_name);

 

 

#endif /* EYOU_AFFIRM_TABLE_H */

affirm_table.h

 

 

 

 

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

 

#include "dbt.h"

 

void init_DBT(DBT *key, DBT *data)

{

    if (key != NULL)

        memset (key, 0, sizeof(DBT));

 

    if (data != NULL)

        memset (data, 0, sizeof(DBT));

}

 

DBT *

affirm_clear_dbt (DBT *dbt)

{

  memset (dbt, 0, sizeof (*dbt));

 

  return dbt;

}

 

 

DBT *affirm_nodata_dbt (DBT *dbt)

{

  affirm_clear_dbt (dbt);

 

  /* A `nodata' dbt is one which retrieves zero bytes from offset zero,

     and stores them in a zero-byte buffer in user-allocated memory.  */

  dbt->flags |= (DB_DBT_USERMEM | DB_DBT_PARTIAL);

  dbt->doff = dbt->dlen = 0;

 

  return dbt;

}

 

 

DBT *

affirm_set_dbt (DBT *dbt, const void *data, unsigned int size)

{

  affirm_clear_dbt (dbt);

 

  dbt->data = (void *) data;

  dbt->size = size;

 

  return dbt;

}

 

dbt.c

 

 

 

 

 

 

/* bdb_compat.c --- Compatibility wrapper for different BDB versions.

 *

 */

#include <db.h>

 

#include "bdb_compat.h"

 

int

affirm_bdb_check_version (void)

{

  int major, minor;

 

  db_version(&major, &minor, NULL);

  if (major != DB_VERSION_MAJOR || minor != DB_VERSION_MINOR)

    return DB_OLD_VERSION;

  return 0;

}

bdb_compat.c

 

 

 

 

 

#include <string.h>

#include <unistd.h>

 

#include "affirm_table.h"

#include "bdb_compat.h"

#include "dbt.h"

#include "bdb_error.h"

 

int bdb_open(DB** dbp, char *db_name)

{

    DB *dbtmp;

 

    if (db_name == NULL)

    {

        return -1;

    }

 

    BDB_ERR(affirm_bdb_check_version());

    BDB_ERR(db_create(&dbtmp, NULL, 0));

    BDB_ERR(dbtmp->open(AFFIRM_BDB_OPEN_PARAMS(dbtmp, NULL),

                db_name, NULL, DB_BTREE,

                DB_CREATE /*| AFFIRM_BDB_AUTO_COMMIT*/,

                0666));

 

    *dbp = dbtmp;

    return 0;

}

 

int bdb_get(DB* dbp, DBT* key, DBT* data, char* db_name)

{

   int db_flag = 0;

   DB* dbtmp = NULL;

 

   if (key == NULL)

   {

       return -1;

   }

 

   if (dbp == NULL)

   {

       int ret;

       if (db_name == NULL)

       {

           return -1;

       }

 

       if ((ret = bdb_open(&dbtmp, db_name)) != 0)

           return ret;

   }

   else

   {

       dbtmp = dbp;

       db_flag = 1;

   }

 

   BDB_ERR(dbtmp->get(dbtmp, NULL, key, data, 0));

 

   if (0 == db_flag)

   {

       BDB_ERR(dbtmp->close(dbtmp, 0));

   }

 

   return 0;

}

 

int bdb_put(DB* dbp, DBT* key, DBT* data, char *db_name)

{

   int db_flag = 0;

   DB* dbtmp = NULL;

 

   if (key == NULL || data == NULL)

   {

       return -1;

   }

 

   if (dbp == NULL)

   {

       int ret;

 

       if (db_name == NULL)

       {

           return -1;

       }

 

       if ((ret = bdb_open(&dbtmp, db_name)) != 0)

           return ret;

   }

   else

   {

       dbtmp = dbp;

       db_flag = 1;

   }

 

   BDB_ERR(dbtmp->put(dbtmp, NULL, key, data, 0));

   BDB_ERR(dbtmp->sync(dbtmp, 0));

 

   if (0 == db_flag)

   {

       BDB_ERR(dbtmp->close(dbtmp, 0));

   }

 

   return 0;

}

 

int bdb_del(DB* dbp, DBT* key, char* db_name)

{

   int db_flag = 0;

   DB* dbtmp = NULL;

 

   if (key == NULL)

   {

       return -1;

   }

 

   if (dbp == NULL)

   {

       int ret;

 

       if (db_name == NULL)

       {

           return -1;

       }

 

       if ((ret = bdb_open(&dbtmp, db_name)) != 0)

           return ret;

   }

   else

   {

       dbtmp = dbp;

       db_flag = 1;

   }

 

   BDB_ERR(dbtmp-> del (dbtmp, NULL, key, 0));

 

   if (0 == db_flag)

   {

       BDB_ERR(dbtmp->close(dbtmp, 0));

   }

 

   return 0;

}

affirm_table.c

 

 

 

 

 

 

#include <stdio.h>

#include <string.h>

#include <db.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

 

#include "affirm_table.h"

#include "bdb_compat.h"

#include "dbt.h"

#include "bdb_error.h"

 

#define AFFIRM_BDB_FILE         "/tmp/aftest.db"

 

void get_func(int i)

{

    int ret;

    DBT key, data;

    memset (&data, 0, sizeof(DBT));

    ret = bdb_get(NULL, affirm_set_dbt(&key, (void*)&i, sizeof(int)), &data, AFFIRM_BDB_FILE);

 

    if (ret ==0 )

        printf("get :key = %d, data = %d/n", i, *(int*)data.data);

}

 

void put_func()

{

    int i,r;

    DBT key, data;

    i = 4;

    r = bdb_put(NULL, affirm_set_dbt(&key, &i, sizeof(int)),

                  affirm_set_dbt(&data, &i, sizeof(int)), AFFIRM_BDB_FILE);

    printf("put: key=%d, data=%d, ret=%d/n", *(int*)key.data, *(int*)data.data, r);

}

 

int main()

{

    DB *dbp;

    DBT key, data;

    int i = 0;

    int ret;

    pid_t pid;

 

 

#if 0

    i++;

    memset(&key, 0, sizeof(DBT));

    memset(&data, 0, sizeof(DBT));

    key.data = &i;

    key.size = sizeof(int);

    data.data = &i;

    data.size = sizeof(int);

#endif

 

    unlink(AFFIRM_BDB_FILE);

#if 0

    ret = bdb_open(&dbp, AFFIRM_BDB_FILE);

    if (ret != 0)

    {

        printf("open error! ret = %d/n", ret);

        return -1;

    }

#endif

 

    pid = fork();

 

    if (pid == 0)

    {

        int r;

        i = 0;

 

        i++;

        r = bdb_put(NULL, affirm_set_dbt(&key, &i, sizeof(int)),

                      affirm_set_dbt(&data, &i, sizeof(int)), AFFIRM_BDB_FILE);

        printf("key=%d, data=%d, ret=%d/n", *(int*)key.data, *(int*)data.data, r);

 

        i++;

        r = bdb_put(NULL, affirm_set_dbt(&key, &i, sizeof(int)),

                      affirm_set_dbt(&data, &i, sizeof(int)), AFFIRM_BDB_FILE);

        printf("key=%d, data=%d, ret=%d/n", *(int*)key.data, *(int*)data.data, r);

 

        i++;

        r = bdb_put(NULL, affirm_set_dbt(&key, &i, sizeof(int)),

                      affirm_set_dbt(&data, &i, sizeof(int)), AFFIRM_BDB_FILE);

        printf("key=%d, data=%d, ret=%d/n", *(int*)key.data, *(int*)data.data, r);

 

#if 0

        ret = bdb_get(NULL, affirm_set_dbt(&key, (void*)&i, sizeof(int)), &data, AFFIRM_BDB_FILE);

        printf("ret = %d/n", ret);

 

        if (ret ==0 )

            printf("key = 3, data = %d/n", *(int*)data.data);

#endif

        exit (0);

    }

 

    printf("wait .../n");

    waitpid(pid, NULL, 0);

    printf("wait return/n");

 

    pid = fork();

    if (pid == 0)

    {

        i = 3;

        memset (&data, 0, sizeof(DBT));

        ret = bdb_get(NULL, affirm_set_dbt(&key, (void*)&i, sizeof(int)), &data, AFFIRM_BDB_FILE);

        printf("ret = %d/n", ret);

 

        if (ret ==0 )

            printf("key = 3, data = %d/n", *(int*)data.data);

 

        exit (0);

    }

    printf("wait .../n");

    waitpid(pid, NULL, 0);

    printf("wait return/n");

 

    i = 3;

    memset (&data, 0, sizeof(DBT));

    ret = bdb_get(NULL, affirm_set_dbt(&key, (void*)&i, sizeof(int)), &data, AFFIRM_BDB_FILE);

    printf("ret = %d/n", ret);

 

    if (ret ==0 )

        printf("key = 3, data = %d/n", *(int*)data.data);

 

    get_func(2);

    put_func();

    get_func(4);

 

    return 0;

}

test.c

 

 

 

 

BIN = bdbtest

OBJS = affirm_table.o bdb_compat.o dbt.o test.o

CC = gcc -Wall

INSTALL = /usr/bin/install -c

TARGET = /var/eyouipb

 

.c.o:

       $(CC) -c $*.c

 

all: $(BIN)

 

$(BIN): $(OBJS)

       $(CC) -o $(BIN) $(OBJS) -ldb

 

clean:

       rm -rf $(OBJS) $(BIN)

 

install: install_affirm_daemon

 

install_affirm_daemon:

       $(INSTALL) $(BIN) $(TARGET)/sbin

Makefile

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值