database: updating migration logic from ptree to rapidjson (#4294)

This commit is contained in:
Nick Anderson 2018-04-17 10:55:58 -07:00 committed by GitHub
parent 1d07098d29
commit 2017068f11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 27 deletions

View File

@ -248,6 +248,8 @@ void resetDatabase();
/// Allow callers to scan each column family and print each value.
void dumpDatabase();
Status ptreeToRapidJSON(const std::string& in, std::string& out);
/**
* @brief Upgrades the legacy database json format from ptree to RapidJSON
*

View File

@ -356,14 +356,39 @@ void dumpDatabase() {
}
}
Status upgradeDatabase() {
std::string db_results_version{""};
getDatabaseValue(kPersistentSettings, "results_version", db_results_version);
Status ptreeToRapidJSON(const std::string& in, std::string& out) {
pt::ptree tree;
try {
std::stringstream ss;
ss << in;
pt::read_json(ss, tree);
} catch (const pt::json_parser::json_parser_error& /* e */) {
return Status(1, "Failed to parse JSON");
}
if (db_results_version == kDatabseResultsVersion) {
if (tree.empty()) {
JSON().toString(out);
return Status();
}
auto json = JSON::newArray();
for (const auto& t : tree) {
std::stringstream ss;
pt::write_json(ss, t.second);
rj::Document row;
if (row.Parse(ss.str()).HasParseError()) {
return Status(1, "Failed to serialize JSON");
}
json.push(row);
}
json.toString(out);
return Status();
}
static Status migrateV0V1(void) {
std::vector<std::string> keys;
auto s = scanDatabaseKeys(kQueries, keys);
if (!s.ok()) {
@ -373,7 +398,8 @@ Status upgradeDatabase() {
for (const auto& key : keys) {
// Skip over epoch and counter entries, as 0 is parsed by ptree
if (boost::algorithm::ends_with(key, kDbEpochSuffix) ||
boost::algorithm::ends_with(key, kDbCounterSuffix)) {
boost::algorithm::ends_with(key, kDbCounterSuffix) ||
boost::algorithm::starts_with(key, "query.")) {
continue;
}
@ -383,37 +409,37 @@ Status upgradeDatabase() {
continue;
}
pt::ptree tree;
try {
std::stringstream ss;
ss << value;
pt::read_json(ss, tree);
} catch (const pt::json_parser::json_parser_error& /* e */) {
LOG(INFO) << "Conversion from ptree to RapidJSON failed for " << key
<< ": " << value;
std::string out;
s = ptreeToRapidJSON(value, out);
if (!s.ok()) {
LOG(WARNING) << "Conversion from ptree to RapidJSON failed for '" << key
<< ": " << value << "': " << s.what() << ". Dropping key!";
continue;
}
auto json = JSON::newArray();
for (const auto& t : tree) {
std::stringstream ss;
pt::write_json(ss, t.second);
rj::Document row;
if (row.Parse(ss.str()).HasParseError()) {
LOG(WARNING) << "Failed to serialize JSON row for " << key;
}
json.push(row);
}
std::string out;
json.toString(out);
if (!setDatabaseValue(kQueries, key, out)) {
LOG(WARNING) << "Failed to update value in database " << key << ": "
<< value;
}
}
return Status();
}
Status upgradeDatabase() {
std::string db_results_version{""};
getDatabaseValue(kPersistentSettings, "results_version", db_results_version);
if (db_results_version == kDatabseResultsVersion) {
return Status();
}
auto s = migrateV0V1();
if (!s.ok()) {
LOG(WARNING) << "Failed to migrate V0 to V1: " << s.what();
return Status(1, "DB migration failed");
}
setDatabaseValue(
kPersistentSettings, "results_version", kDatabseResultsVersion);
return Status();