我编写了一个 C++ 方法,可以重新索引键值对。我正在使用 DB 游标来获取数据并将其存储在一个结构中。将结构复制到另一个结构并修改内容并将其写回数据库(db.put())。这里的代码似乎进入了一个无限循环,当我按下 ctrl+C 时,它以分段错误结束。我是 C++ 和 Berkeley DB 的新手。任何帮助将不胜感激。
int BerkeleyDb::reindex(string dbFileName, string dbAttribName,string inputValue)
{
BdbStruct findExistCmdbData;
BdbStruct* insertCmdbData;
Dbt tempKeyExist;
Dbt tempDataExist;
Dbt tempKeyAndIndex;
Dbt tempDataAndIndex;
DbTxn *txn = NULL;
int retVal = 0;
int keyNotExist=0;
Dbc *keyExistCursor = NULL;
Dbc *delCursor = NULL;
int startIndex = 0;
int newIndex = 0;
int oldIndex = 0;
int offSet = 0;
try
{
// open the DB
Db writedb(&dbenv, 0);
// Begin Transactions
//retVal = dbenv.txn_begin(NULL, &txn, 0);
if(retVal != 0)
{
dbenv.err(retVal,"error in writeBDb::txn_begin");
}
// Open the DB file for writing
writedb.open(NULL,StrtoCharConvert(dbFileName), NULL, DB_BTREE, DB_CREATE |DB_AUTO_COMMIT, DB_OPEN_PERMISSION);
// Initiate cursors
retVal = writedb.cursor(txn,&delCursor,0);
if(retVal != 0)
{
writedb.err (retVal, "error while opening delete cursor");
}
retVal = writedb.cursor(txn,&keyExistCursor,0);
if(retVal != 0)
{
writedb.err (retVal, "error while opening cursor");
}
//to find whether key exist
tempKeyExist.set_size(sizeof( findExistCmdbData.BdbKeyattribute));
tempDataExist.set_size(sizeof(BdbStruct));
while(!(retVal = keyExistCursor->get(&tempKeyExist, &tempDataExist, DB_NEXT)))
{
findExistCmdbData = *(BdbStruct*)(tempDataExist.get_data());
if(string(findExistCmdbData.BdbKeyattribute)== dbAttribName)
{
keyNotExist=1;
}
}
retVal = keyExistCursor->close();
if(retVal != 0)
{
dbenv.err(retVal,"error while closing cursor");
}
if(keyNotExist==0)
{
cerr << "key not exist"<<endl;
retVal = txn->commit(DB_DEFAULT_FLAG);
if(retVal != 0)
{
dbenv.err(retVal,"error while committing transaction");
}
}
else
{
try
{
startIndex = BerkeleyDb::minIndex(dbFileName,dbAttribName);
}
catch (exception &e)
{
cerr << "minIndex failure exception" << e.what() << endl;
}
newIndex = atoi(inputValue.c_str());
oldIndex = startIndex;
offSet = newIndex - startIndex;
tempKeyAndIndex.set_size(sizeof(findExistCmdbData.BdbKeyattribute));
tempDataAndIndex.set_size(sizeof(BdbStruct));
while(!(retVal = delCursor->get(&tempKeyAndIndex, &tempDataAndIndex, DB_NEXT)))
{
findExistCmdbData = *(BdbStruct*)(tempDataAndIndex.get_data());
if((string(findExistCmdbData.BdbKeyattribute)== dbAttribName))
{
insertCmdbData = new BdbStruct;
strcpy(insertCmdbData->BdbKeyattribute, findExistCmdbData.BdbKeyattribute);
insertCmdbData->BdbIndexattribute = findExistCmdbData.BdbIndexattribute + offSet;
strcpy(insertCmdbData->BdbValueattribute, findExistCmdbData.BdbValueattribute);
// writing Key attribute to the DB file
Dbt key(insertCmdbData->BdbKeyattribute, sizeof(insertCmdbData->BdbKeyattribute));
// Writing Value attribute to the DB file
Dbt value((insertCmdbData), (sizeof(BdbStruct)));
retVal = writedb.put(txn, &key, &value, 0);
if (retVal !=0)
{
writedb.err(retVal, "Error while writing to Db");
}
oldIndex++;
newIndex++;
// Memory management for Key - Value and structure
memset(&key, 0, sizeof(key));
memset(&value, 0, sizeof(value));
memset(insertCmdbData, 0, sizeof(BdbStruct));
delete insertCmdbData;
}
retVal = txn->commit(DB_DEFAULT_FLAG);
if(retVal != 0)
{
dbenv.err(retVal,"error while committing transaction");
}
}
retVal = delCursor->close();
if(retVal != 0)
{
dbenv.err(retVal,"error while closing cursor");
}
retVal = txn->commit(DB_DEFAULT_FLAG);
if(retVal != 0)
{
dbenv.err(retVal,"error while committing transaction");
}
}
writedb.close(DB_DEFAULT_FLAG);
}
catch (DbException& dbex)
{
dbenv.err(dbex.get_errno(), "Db exception caught");
return 1;
}
return 0;
}