Berkeley DB——Usage



使用

Berkeley DB提供了多种语言的API,但我使用的是其C++ API,虽然C的API来得最直接,但是对我而言比较难用,没有C++的来得舒服——我比较适应面向对象风格的东西。可惜它的C++ API也没有做足够好的封装,使用者还是要写很多繁复的代码,而且要记住它API中会使用到N多的Flag。因此我又把它C++的API包装了一遍,提供更为直观的API,舍弃那些通常不会用到的Flag参数。
在使用中,我发现了几个令人感到疑惑和郁闷的问题(可能是我水平有限的缘故):
1、.DB文件的文件名仅支持char*的,这在国际化软件环境中会是一个问题。
2、不支持直接存入string和wstring类型的数据。STL是人们在使用C++过程中普遍会用到的,而若你直接往Berkeley DB中存入string和wstring(或者Field的类型为string和wstring的结构体)的话,那你将得到不正确的结果——存入数据后,API返回sucess,但是当你把数据再取出时,只能是最后存入的那对key/data,且data中的内容部分字节发生了乱码,比如你在data中存入了hello,那可能取出的内容中前面的字符是he,而后面的字符都是乱码。
3、说是支持重复记录(duplicate records),但是当我按照其示例代码调用相应的API时,却发生异常:无效的参数!真不知道Sleepycat哪个环节的工作出了问题。
4、其源码说是可以使用vs2005编译,但是使用vs2005编译会出现大把大把的错误,而使用vc6编译则无问题。

示例

下面是我测试其duplicate records的代码(执行并不成功,报“无效的参数”):

void TestMultiData()
{
    
int ret = 0;
    Db db(NULL,
0);
    ret 
= db.set_flags(DB_DUP);
    ret 
= db.open(NULL,"multi.db",NULL,DB_BTREE,DB_CREATE,0);
    
    ret 
= db.truncate(NULL,0,0);

    Dbt key,data;
    
char *strk,*strd;
    strk 
= "001";
    key.set_data(strk);
    key.set_size(strlen(strk)
+1);
    strd 
= "data1";
    data.set_data(strd);
    data.set_size(strlen(strd)
+1);
    ret 
= db.put(NULL,&key,&data,0);

    strd 
= "data2";
    data.set_data(strd);
    data.set_size(strlen(strd)
+1);
    ret 
= db.put(NULL,&key,&data,0);

    strd 
= "data3";
    data.set_data(strd);
    data.set_size(strlen(strd)
+1);
    ret 
= db.put(NULL,&key,&data,0);


    Dbt dataBuffer;
    dataBuffer.set_data(
&strd);
    dataBuffer.set_ulen(
6*1024);
    dataBuffer.set_flags(DB_DBT_USERMEM);
    
    
try
    
{
        ret 
= db.get(NULL,&key,&dataBuffer,DB_MULTIPLE);
    }

    
catch (DbException &e)
    
{
        cout
<<"  "<<e.what();
    }

    DbMultipleDataIterator iterator(dataBuffer);
    Dbt mdata;
    
while ( iterator.next(mdata) == true )
    
{
        
char *str = (char*)mdata.get_data();
        cout
<<"data:  "<<str<<endl;
    }

}


所有Berkeley DB相关的随笔
posted @ 2006-04-12 15:43  风满袖  阅读(3429)  评论(3编辑  收藏  举报