14 #include <boost/lexical_cast.hpp> 27 int MySqlHolder::atexit_ = [] {
28 return atexit([] { mysql_library_end(); });
35 : conn_(conn), committed_(false) {
58 const char* host =
"localhost";
61 shost = getParameter(
"host");
67 unsigned int port = 0;
69 setIntParameterValue(
"port", 0, numeric_limits<uint16_t>::max(), port);
71 }
catch (
const std::exception& ex) {
75 const char* user = NULL;
78 suser = getParameter(
"user");
84 const char* password = NULL;
87 spassword = getParameter(
"password");
88 password = spassword.c_str();
93 const char* name = NULL;
96 sname = getParameter(
"name");
104 unsigned int read_timeout = 0;
105 unsigned int write_timeout = 0;
110 setIntParameterValue(
"connect-timeout", 1, numeric_limits<int>::max(), connect_timeout);
114 setIntParameterValue(
"read-timeout", 0, numeric_limits<int>::max(), read_timeout);
115 setIntParameterValue(
"write-timeout", 0, numeric_limits<int>::max(), write_timeout);
117 }
catch (
const std::exception& ex) {
121 const char* ca_file(0);
122 const char* ca_dir(0);
125 sca = getParameter(
"trust-anchor");
128 ca_dir = sca.c_str();
130 ca_file = sca.c_str();
136 const char* cert_file(0);
139 scert = getParameter(
"cert-file");
141 cert_file = scert.c_str();
146 const char* key_file(0);
149 skey = getParameter(
"key-file");
151 key_file = skey.c_str();
156 const char* cipher_list(0);
159 scipher = getParameter(
"cipher-list");
161 cipher_list = scipher.c_str();
173 int result = mysql_options(mysql_, MYSQL_OPT_RECONNECT, &auto_reconnect);
176 mysql_error(mysql_));
180 const char *wait_time =
"SET SESSION wait_timeout = 30 * 86400";
181 result = mysql_options(mysql_, MYSQL_INIT_COMMAND, wait_time);
184 mysql_error(mysql_));
191 const char *sql_mode =
"SET SESSION sql_mode ='STRICT_ALL_TABLES'";
192 result = mysql_options(mysql_, MYSQL_INIT_COMMAND, sql_mode);
195 mysql_error(mysql_));
200 result = mysql_options(mysql_, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
203 mysql_error(mysql_));
208 if (read_timeout > 0) {
209 result = mysql_options(mysql_, MYSQL_OPT_READ_TIMEOUT, &read_timeout);
212 mysql_error(mysql_));
218 if (write_timeout > 0) {
219 result = mysql_options(mysql_, MYSQL_OPT_WRITE_TIMEOUT, &write_timeout);
222 mysql_error(mysql_));
229 mysql_ssl_set(mysql_, key_file, cert_file, ca_file, ca_dir,
243 MYSQL* status = mysql_real_connect(mysql_, host, user, password, name,
244 port, NULL, CLIENT_FOUND_ROWS);
245 if (status != mysql_) {
256 my_bool autocommit_result = mysql_autocommit(mysql_, 1);
257 if (autocommit_result != 0) {
270 std::pair<uint32_t, uint32_t>
279 MYSQL_STMT *stmt = mysql_stmt_init(conn.
mysql_);
282 "statement structure, reason: " << mysql_error(conn.
mysql_));
288 const char* version_sql =
"SELECT version, minor FROM schema_version";
289 int status = mysql_stmt_prepare(stmt, version_sql, strlen(version_sql));
292 << version_sql <<
">, reason: " 293 << mysql_error(conn.
mysql_));
299 << version_sql <<
">, reason: " 300 << mysql_errno(conn.
mysql_));
305 memset(bind, 0,
sizeof(bind));
308 bind[0].buffer_type = MYSQL_TYPE_LONG;
309 bind[0].is_unsigned = 1;
311 bind[0].buffer_length =
sizeof(
version);
314 bind[1].buffer_type = MYSQL_TYPE_LONG;
315 bind[1].is_unsigned = 1;
316 bind[1].buffer = &minor;
317 bind[1].buffer_length =
sizeof(minor);
319 if (mysql_stmt_bind_result(stmt, bind)) {
321 << version_sql <<
">, reason: " 322 << mysql_errno(conn.
mysql_));
326 if (mysql_stmt_fetch(stmt)) {
328 << version_sql <<
">, reason: " 329 << mysql_errno(conn.
mysql_));
333 mysql_stmt_close(stmt);
335 return (std::make_pair(version, minor));
337 }
catch (
const std::exception&) {
339 mysql_stmt_close(stmt);
357 if ((index >= statements_.size()) || (statements_[index] != NULL)) {
359 static_cast<int>(index) <<
") or indexed prepared " <<
360 "statement is not null");
364 text_statements_[index] = std::string(text);
365 statements_[index] = mysql_stmt_init(mysql_);
366 if (statements_[index] == NULL) {
368 "statement structure, reason: " << mysql_error(mysql_));
371 int status = mysql_stmt_prepare(statements_[index], text, strlen(text));
374 text <<
">, reason: " << mysql_error(mysql_));
383 tagged_statement != end_statement; ++tagged_statement) {
384 if (tagged_statement->index >= statements_.size()) {
385 statements_.resize(tagged_statement->index + 1, NULL);
386 text_statements_.resize(tagged_statement->index + 1,
389 prepareStatement(tagged_statement->index,
390 tagged_statement->text);
396 text_statements_.clear();
404 for (
int i = 0; i < statements_.size(); ++i) {
405 if (statements_[i] != NULL) {
406 (void) mysql_stmt_close(statements_[i]);
407 statements_[i] = NULL;
411 text_statements_.clear();
426 MYSQL_TIME& output_time) {
432 const uint32_t valid_lifetime,
433 MYSQL_TIME& expire) {
439 uint32_t valid_lifetime, time_t& cltt) {
446 if (++transaction_ref_count_ > 1) {
454 int status = mysql_query(mysql_,
"START TRANSACTION");
457 "reason: " << mysql_error(mysql_));
463 return (transaction_ref_count_ > 0);
468 if (transaction_ref_count_ <= 0) {
473 if (--transaction_ref_count_ > 0) {
478 if (mysql_commit(mysql_) != 0) {
480 << mysql_error(mysql_));
486 if (transaction_ref_count_ <= 0) {
491 if (--transaction_ref_count_ > 0) {
496 if (mysql_rollback(mysql_) != 0) {
498 << mysql_error(mysql_));
504 MySqlConnection::setIntParameterValue(
const std::string& name, int64_t min, int64_t max, T& value) {
507 svalue = getParameter(name);
511 if (svalue.empty()) {
516 auto parsed_value = boost::lexical_cast<T>(svalue);
518 if ((parsed_value < min) || (parsed_value > max)) {
522 value = parsed_value;
529 svalue <<
") must be an integer between " 530 << min <<
" and " << max);
We want to reuse the database backend connection and exchange code for other uses, in particular for hook libraries.
bool my_bool
my_bool type in MySQL 8.x.
MySqlHolder mysql_
MySQL connection handle.
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Convert time_t value to database time.
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Converts time_t value to database time.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters)
Get the schema version.
void commit()
Commits transaction.
static void convertFromDatabaseTime(const MYSQL_TIME &expire, uint32_t valid_lifetime, time_t &cltt)
Convert Database Time to Lease Times.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Exception thrown on failure to open database.
int MysqlExecuteStatement(MYSQL_STMT *stmt)
Execute a prepared statement.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
const my_bool MLM_FALSE
MySQL false value.
Exception thrown if name of database is not specified.
A generic exception that is thrown when an unexpected error condition occurs.
int version()
returns Kea hooks version.
static void convertFromDatabaseTime(const MYSQL_TIME &expire, uint32_t valid_lifetime, time_t &cltt)
Converts Database Time to Lease Times.
void clearStatements()
Clears prepared statements and text statements.
const int MYSQL_DEFAULT_CONNECTION_TIMEOUT
virtual ~MySqlConnection()
Destructor.
bool isDir(const string &name)
Is a directory predicate.
bool isTransactionStarted() const
Checks if there is a transaction in progress.
const int DB_DBG_TRACE_DETAIL
Database logging levels.
Defines the logger used by the top-level component of kea-lfc.
void startTransaction()
Starts new transaction.
void rollback()
Rollbacks current transaction.
void commit()
Commits current transaction.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
void prepareStatement(uint32_t index, const char *text)
Prepare Single Statement.
void prepareStatements(const TaggedStatement *start_statement, const TaggedStatement *end_statement)
Prepare statements.
void openDatabase()
Open Database.
MySQL Selection Statements.
Exception thrown on failure to execute a database function.
~MySqlTransaction()
Destructor.
Common MySQL Connector Pool.