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;
}
}
{
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相关的随笔