| 352 | } |
| 353 | |
| 354 | bool CDB::Rewrite(const string& strFile, const char* pszSkip) |
| 355 | { |
| 356 | while (true) { |
| 357 | { |
| 358 | LOCK(bitdb.cs_db); |
| 359 | if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { |
| 360 | // Flush log data to the dat file |
| 361 | bitdb.CloseDb(strFile); |
| 362 | bitdb.CheckpointLSN(strFile); |
| 363 | bitdb.mapFileUseCount.erase(strFile); |
| 364 | |
| 365 | bool fSuccess = true; |
| 366 | LogPrint(BCLog::CDB,"CDB::Rewrite: Rewriting %s...\n", strFile); |
| 367 | string strFileRes = strFile + ".rewrite"; |
| 368 | { // surround usage of db with extra {} |
| 369 | CDB db(strFile.c_str(), "r"); |
| 370 | Db* pdbCopy = new Db(bitdb.dbenv, 0); |
| 371 | |
| 372 | int ret = pdbCopy->open(NULL, // Txn pointer |
| 373 | strFileRes.c_str(), // Filename |
| 374 | "main", // Logical db name |
| 375 | DB_BTREE, // Database type |
| 376 | DB_CREATE, // Flags |
| 377 | 0); |
| 378 | if (ret > 0) { |
| 379 | LogPrint(BCLog::CDB,"CDB::Rewrite: Can't create database file %s\n", strFileRes); |
| 380 | fSuccess = false; |
| 381 | } |
| 382 | |
| 383 | Dbc* pcursor = db.GetCursor(); |
| 384 | if (pcursor) |
| 385 | while (fSuccess) { |
| 386 | CDataStream ssKey(SER_DISK, CLIENT_VERSION); |
| 387 | CDataStream ssValue(SER_DISK, CLIENT_VERSION); |
| 388 | int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); |
| 389 | if (ret == DB_NOTFOUND) { |
| 390 | pcursor->close(); |
| 391 | break; |
| 392 | } else if (ret != 0) { |
| 393 | pcursor->close(); |
| 394 | fSuccess = false; |
| 395 | break; |
| 396 | } |
| 397 | if (pszSkip && |
| 398 | strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) |
| 399 | continue; |
| 400 | if (strncmp(&ssKey[0], "\x07version", 8) == 0) { |
| 401 | // Update version: |
| 402 | ssValue.clear(); |
| 403 | ssValue << CLIENT_VERSION; |
| 404 | } |
| 405 | Dbt datKey(&ssKey[0], ssKey.size()); |
| 406 | Dbt datValue(&ssValue[0], ssValue.size()); |
| 407 | int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); |
| 408 | if (ret2 > 0) |
| 409 | fSuccess = false; |
| 410 | } |
| 411 | if (fSuccess) { |
nothing calls this directly
no test coverage detected