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";
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;
84 const char* password = NULL;
88 password = spassword.c_str();
93 const char* name = NULL;
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);
128 ca_dir = sca.c_str();
130 ca_file = sca.c_str();
136 const char* cert_file(0);
141 cert_file = scert.c_str();
146 const char* key_file(0);
151 key_file = skey.c_str();
156 const char* cipher_list(0);
161 cipher_list = scipher.c_str();
173 int result = mysql_options(
mysql_, MYSQL_OPT_RECONNECT, &auto_reconnect);
180 const char *wait_time =
"SET SESSION wait_timeout = 30 * 86400";
181 result = mysql_options(
mysql_, MYSQL_INIT_COMMAND, wait_time);
191 const char *sql_mode =
"SET SESSION sql_mode ='STRICT_ALL_TABLES'";
192 result = mysql_options(
mysql_, MYSQL_INIT_COMMAND, sql_mode);
200 result = mysql_options(
mysql_, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
208 if (read_timeout > 0) {
209 result = mysql_options(
mysql_, MYSQL_OPT_READ_TIMEOUT, &read_timeout);
218 if (write_timeout > 0) {
219 result = mysql_options(
mysql_, MYSQL_OPT_WRITE_TIMEOUT, &write_timeout);
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);
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);
334 return (std::make_pair(
version, minor));
336 }
catch (
const std::exception&) {
338 mysql_stmt_close(stmt);
356 if ((index >= statements_.size()) || (statements_[index] != NULL)) {
358 static_cast<int>(index) <<
") or indexed prepared " <<
359 "statement is not null");
364 statements_[index] = mysql_stmt_init(
mysql_);
365 if (statements_[index] == NULL) {
367 "statement structure, reason: " << mysql_error(
mysql_));
370 int status = mysql_stmt_prepare(statements_[index], text, strlen(text));
373 text <<
">, reason: " << mysql_error(
mysql_));
382 tagged_statement != end_statement; ++tagged_statement) {
383 if (tagged_statement->index >= statements_.size()) {
384 statements_.resize(tagged_statement->index + 1, NULL);
389 tagged_statement->text);
398 for (
int i = 0; i < statements_.size(); ++i) {
399 if (statements_[i] != NULL) {
400 (void) mysql_stmt_close(statements_[i]);
401 statements_[i] = NULL;
420 MYSQL_TIME& output_time) {
426 const uint32_t valid_lifetime,
427 MYSQL_TIME& expire) {
433 uint32_t valid_lifetime, time_t& cltt) {
448 int status = mysql_query(
mysql_,
"START TRANSACTION");
451 "reason: " << mysql_error(
mysql_));
472 if (mysql_commit(
mysql_) != 0) {
490 if (mysql_rollback(
mysql_) != 0) {
498 MySqlConnection::setIntParameterValue(
const std::string& name, int64_t min, int64_t max, T& value) {
505 if (svalue.empty()) {
510 auto parsed_value = boost::lexical_cast<T>(svalue);
512 if ((parsed_value < min) || (parsed_value > max)) {
516 value = parsed_value;
523 svalue <<
") must be an integer between "
524 << min <<
" and " << max);
int version()
returns Kea hooks version.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown when an unexpected error condition occurs.
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
void checkUnusable()
Throws an exception if the connection is not usable.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Exception thrown on failure to open database.
Exception thrown on failure to execute a database function.
static void convertFromDatabaseTime(const MYSQL_TIME &expire, uint32_t valid_lifetime, time_t &cltt)
Converts Database Time to Lease Times.
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Converts time_t value to database time.
Common MySQL Connector Pool.
MySqlHolder mysql_
MySQL connection handle.
void prepareStatement(uint32_t index, const char *text)
Prepare Single Statement.
bool isTransactionStarted() const
Checks if there is a transaction in progress.
std::vector< std::string > text_statements_
Raw text of statements.
bool tls_
TLS flag (true when TLS was required, false otherwise).
static void convertToDatabaseTime(const time_t input_time, MYSQL_TIME &output_time)
Convert time_t value to database time.
static void convertFromDatabaseTime(const MYSQL_TIME &expire, uint32_t valid_lifetime, time_t &cltt)
Convert Database Time to Lease Times.
void commit()
Commits current transaction.
void openDatabase()
Open Database.
void prepareStatements(const TaggedStatement *start_statement, const TaggedStatement *end_statement)
Prepare statements.
static std::pair< uint32_t, uint32_t > getVersion(const ParameterMap ¶meters)
Get the schema version.
int transaction_ref_count_
Reference counter for transactions.
void startTransaction()
Starts new transaction.
virtual ~MySqlConnection()
Destructor.
void rollback()
Rollbacks current transaction.
~MySqlTransaction()
Destructor.
void commit()
Commits transaction.
Exception thrown if name of database is not specified.
We want to reuse the database backend connection and exchange code for other uses,...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const int DB_DBG_TRACE_DETAIL
Database logging levels.
const my_bool MLM_FALSE
MySQL false value.
const int MYSQL_DEFAULT_CONNECTION_TIMEOUT
@ MYSQL_START_TRANSACTION
bool my_bool
my_bool type in MySQL 8.x.
int MysqlExecuteStatement(MYSQL_STMT *stmt)
Execute a prepared statement.
bool isDir(const string &name)
Is a directory predicate.
Defines the logger used by the top-level component of kea-lfc.
MySQL Selection Statements.