7 #ifndef MYSQL_CONNECTION_H 8 #define MYSQL_CONNECTION_H 17 #include <boost/scoped_ptr.hpp> 19 #include <mysqld_error.h> 63 (void) mysql_stmt_free_result(statement_);
67 MYSQL_STMT* statement_;
88 template <
typename Fun,
typename... Args>
91 for (
unsigned count = 0; count < 5; ++count) {
92 status = fun(args...);
93 if (status != ER_LOCK_DEADLOCK) {
141 if (mysql_ == NULL) {
150 if (mysql_ != NULL) {
159 operator MYSQL*()
const {
252 io_service_accessor_(io_accessor), io_service_(),
253 transaction_ref_count_(0), tls_(false) {
269 static std::pair<uint32_t, uint32_t>
285 void prepareStatement(uint32_t index,
const char* text);
305 void clearStatements();
330 void convertToDatabaseTime(
const time_t input_time, MYSQL_TIME& output_time);
352 void convertToDatabaseTime(
const time_t cltt,
const uint32_t valid_lifetime,
373 void convertFromDatabaseTime(
const MYSQL_TIME& expire,
374 uint32_t valid_lifetime, time_t& cltt);
390 void startTransaction();
395 bool isTransactionStarted()
const;
424 template<
typename StatementIndex>
428 ConsumeResultFun process_result) {
431 std::vector<MYSQL_BIND> in_bind_vec;
433 in_bind_vec.push_back(in_binding->getMySqlBinding());
437 if (!in_bind_vec.empty()) {
439 status = mysql_stmt_bind_param(statements_[index],
440 in_bind_vec.empty() ? 0 : &in_bind_vec[0]);
441 checkError(status, index,
"unable to bind parameters for select");
445 std::vector<MYSQL_BIND> out_bind_vec;
447 out_bind_vec.push_back(out_binding->getMySqlBinding());
449 if (!out_bind_vec.empty()) {
450 status = mysql_stmt_bind_result(statements_[index], &out_bind_vec[0]);
451 checkError(status, index,
"unable to bind result parameters for select");
456 checkError(status, index,
"unable to execute");
458 status = mysql_stmt_store_result(statements_[index]);
459 checkError(status, index,
"unable to set up for storing all results");
463 while ((status = mysql_stmt_fetch(statements_[index])) ==
468 process_result(out_bindings);
470 }
catch (
const std::exception& ex) {
473 text_statements_[index] <<
">");
481 checkError(status, index,
"unable to fetch results");
483 }
else if (status == MYSQL_DATA_TRUNCATED) {
486 <<
" returned truncated data");
504 template<
typename StatementIndex>
508 std::vector<MYSQL_BIND> in_bind_vec;
510 in_bind_vec.push_back(in_binding->getMySqlBinding());
514 int status = mysql_stmt_bind_param(statements_[index],
515 in_bind_vec.empty() ? 0 : &in_bind_vec[0]);
516 checkError(status, index,
"unable to bind parameters");
523 if (mysql_errno(mysql_) == ER_DUP_ENTRY) {
527 if (mysql_errno(mysql_) == ER_BAD_NULL_ERROR) {
530 checkError(status, index,
"unable to execute");
548 template<
typename StatementIndex>
552 std::vector<MYSQL_BIND> in_bind_vec;
554 in_bind_vec.push_back(in_binding->getMySqlBinding());
558 int status = mysql_stmt_bind_param(statements_[index],
559 in_bind_vec.empty() ? 0 : &in_bind_vec[0]);
560 checkError(status, index,
"unable to bind parameters");
567 if ((mysql_errno(mysql_) == ER_DUP_ENTRY)
568 #ifdef ER_FOREIGN_DUPLICATE_KEY
569 || (mysql_errno(mysql_) == ER_FOREIGN_DUPLICATE_KEY)
571 #ifdef ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO
572 || (mysql_errno(mysql_) == ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO)
574 #ifdef ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO
575 || (mysql_errno(mysql_) == ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO)
580 checkError(status, index,
"unable to execute");
584 return (static_cast<uint64_t>(mysql_stmt_affected_rows(statements_[index])));
639 template<
typename StatementIndex>
640 void checkError(
const int status,
const StatementIndex& index,
643 switch(mysql_errno(mysql_)) {
650 case CR_SERVER_GONE_ERROR:
652 case CR_OUT_OF_MEMORY:
653 case CR_CONNECTION_ERROR: {
656 .
arg(text_statements_[static_cast<int>(index)])
657 .
arg(mysql_error(mysql_))
658 .
arg(mysql_errno(mysql_));
664 startRecoverDbConnection();
669 "fatal database error or connectivity lost");
674 << text_statements_[static_cast<int>(index)]
676 << mysql_error(mysql_) <<
" (error code " 677 << mysql_errno(mysql_) <<
")");
689 if (!io_service_ && io_service_accessor_) {
690 io_service_ = (*io_service_accessor_)();
691 io_service_accessor_.reset();
695 io_service_->post(std::bind(callback_, reconnectCtl()));
711 const char* cipher = mysql_get_ssl_cipher(mysql_);
712 return (cipher ? std::string(cipher) :
"");
732 void setIntParameterValue(
const std::string& name, int64_t min, int64_t max, T& value);
781 #endif // MYSQL_CONNECTION_H std::vector< std::string > text_statements_
Raw text of statements.
We want to reuse the database backend connection and exchange code for other uses, in particular for hook libraries.
void selectQuery(const StatementIndex &index, const MySqlBindingCollection &in_bindings, MySqlBindingCollection &out_bindings, ConsumeResultFun process_result)
Executes SELECT query using prepared statement.
std::function< bool(util::ReconnectCtlPtr db_reconnect_ctl)> DbCallback
Defines a callback prototype for propagating events upward.
MySqlHolder mysql_
MySQL connection handle.
Fetch and Release MySQL Results.
void insertQuery(const StatementIndex &index, const MySqlBindingCollection &in_bindings)
Executes INSERT prepared statement.
std::function< void(MySqlBindingCollection &)> ConsumeResultFun
Function invoked to process fetched row.
void checkError(const int status, const StatementIndex &index, const char *what)
Check Error and Throw Exception.
int transaction_ref_count_
Reference counter for transactions.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
MySqlFreeResult(MYSQL_STMT *statement)
Constructor.
Common database connection class.
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...
isc::asiolink::IOServicePtr io_service_
IOService object, used for all ASIO operations.
bool getTls() const
Get the TLS flag.
int MysqlQuery(MYSQL *mysql, const char *stmt)
Execute a literal statement.
std::string getTlsCipher()
Get the TLS cipher.
int retryOnDeadlock(Fun &fun, Args... args)
Retry on InnoDB deadlock.
~MySqlFreeResult()
Destructor.
const int MLM_MYSQL_FETCH_SUCCESS
check for bool size
Defines the logger used by the top-level component of kea-lfc.
uint64_t updateDeleteQuery(const StatementIndex &index, const MySqlBindingCollection &in_bindings)
Executes UPDATE or DELETE prepared statement and returns the number of affected rows.
DB_LOG & arg(T first, Args... args)
Pass parameters to replace logger placeholders.
std::vector< MYSQL_STMT * > statements_
Prepared statements.
const int MLM_MYSQL_FETCH_FAILURE
MySQL fetch failure code.
bool tls_
TLS flag (true when TLS was required, false otherwise).
MySqlHolder()
Constructor.
RAII object representing MySQL transaction.
MySqlConnection(const ParameterMap ¶meters, IOServiceAccessorPtr io_accessor=IOServiceAccessorPtr(), DbCallback callback=DbCallback())
Constructor.
void startRecoverDbConnection()
The recover connection.
std::vector< MySqlBindingPtr > MySqlBindingCollection
Collection of bindings.
Exception thrown when a specific connection has been rendered unusable either through loss of connect...
IOServiceAccessorPtr io_service_accessor_
Accessor function which returns the IOService that can be used to recover the connection.
boost::shared_ptr< MySqlBinding > MySqlBindingPtr
Shared pointer to the Binding class.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
~MySqlHolder()
Destructor.
MySQL Selection Statements.
Exception thrown on failure to execute a database function.
Key is NULL but was specified NOT NULL.
boost::shared_ptr< IOServiceAccessor > IOServiceAccessorPtr
Pointer to an instance of IOServiceAccessor.
Database duplicate entry error.
Common MySQL Connector Pool.