mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-09 02:15:21 +00:00
[#92,!13] New libkea-database library created.
This commit is contained in:
159
src/lib/database/database_connection.cc
Normal file
159
src/lib/database/database_connection.cc
Normal file
@@ -0,0 +1,159 @@
|
||||
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <database/database_connection.h>
|
||||
#include <database/db_exceptions.h>
|
||||
#include <database/db_log.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace isc {
|
||||
namespace db {
|
||||
|
||||
const time_t DatabaseConnection::MAX_DB_TIME = 2147483647;
|
||||
|
||||
std::string
|
||||
DatabaseConnection::getParameter(const std::string& name) const {
|
||||
ParameterMap::const_iterator param = parameters_.find(name);
|
||||
if (param == parameters_.end()) {
|
||||
isc_throw(BadValue, "Parameter " << name << " not found");
|
||||
}
|
||||
return (param->second);
|
||||
}
|
||||
|
||||
DatabaseConnection::ParameterMap
|
||||
DatabaseConnection::parse(const std::string& dbaccess) {
|
||||
DatabaseConnection::ParameterMap mapped_tokens;
|
||||
|
||||
if (!dbaccess.empty()) {
|
||||
vector<string> tokens;
|
||||
|
||||
// We need to pass a string to is_any_of, not just char*. Otherwise
|
||||
// there are cryptic warnings on Debian6 running g++ 4.4 in
|
||||
// /usr/include/c++/4.4/bits/stl_algo.h:2178 "array subscript is above
|
||||
// array bounds"
|
||||
boost::split(tokens, dbaccess, boost::is_any_of(string("\t ")));
|
||||
BOOST_FOREACH(std::string token, tokens) {
|
||||
size_t pos = token.find("=");
|
||||
if (pos != string::npos) {
|
||||
string name = token.substr(0, pos);
|
||||
string value = token.substr(pos + 1);
|
||||
mapped_tokens.insert(make_pair(name, value));
|
||||
} else {
|
||||
DB_LOG_ERROR(DB_INVALID_ACCESS).arg(dbaccess);
|
||||
isc_throw(InvalidParameter, "Cannot parse " << token
|
||||
<< ", expected format is name=value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (mapped_tokens);
|
||||
}
|
||||
|
||||
std::string
|
||||
DatabaseConnection::redactedAccessString(const ParameterMap& parameters) {
|
||||
// Reconstruct the access string: start of with an empty string, then
|
||||
// work through all the parameters in the original string and add them.
|
||||
std::string access;
|
||||
for (DatabaseConnection::ParameterMap::const_iterator i = parameters.begin();
|
||||
i != parameters.end(); ++i) {
|
||||
|
||||
// Separate second and subsequent tokens are preceded by a space.
|
||||
if (!access.empty()) {
|
||||
access += " ";
|
||||
}
|
||||
|
||||
// Append name of parameter...
|
||||
access += i->first;
|
||||
access += "=";
|
||||
|
||||
// ... and the value, except in the case of the password, where a
|
||||
// redacted value is appended.
|
||||
if (i->first == std::string("password")) {
|
||||
access += "*****";
|
||||
} else {
|
||||
access += i->second;
|
||||
}
|
||||
}
|
||||
|
||||
return (access);
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseConnection::configuredReadOnly() const {
|
||||
std::string readonly_value = "false";
|
||||
try {
|
||||
readonly_value = getParameter("readonly");
|
||||
boost::algorithm::to_lower(readonly_value);
|
||||
} catch (...) {
|
||||
// Parameter "readonly" hasn't been specified so we simply use
|
||||
// the default value of "false".
|
||||
}
|
||||
|
||||
if ((readonly_value != "false") && (readonly_value != "true")) {
|
||||
isc_throw(DbInvalidReadOnly, "invalid value '" << readonly_value
|
||||
<< "' specified for boolean parameter 'readonly'");
|
||||
}
|
||||
|
||||
return (readonly_value == "true");
|
||||
}
|
||||
|
||||
ReconnectCtlPtr
|
||||
DatabaseConnection::makeReconnectCtl() const {
|
||||
ReconnectCtlPtr retry;
|
||||
string type = "unknown";
|
||||
unsigned int retries = 0;
|
||||
unsigned int interval = 0;
|
||||
|
||||
// Assumes that parsing ensurse only valid values are present
|
||||
try {
|
||||
type = getParameter("type");
|
||||
} catch (...) {
|
||||
// Wasn't specified so we'll use default of "unknown".
|
||||
}
|
||||
|
||||
std::string parm_str;
|
||||
try {
|
||||
parm_str = getParameter("max-reconnect-tries");
|
||||
retries = boost::lexical_cast<unsigned int>(parm_str);
|
||||
} catch (...) {
|
||||
// Wasn't specified so we'll use default of 0;
|
||||
}
|
||||
|
||||
try {
|
||||
parm_str = getParameter("reconnect-wait-time");
|
||||
interval = boost::lexical_cast<unsigned int>(parm_str);
|
||||
} catch (...) {
|
||||
// Wasn't specified so we'll use default of 0;
|
||||
}
|
||||
|
||||
retry.reset(new ReconnectCtl(type, retries, interval));
|
||||
return (retry);
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseConnection::invokeDbLostCallback() const {
|
||||
if (DatabaseConnection::db_lost_callback) {
|
||||
// Invoke the callback, passing in a new instance of ReconnectCtl
|
||||
return (DatabaseConnection::db_lost_callback)(makeReconnectCtl());
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
DatabaseConnection::DbLostCallback
|
||||
DatabaseConnection::db_lost_callback = 0;
|
||||
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user