电子书《BerkeleyDB-Core-Cxx-GSG.pdf》,在chapter5描述了Secondary Database的使用。
Primary Databbase --> db
Secondary Database --> sdb
根据Reading Secondary Databases小节的描述,若要通过Secondary Database读取Primary Databbase的记录,
需要同时打开Primary Databbase和Secondary Database,并且调用db.associate()方法关联Secondary Database。
这样就可以通过sdb中的key,调用方法sdb.get()读取db中相应的data,或者调用sdb.pget()读取db中相应的key和data。
若没有打开Primary Databbase并调用db.associate()方法,则sdb.get()获取的是sdb自身的data,并且sdb.pget()的调用会报如下错误:
db exception: Db::pget: Invalid argument
Press any key to continue
Primary Databbase --> db
Secondary Database --> sdb
根据Reading Secondary Databases小节的描述,若要通过Secondary Database读取Primary Databbase的记录,
需要同时打开Primary Databbase和Secondary Database,并且调用db.associate()方法关联Secondary Database。
这样就可以通过sdb中的key,调用方法sdb.get()读取db中相应的data,或者调用sdb.pget()读取db中相应的key和data。
若没有打开Primary Databbase并调用db.associate()方法,则sdb.get()获取的是sdb自身的data,并且sdb.pget()的调用会报如下错误:
db exception: Db::pget: Invalid argument
Press any key to continue
示例代码:
#include <iostream>
#include <db_cxx.h>
#define PRIMARY_DATABASE "primary.db"
#define SECONDARY_DATABASE "secondary.db"
int get_secondary_key(Db* sdbp, const Dbt* key, const Dbt* data, Dbt* skey)
{
char* pData = (char*)data->get_data();
skey->set_data(pData);
skey->set_size(strlen(pData) + 1);
return 0;
}
int put_records_sdb()
{
Db db(NULL, 0);
Db sdb(NULL, 0);
int nRet = 0;
try {
db.open(NULL, PRIMARY_DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
sdb.set_flags(DB_DUPSORT);
sdb.open(NULL, SECONDARY_DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
db.associate(NULL, &sdb, get_secondary_key, 0);
Dbt key, data;
char* pKey = "first";
key.set_data(pKey);
key.set_size(strlen(pKey) + 1);
char* pData = "value";
data.set_size(strlen(pData) + 1);
data.set_data(pData);
nRet = db.put(NULL, &key, &data, 0);
if (nRet == 0) {
std::cout << "insert record success" << std::endl;
}
}
catch (DbException& e) {
std::cout << "db exception: " << e.what() << std::endl;
}
catch (std::exception &e) {
std::cout << "std::exception: " << e.what() << std::endl;
}
sdb.close(0);
db.close(0);
return 0;
};
int read_records_sdb()
{
Db db(NULL, 0);
Db sdb(NULL, 0);
int nRet = 0;
try {
db.open(NULL, PRIMARY_DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
sdb.set_flags(DB_DUPSORT);
sdb.open(NULL, SECONDARY_DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
db.associate(NULL, &sdb, get_secondary_key, 0);
char* pKeyStr = "value";
Dbt key(pKeyStr, strlen(pKeyStr) + 1);
Dbt pKey, pData; //primary key and data
nRet = sdb.get(NULL, &key, &pData, 0);
if (nRet == 0) {
std::cout << "get primary data: " << (char*)pData.get_data() << std::endl;
}
nRet = sdb.pget(NULL, &key, &pKey, &pData, 0);
if (nRet == 0) {
std::cout << "get primary key: " << (char*)pKey.get_data() << std::endl;
std::cout << "get primary data: " << (char*)pData.get_data() << std::endl;
}
}
catch (DbException& e) {
std::cout << "db exception: " << e.what() << std::endl;
}
catch (std::exception &e) {
std::cout << "std::exception: " << e.what() << std::endl;
}
sdb.close(0);
db.close(0);
return 0;
}
int main()
{
//put_records_sdb();
read_records_sdb();
return 0;
};