根据《BerkeleyDB-Core-Cxx-GSG.pdf》对于支持sorted duplicates的btree,替换重复record的data,会因为排序规则导致替换失败。
文章中说明对于这种btree,若想替换重复record的data,需要先删除然后在put新记录。
示例代码:
#include <iostream>
#include <db_cxx.h>
#include "print.hh"
#define DATABASE "duplicated.db"
int main()
{
Db my_database(NULL, 0);
Dbc *cursorp;
int nRet = 0;
try {
// open database
my_database.open(NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
// open cursor
my_database.cursor(NULL, &cursorp, 0);
// print all records
RECORDS_PRINT(cursorp, "before: ");
char* key1str = "Alabama";
char* data1str = "Florence";
char* replacement_data = "Replace me";
// set up on DBT
Dbt key(key1str, strlen(key1str) + 1);
Dbt data;
// position the cursor for sort duplicated database
nRet = cursorp->get(&key, &data, DB_SET);
if (nRet == 0) {
data.set_data(replacement_data);
data.set_size(strlen(replacement_data) + 1);
cursorp->del(0); //删除要替换的记录
nRet = my_database.put(NULL, &key, &data, 0); //插入新记录
if (nRet != 0) {
std::cout << "put failed!" << std::endl;
}
}
// print all records
RECORDS_PRINT(cursorp, "after: ");
}
catch (DbException& e) {
std::cout << "db exception: " << e.what() << std::endl;
}
catch (std::exception &e) {
std::cout << "std::exception: " << e.what() << std::endl;
}
if (cursorp != NULL)
cursorp->close();
my_database.close(0);
return 0;
}
执行结果:
before:
Alabama Athens
Alabama Florence
Alaska Anchorage
Alaska Fairbanks
Arizona Florence
after:
Alabama Florence
Alabama Replace me
Alaska Anchorage
Alaska Fairbanks
Arizona Florence
Press any key to continue
附上print.hh
// use cursor to print all records
#define RECORDS_PRINT(cursorp, optstr) \
do { \
std::cout << optstr << std::endl; \
Dbc* cursorp_d; \
cursorp->dup(&cursorp_d, 0); \
Dbt key, data; \
while ((nRet = cursorp_d->get(&key, &data, DB_NEXT)) != DB_NOTFOUND) { \
std::cout << (char*)key.get_data() << " " << (char*)data.get_data() << std::endl; \
} \
} while (0);