LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_HOST_DB_GET_VERSION);
+ MySqlHolder& holderHandle = conn_.handle();
+
// Allocate a new statement.
- MYSQL_STMT *stmt = mysql_stmt_init(conn_.handle());
+ MYSQL_STMT *stmt = mysql_stmt_init(holderHandle);
if (stmt == NULL) {
isc_throw(DbOperationError, "unable to allocate MySQL prepared "
- "statement structure, reason: " << mysql_error(conn_.handle()));
+ "statement structure, reason: " << mysql_error(holderHandle));
}
// Prepare the statement from SQL text.
if (status != 0) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "unable to prepare MySQL statement <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Execute the prepared statement.
if (mysql_stmt_execute(stmt) != 0) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "cannot execute schema version query <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Bind the output of the statement to the appropriate variables.
if (mysql_stmt_bind_result(stmt, bind)) {
isc_throw(DbOperationError, "unable to bind result set for <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Fetch the data.
if (mysql_stmt_fetch(stmt)) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "unable to bind result set for <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Discard the statement and its resources
void
MySqlHostDataSourceImpl::addStatement(StatementIndex stindex,
std::vector<MYSQL_BIND>& bind) {
+ MySqlHolder& holderHandle = conn_.handle();
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], &bind[0]);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], &bind[0]);
checkError(status, stindex, "unable to bind parameters");
// Execute the statement
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
if (status != 0) {
// Failure: check for the special case of duplicate entry.
- if (mysql_errno(conn_.handle()) == ER_DUP_ENTRY) {
+ if (mysql_errno(holderHandle) == ER_DUP_ENTRY) {
isc_throw(DuplicateEntry, "Database duplicate entry error");
}
checkError(status, stindex, "unable to execute");
bool
MySqlHostDataSourceImpl::delStatement(StatementIndex stindex,
MYSQL_BIND* bind) {
+ MySqlHolder& holderHandle = conn_.handle();
+
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], &bind[0]);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], &bind[0]);
checkError(status, stindex, "unable to bind parameters");
// Execute the statement
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
if (status != 0) {
checkError(status, stindex, "unable to execute");
}
// Let's check how many hosts were deleted.
- my_ulonglong numrows = mysql_stmt_affected_rows(conn_.handle().statements_[stindex]);
+ my_ulonglong numrows = mysql_stmt_affected_rows(holderHandle.statements_[stindex]);
return (numrows != 0);
}
getHostCollection(StatementIndex stindex, MYSQL_BIND* bind,
boost::shared_ptr<MySqlHostExchange> exchange,
ConstHostCollection& result, bool single) const {
+ MySqlHolder& holderHandle = conn_.handle();
// Bind the selection parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], bind);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], bind);
checkError(status, stindex, "unable to bind WHERE clause parameter");
// Set up the MYSQL_BIND array for the data being returned and bind it to
// the statement.
std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
- status = mysql_stmt_bind_result(conn_.handle().statements_[stindex], &outbind[0]);
+ status = mysql_stmt_bind_result(holderHandle.statements_[stindex], &outbind[0]);
checkError(status, stindex, "unable to bind SELECT clause parameters");
// Execute the statement
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to execute");
// Ensure that all the lease information is retrieved in one go to avoid
// overhead of going back and forth between client and server.
- status = mysql_stmt_store_result(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_store_result(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to set up for storing all results");
// Set up the fetch "release" object to release resources associated
// with the call to mysql_stmt_fetch when this method exits, then
// retrieve the data. mysql_stmt_fetch return value equal to 0 represents
// successful data fetch.
- MySqlFreeResult fetch_release(conn_.handle().statements_[stindex]);
- while ((status = mysql_stmt_fetch(conn_.handle().statements_[stindex])) ==
+ MySqlFreeResult fetch_release(holderHandle.statements_[stindex]);
+ while ((status = mysql_stmt_fetch(holderHandle.statements_[stindex])) ==
MLM_MYSQL_FETCH_SUCCESS) {
try {
exchange->processFetchedData(result);
void
MySqlHostDataSource::add(const HostPtr& host) {
+ MySqlHolder& holderHandle = impl_->conn_.handle();
+
// If operating in read-only mode, throw exception.
impl_->checkReadOnly();
impl_->addStatement(MySqlHostDataSourceImpl::INSERT_HOST, bind);
// Gets the last inserted hosts id
- uint64_t host_id = mysql_insert_id(impl_->conn_.handle());
+ uint64_t host_id = mysql_insert_id(holderHandle);
// Insert DHCPv4 options.
ConstCfgOptionPtr cfg_option4 = host->getCfgOption4();
/// Safely fetch the statement from the connection based on statement index
/// @throw BadValue if statement index is out of range
void validateStatement() {
+ MySqlHolder& holderHandle = conn_.handle();
+
if (statement_index_ >= MySqlLeaseMgr::NUM_STATEMENTS) {
isc_throw(BadValue, "MySqlLeaseStatsQuery"
" - invalid statement index" << statement_index_);
}
- statement_ = conn_.handle().statements_[statement_index_];
+ statement_ = holderHandle.statements_[statement_index_];
}
/// @brief Database connection to use to execute the query
bool
MySqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
std::vector<MYSQL_BIND>& bind) {
+ MySqlHolder& holderHandle = conn_.handle();
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], &bind[0]);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], &bind[0]);
checkError(status, stindex, "unable to bind parameters");
// Execute the statement
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
if (status != 0) {
// Failure: check for the special case of duplicate entry. If this is
// the case, we return false to indicate that the row was not added.
// Otherwise we throw an exception.
- if (mysql_errno(conn_.handle()) == ER_DUP_ENTRY) {
+ if (mysql_errno(holderHandle) == ER_DUP_ENTRY) {
return (false);
}
checkError(status, stindex, "unable to execute");
Exchange& exchange,
LeaseCollection& result,
bool single) const {
-
+ MySqlHolder& holderHandle = conn_.handle();
int status;
if (bind) {
// Bind the selection parameters to the statement
- status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], bind);
+ status = mysql_stmt_bind_param(holderHandle.statements_[stindex], bind);
checkError(status, stindex, "unable to bind WHERE clause parameter");
}
// Set up the MYSQL_BIND array for the data being returned and bind it to
// the statement.
std::vector<MYSQL_BIND> outbind = exchange->createBindForReceive();
- status = mysql_stmt_bind_result(conn_.handle().statements_[stindex], &outbind[0]);
+ status = mysql_stmt_bind_result(holderHandle.statements_[stindex], &outbind[0]);
checkError(status, stindex, "unable to bind SELECT clause parameters");
// Execute the statement
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to execute");
// Ensure that all the lease information is retrieved in one go to avoid
// overhead of going back and forth between client and server.
- status = mysql_stmt_store_result(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_store_result(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to set up for storing all results");
// Set up the fetch "release" object to release resources associated
// with the call to mysql_stmt_fetch when this method exits, then
// retrieve the data.
- MySqlFreeResult fetch_release(conn_.handle().statements_[stindex]);
+ MySqlFreeResult fetch_release(holderHandle.statements_[stindex]);
int count = 0;
- while ((status = mysql_stmt_fetch(conn_.handle().statements_[stindex])) == 0) {
+ while ((status = mysql_stmt_fetch(holderHandle.statements_[stindex])) == 0) {
try {
result.push_back(exchange->getLeaseData());
void
MySqlLeaseMgr::updateLeaseCommon(StatementIndex stindex, MYSQL_BIND* bind,
const LeasePtr& lease) {
+ MySqlHolder& holderHandle = conn_.handle();
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], bind);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], bind);
checkError(status, stindex, "unable to bind parameters");
// Execute
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to execute");
// See how many rows were affected. The statement should only update a
// single row.
- int affected_rows = mysql_stmt_affected_rows(conn_.handle().statements_[stindex]);
+ int affected_rows = mysql_stmt_affected_rows(holderHandle.statements_[stindex]);
if (affected_rows == 0) {
isc_throw(NoSuchLease, "unable to update lease for address " <<
lease->addr_ << " as it does not exist");
uint64_t
MySqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex, MYSQL_BIND* bind) {
+ MySqlHolder& holderHandle = conn_.handle();
// Bind the input parameters to the statement
- int status = mysql_stmt_bind_param(conn_.handle().statements_[stindex], bind);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[stindex], bind);
checkError(status, stindex, "unable to bind WHERE clause parameter");
// Execute
- status = mysql_stmt_execute(conn_.handle().statements_[stindex]);
+ status = mysql_stmt_execute(holderHandle.statements_[stindex]);
checkError(status, stindex, "unable to execute");
// See how many rows were affected. Note that the statement may delete
// multiple rows.
- return (static_cast<uint64_t>(mysql_stmt_affected_rows(conn_.handle().statements_[stindex])));
+ return (static_cast<uint64_t>(mysql_stmt_affected_rows(holderHandle.statements_[stindex])));
}
bool
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_VERSION);
+ MySqlHolder& holderHandle = conn_.handle();
+
// Allocate a new statement.
- MYSQL_STMT *stmt = mysql_stmt_init(conn_.handle());
+ MYSQL_STMT *stmt = mysql_stmt_init(holderHandle);
if (stmt == NULL) {
isc_throw(DbOperationError, "unable to allocate MySQL prepared "
- "statement structure, reason: " << mysql_error(conn_.handle()));
+ "statement structure, reason: " << mysql_error(holderHandle));
}
// Prepare the statement from SQL text.
if (status != 0) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "unable to prepare MySQL statement <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Execute the prepared statement.
if (mysql_stmt_execute(stmt) != 0) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "cannot execute schema version query <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Bind the output of the statement to the appropriate variables.
if (mysql_stmt_bind_result(stmt, bind)) {
isc_throw(DbOperationError, "unable to bind result set for <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Fetch the data.
if (mysql_stmt_fetch(stmt)) {
mysql_stmt_close(stmt);
isc_throw(DbOperationError, "unable to bind result set for <"
- << version_sql << ">, reason: " << mysql_error(conn_.handle()));
+ << version_sql << ">, reason: " << mysql_error(holderHandle));
}
// Discard the statement and its resources
void
MySqlLeaseMgr::commit() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_COMMIT);
- if (mysql_commit(conn_.handle()) != 0) {
- isc_throw(DbOperationError, "commit failed: " << mysql_error(conn_.handle()));
+
+ MySqlHolder& holderHandle = conn_.handle();
+
+ if (mysql_commit(holderHandle) != 0) {
+ isc_throw(DbOperationError, "commit failed: " << mysql_error(holderHandle));
}
}
void
MySqlLeaseMgr::rollback() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_ROLLBACK);
- if (mysql_rollback(conn_.handle()) != 0) {
- isc_throw(DbOperationError, "rollback failed: " << mysql_error(conn_.handle()));
+
+ MySqlHolder& holderHandle = conn_.handle();
+
+ if (mysql_rollback(holderHandle) != 0) {
+ isc_throw(DbOperationError, "rollback failed: " << mysql_error(holderHandle));
}
}
PgSqlHostDataSourceImpl::addStatement(StatementIndex stindex,
PsqlBindArrayPtr& bind_array,
const bool return_last_id) {
+ PgSqlHolder& holderHandle = conn_.handle();
uint64_t last_id = 0;
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array->values_[0],
&bind_array->lengths_[0],
bool
PgSqlHostDataSourceImpl::delStatement(StatementIndex stindex,
PsqlBindArrayPtr& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+ PgSqlHolder& holderHandle = conn_.handle();
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array->values_[0],
&bind_array->lengths_[0],
getHostCollection(StatementIndex stindex, PsqlBindArrayPtr bind_array,
boost::shared_ptr<PgSqlHostExchange> exchange,
ConstHostCollection& result, bool single) const {
+ PgSqlHolder& holderHandle = conn_.handle();
exchange->clear();
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array->values_[0],
&bind_array->lengths_[0],
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_HOST_DB_GET_VERSION);
+ PgSqlHolder& holderHandle = conn_.handle();
const char* version_sql = "SELECT version, minor FROM schema_version;";
- PgSqlResult r(PQexec(conn_.handle(), version_sql));
+
+ PgSqlResult r(PQexec(holderHandle, version_sql));
if(PQresultStatus(r) != PGRES_TUPLES_OK) {
isc_throw(DbOperationError, "unable to execute PostgreSQL statement <"
- << version_sql << ">, reason: " << PQerrorMessage(conn_.handle()));
+ << version_sql << ">, reason: " << PQerrorMessage(holderHandle));
}
uint32_t major;
/// parameters (for all subnets), a subnet id for a single subnet, or
/// a first and last subnet id for a subnet range.
void start() {
+ PgSqlHolder& holderHandle = conn_.handle();
if (getSelectMode() == ALL_SUBNETS) {
// Run the query with no where clause parameters.
- result_set_.reset(new PgSqlResult(PQexecPrepared(conn_.handle(), statement_.name,
+ result_set_.reset(new PgSqlResult(PQexecPrepared(holderHandle, statement_.name,
0, 0, 0, 0, 0)));
} else {
// Set up the WHERE clause values
}
// Run the query with where clause parameters.
- result_set_.reset(new PgSqlResult(PQexecPrepared(conn_.handle(), statement_.name,
+ result_set_.reset(new PgSqlResult(PQexecPrepared(holderHandle, statement_.name,
parms.size(), &parms.values_[0],
&parms.lengths_[0], &parms.formats_[0], 0)));
}
bool
PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+ PgSqlHolder& holderHandle = conn_.handle();
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
Exchange& exchange,
LeaseCollection& result,
bool single) const {
+ PgSqlHolder& holderHandle = conn_.handle();
const int n = tagged_statements[stindex].nbparams;
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name, n,
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name, n,
n > 0 ? &bind_array.values_[0] : NULL,
n > 0 ? &bind_array.lengths_[0] : NULL,
n > 0 ? &bind_array.formats_[0] : NULL, 0));
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(tagged_statements[stindex].name);
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+ PgSqlHolder& holderHandle = conn_.handle();
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
uint64_t
PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_.handle(), tagged_statements[stindex].name,
+ PgSqlHolder& holderHandle = conn_.handle();
+
+ PgSqlResult r(PQexecPrepared(holderHandle, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_GET_VERSION);
+ PgSqlHolder& holderHandle = conn_.handle();
const char* version_sql = "SELECT version, minor FROM schema_version;";
- PgSqlResult r(PQexec(conn_.handle(), version_sql));
+
+ PgSqlResult r(PQexec(holderHandle, version_sql));
if(PQresultStatus(r) != PGRES_TUPLES_OK) {
isc_throw(DbOperationError, "unable to execute PostgreSQL statement <"
- << version_sql << ">, reason: " << PQerrorMessage(conn_.handle()));
+ << version_sql << ">, reason: " << PQerrorMessage(holderHandle));
}
uint32_t major;
MySqlConnection conn(params);
conn.openDatabase();
- int status = mysql_query(conn.handle(), query.c_str());
+ MySqlHolder& holderHandle = conn.handle();
+
+ int status = mysql_query(holderHandle, query.c_str());
if (status !=0) {
- isc_throw(DbOperationError, "Query failed: " << mysql_error(conn.handle()));
+ isc_throw(DbOperationError, "Query failed: " << mysql_error(holderHandle));
}
- MYSQL_RES * res = mysql_store_result(conn.handle());
+ MYSQL_RES * res = mysql_store_result(holderHandle);
int numrows = static_cast<int>(mysql_num_rows(res));
mysql_free_result(res);
MySqlConnection conn(params);
ASSERT_NO_THROW(conn.openDatabase());
- int status = mysql_query(conn.handle(),
- "DROP TABLE IF EXISTS ipv6_reservations");
- ASSERT_EQ(0, status) << mysql_error(conn.handle());
+ MySqlHolder& holderHandle = conn.handle();
+
+ int status = mysql_query(holderHandle, "DROP TABLE IF EXISTS ipv6_reservations");
+ ASSERT_EQ(0, status) << mysql_error(holderHandle);
// Create a host with a reservation.
HostPtr host = HostDataSourceUtils::initializeHost6("2001:db8:1::1", Host::IDENT_HWADDR, false);
PgSqlConnection conn(params);
conn.openDatabase();
- PgSqlResult r(PQexec(conn.handle(), query.c_str()));
+ PgSqlHolder& holderHandle = conn.handle();
+
+ PgSqlResult r(PQexec(holderHandle, query.c_str()));
if (PQresultStatus(r) != PGRES_TUPLES_OK) {
- isc_throw(DbOperationError, "Query failed:" << PQerrorMessage(conn.handle()));
+ isc_throw(DbOperationError, "Query failed:" << PQerrorMessage(holderHandle));
}
int numrows = PQntuples(r);
PgSqlConnection conn(params);
ASSERT_NO_THROW(conn.openDatabase());
- PgSqlResult r(PQexec(conn.handle(), "DROP TABLE IF EXISTS ipv6_reservations"));
- ASSERT_TRUE (PQresultStatus(r) == PGRES_COMMAND_OK)
- << " drop command failed :" << PQerrorMessage(conn.handle());
+ PgSqlHolder& holderHandle = conn.handle();
+
+ PgSqlResult r(PQexec(holderHandle, "DROP TABLE IF EXISTS ipv6_reservations"));
+ ASSERT_TRUE(PQresultStatus(r) == PGRES_COMMAND_OK)
+ << " drop command failed :" << PQerrorMessage(holderHandle);
// Create a host with a reservation.
HostPtr host = HostDataSourceUtils::initializeHost6("2001:db8:1::1",
// connection after a reconnect as among other things, it drops all our
// pre-compiled statements.
my_bool auto_reconnect = MLM_FALSE;
- int result = mysql_options(handle(), MYSQL_OPT_RECONNECT, &auto_reconnect);
+ MySqlHolder& holderHandle = handle();
+
+ int result = mysql_options(holderHandle, MYSQL_OPT_RECONNECT, &auto_reconnect);
if (result != 0) {
isc_throw(DbOpenError, "unable to set auto-reconnect option: " <<
- mysql_error(handle()));
+ mysql_error(holderHandle));
}
// Make sure we have a large idle time window ... say 30 days...
const char *wait_time = "SET SESSION wait_timeout = 30 * 86400";
- result = mysql_options(handle(), MYSQL_INIT_COMMAND, wait_time);
+ result = mysql_options(holderHandle, MYSQL_INIT_COMMAND, wait_time);
if (result != 0) {
isc_throw(DbOpenError, "unable to set wait_timeout " <<
- mysql_error(handle()));
+ mysql_error(holderHandle));
}
// Set SQL mode options for the connection: SQL mode governs how what
// invalid data. We want to ensure we get the strictest behavior and
// to reject invalid data with an error.
const char *sql_mode = "SET SESSION sql_mode ='STRICT_ALL_TABLES'";
- result = mysql_options(handle(), MYSQL_INIT_COMMAND, sql_mode);
+ result = mysql_options(holderHandle, MYSQL_INIT_COMMAND, sql_mode);
if (result != 0) {
isc_throw(DbOpenError, "unable to set SQL mode options: " <<
- mysql_error(handle()));
+ mysql_error(holderHandle));
}
// Connection timeout, the amount of time taken for the client to drop
// the connection if the server is not responding.
- result = mysql_options(handle(), MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
+ result = mysql_options(holderHandle, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
if (result != 0) {
isc_throw(DbOpenError, "unable to set database connection timeout: " <<
- mysql_error(handle()));
+ mysql_error(holderHandle));
}
// Open the database.
// This makes it hard to distinguish whether the UPDATE changed no rows
// because no row matching the WHERE clause was found, or because a
// row was found but no data was altered.
- MYSQL* status = mysql_real_connect(handle(), host, user, password, name,
+ MYSQL* status = mysql_real_connect(holderHandle, host, user, password, name,
port, NULL, CLIENT_FOUND_ROWS);
- if (status != handle()) {
- isc_throw(DbOpenError, mysql_error(handle()));
+ if (status != holderHandle) {
+ isc_throw(DbOpenError, mysql_error(holderHandle));
}
// Enable autocommit. In case transaction is explicitly used, this
// caused issues for some unit tests which were unable to cleanup
// the database after the test because of pending transactions.
// Use of autocommit will eliminate this problem.
- my_bool auto_commit = mysql_autocommit(handle(), 1);
+ my_bool auto_commit = mysql_autocommit(holderHandle, 1);
if (auto_commit != MLM_FALSE) {
- isc_throw(DbOperationError, mysql_error(handle()));
+ isc_throw(DbOperationError, mysql_error(holderHandle));
}
- handle().connected_ = true;
+ holderHandle.connected_ = true;
connected_ = true;
}
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, MYSQL_START_TRANSACTION);
// We create prepared statements for all other queries, but MySQL
// don't support prepared statements for START TRANSACTION.
- int status = mysql_query(handle(), "START TRANSACTION");
+
+ MySqlHolder& holderHandle = handle();
+
+ int status = mysql_query(holderHandle, "START TRANSACTION");
if (status != 0) {
isc_throw(DbOperationError, "unable to start transaction, "
- "reason: " << mysql_error(handle()));
+ "reason: " << mysql_error(holderHandle));
}
}
void
MySqlConnection::commit() {
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, MYSQL_COMMIT);
- if (mysql_commit(handle()) != 0) {
+
+ MySqlHolder& holderHandle = handle();
+
+ if (mysql_commit(holderHandle) != 0) {
isc_throw(DbOperationError, "commit failed: "
- << mysql_error(handle()));
+ << mysql_error(holderHandle));
}
}
void
MySqlConnection::rollback() {
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, MYSQL_ROLLBACK);
- if (mysql_rollback(handle()) != 0) {
+
+ MySqlHolder& holderHandle = handle();
+
+ if (mysql_rollback(holderHandle) != 0) {
isc_throw(DbOperationError, "rollback failed: "
- << mysql_error(handle()));
+ << mysql_error(holderHandle));
}
}
const MySqlBindingCollection& in_bindings,
MySqlBindingCollection& out_bindings,
ConsumeResultFun process_result) {
+ MySqlHolder& holderHandle = handle();
+
// Extract native input bindings.
std::vector<MYSQL_BIND> in_bind_vec;
for (MySqlBindingPtr in_binding : in_bindings) {
int status = 0;
if (!in_bind_vec.empty()) {
// Bind parameters to the prepared statement.
- status = mysql_stmt_bind_param(handle().statements_[index], &in_bind_vec[0]);
+ status = mysql_stmt_bind_param(holderHandle.statements_[index], &in_bind_vec[0]);
checkError(status, index, "unable to bind parameters for select");
}
out_bind_vec.push_back(out_binding->getMySqlBinding());
}
if (!out_bind_vec.empty()) {
- status = mysql_stmt_bind_result(handle().statements_[index], &out_bind_vec[0]);
+ status = mysql_stmt_bind_result(holderHandle.statements_[index], &out_bind_vec[0]);
checkError(status, index, "unable to bind result parameters for select");
}
// Execute query.
- status = mysql_stmt_execute(handle().statements_[index]);
+ status = mysql_stmt_execute(holderHandle.statements_[index]);
checkError(status, index, "unable to execute");
- status = mysql_stmt_store_result(handle().statements_[index]);
+ status = mysql_stmt_store_result(holderHandle.statements_[index]);
checkError(status, index, "unable to set up for storing all results");
// Fetch results.
- MySqlFreeResult fetch_release(handle().statements_[index]);
- while ((status = mysql_stmt_fetch(handle().statements_[index])) ==
+ MySqlFreeResult fetch_release(holderHandle.statements_[index]);
+ while ((status = mysql_stmt_fetch(holderHandle.statements_[index])) ==
MLM_MYSQL_FETCH_SUCCESS) {
try {
// For each returned row call user function which should
template<typename StatementIndex>
void insertQuery(const StatementIndex& index,
const MySqlBindingCollection& in_bindings) {
+ MySqlHolder& holderHandle = handle();
std::vector<MYSQL_BIND> in_bind_vec;
+
for (MySqlBindingPtr in_binding : in_bindings) {
in_bind_vec.push_back(in_binding->getMySqlBinding());
}
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(handle().statements_[index], &in_bind_vec[0]);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[index], &in_bind_vec[0]);
checkError(status, index, "unable to bind parameters");
// Execute the statement
- status = mysql_stmt_execute(handle().statements_[index]);
+ status = mysql_stmt_execute(holderHandle.statements_[index]);
if (status != 0) {
// Failure: check for the special case of duplicate entry.
- if (mysql_errno(handle()) == ER_DUP_ENTRY) {
+ if (mysql_errno(holderHandle) == ER_DUP_ENTRY) {
isc_throw(DuplicateEntry, "Database duplicate entry error");
}
checkError(status, index, "unable to execute");
template<typename StatementIndex>
uint64_t updateDeleteQuery(const StatementIndex& index,
const MySqlBindingCollection& in_bindings) {
+ MySqlHolder& holderHandle = handle();
std::vector<MYSQL_BIND> in_bind_vec;
+
for (MySqlBindingPtr in_binding : in_bindings) {
in_bind_vec.push_back(in_binding->getMySqlBinding());
}
// Bind the parameters to the statement
- int status = mysql_stmt_bind_param(handle().statements_[index], &in_bind_vec[0]);
+ int status = mysql_stmt_bind_param(holderHandle.statements_[index], &in_bind_vec[0]);
checkError(status, index, "unable to bind parameters");
// Execute the statement
- status = mysql_stmt_execute(handle().statements_[index]);
+ status = mysql_stmt_execute(holderHandle.statements_[index]);
if (status != 0) {
// Failure: check for the special case of duplicate entry.
- if ((mysql_errno(handle()) == ER_DUP_ENTRY)
+ if ((mysql_errno(holderHandle) == ER_DUP_ENTRY)
#ifdef ER_FOREIGN_DUPLICATE_KEY
- || (mysql_errno(handle()) == ER_FOREIGN_DUPLICATE_KEY)
+ || (mysql_errno(holderHandle) == ER_FOREIGN_DUPLICATE_KEY)
#endif
#ifdef ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO
- || (mysql_errno(handle()) == ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO)
+ || (mysql_errno(holderHandle) == ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO)
#endif
#ifdef ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO
- || (mysql_errno(handle()) == ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO)
+ || (mysql_errno(holderHandle) == ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO)
#endif
) {
isc_throw(DuplicateEntry, "Database duplicate entry error");
}
// Let's return how many rows were affected.
- return (static_cast<uint64_t>(mysql_stmt_affected_rows(handle().statements_[index])));
+ return (static_cast<uint64_t>(mysql_stmt_affected_rows(holderHandle.statements_[index])));
}
template <typename StatementIndex>
void checkError(const int status, const StatementIndex& index,
const char* what) const {
+ MySqlHolder& holderHandle = handle();
+
if (status != 0) {
- switch(mysql_errno(handle())) {
+ switch(mysql_errno(holderHandle)) {
// These are the ones we consider fatal. Remember this method is
// used to check errors of API calls made subsequent to successfully
// connecting. Errors occurring while attempting to connect are
DB_LOG_ERROR(db::MYSQL_FATAL_ERROR)
.arg(what)
.arg(text_statements_[static_cast<int>(index)])
- .arg(mysql_error(handle()))
- .arg(mysql_errno(handle()));
+ .arg(mysql_error(holderHandle))
+ .arg(mysql_errno(holderHandle));
// If there's no lost db callback or it returns false,
// then we're not attempting to recover so we're done
isc_throw(db::DbOperationError, what << " for <"
<< text_statements_[static_cast<int>(index)]
<< ">, reason: "
- << mysql_error(handle()) << " (error code "
- << mysql_errno(handle()) << ")");
+ << mysql_error(holderHandle) << " (error code "
+ << mysql_errno(holderHandle) << ")");
}
}
}
///
/// @param sql Query in the textual form.
void runQuery(const std::string& sql) {
- MYSQL_STMT *stmt = mysql_stmt_init(conn_.handle());
+ MySqlHolder& holderHandle = conn_.handle();
+
+ MYSQL_STMT *stmt = mysql_stmt_init(holderHandle);
if (stmt == NULL) {
isc_throw(DbOperationError, "unable to allocate MySQL prepared "
- "statement structure, reason: " << mysql_error(conn_.handle()));
+ "statement structure, reason: " << mysql_error(holderHandle));
}
int status = mysql_stmt_prepare(stmt, sql.c_str(), sql.length());
if (status != 0) {
isc_throw(DbOperationError, "unable to prepare MySQL statement <"
- << sql << ">, reason: " << mysql_errno(conn_.handle()));
+ << sql << ">, reason: " << mysql_errno(holderHandle));
}
// Execute the prepared statement.
if (mysql_stmt_execute(stmt) != 0) {
isc_throw(DbOperationError, "cannot execute MySQL query <"
- << sql << ">, reason: " << mysql_errno(conn_.handle()));
+ << sql << ">, reason: " << mysql_errno(holderHandle));
}
// Discard the statement and its resources
}
// We have a valid connection, so let's save it to our holder
- handle().setConnection(new_conn);
- handle().connected_ = true;
+ PgSqlHolder& holderHandle = handle();
+ holderHandle.setConnection(new_conn);
+ holderHandle.connected_ = true;
connected_ = true;
}
// error class. Note, there is a severity field, but it can be
// misleadingly returned as fatal. However, a loss of connectivity
// can lead to a NULL sqlstate with a status of PGRES_FATAL_ERROR.
+
+ PgSqlHolder& holderHandle = handle();
+
const char* sqlstate = PQresultErrorField(r, PG_DIAG_SQLSTATE);
if ((sqlstate == NULL) ||
((memcmp(sqlstate, "08", 2) == 0) || // Connection Exception
(memcmp(sqlstate, "58", 2) == 0))) { // System error
DB_LOG_ERROR(PGSQL_FATAL_ERROR)
.arg(statement.name)
- .arg(PQerrorMessage(handle()))
+ .arg(PQerrorMessage(holderHandle))
.arg(sqlstate ? sqlstate : "<sqlstate null>");
// If there's no lost db callback or it returns false,
}
// Apparently it wasn't fatal, so we throw with a helpful message.
- const char* error_message = PQerrorMessage(handle());
+ const char* error_message = PQerrorMessage(holderHandle);
isc_throw(DbOperationError, "Statement exec failed:" << " for: "
<< statement.name << ", status: " << s
<< "sqlstate:[ " << (sqlstate ? sqlstate : "<null>")
void
PgSqlConnection::startTransaction() {
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, PGSQL_START_TRANSACTION);
- PgSqlResult r(PQexec(handle(), "START TRANSACTION"));
+
+ PgSqlHolder& holderHandle = handle();
+
+ PgSqlResult r(PQexec(holderHandle, "START TRANSACTION"));
if (PQresultStatus(r) != PGRES_COMMAND_OK) {
- const char* error_message = PQerrorMessage(handle());
+ const char* error_message = PQerrorMessage(holderHandle);
isc_throw(DbOperationError, "unable to start transaction"
<< error_message);
}
void
PgSqlConnection::commit() {
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, PGSQL_COMMIT);
- PgSqlResult r(PQexec(handle(), "COMMIT"));
+
+ PgSqlHolder& holderHandle = handle();
+
+ PgSqlResult r(PQexec(holderHandle, "COMMIT"));
if (PQresultStatus(r) != PGRES_COMMAND_OK) {
- const char* error_message = PQerrorMessage(handle());
+ const char* error_message = PQerrorMessage(holderHandle);
isc_throw(DbOperationError, "commit failed: " << error_message);
}
}
void
PgSqlConnection::rollback() {
DB_LOG_DEBUG(DB_DBG_TRACE_DETAIL, PGSQL_ROLLBACK);
- PgSqlResult r(PQexec(handle(), "ROLLBACK"));
+
+ PgSqlHolder& holderHandle = handle();
+
+ PgSqlResult r(PQexec(holderHandle, "ROLLBACK"));
if (PQresultStatus(r) != PGRES_COMMAND_OK) {
- const char* error_message = PQerrorMessage(handle());
+ const char* error_message = PQerrorMessage(holderHandle);
isc_throw(DbOperationError, "rollback failed: " << error_message);
}
}
" varchar_col VARCHAR(255) "
"); ";
- PgSqlResult r(PQexec(conn_->handle(), sql));
+ PgSqlHolder& holderHandle = conn_->handle();
+
+ PgSqlResult r(PQexec(holderHandle, sql));
ASSERT_EQ(PQresultStatus(r), PGRES_COMMAND_OK)
- << " create basics table failed: " << PQerrorMessage(conn_->handle());
+ << " create basics table failed: " << PQerrorMessage(holderHandle);
}
/// @brief Destroys the basics table
/// Asserts if the destruction fails
void destroySchema() {
if (conn_) {
- PgSqlResult r(PQexec(conn_->handle(), "DROP TABLE IF EXISTS basics;"));
+ PgSqlHolder& holderHandle = conn_->handle();
+
+ PgSqlResult r(PQexec(holderHandle, "DROP TABLE IF EXISTS basics;"));
ASSERT_EQ(PQresultStatus(r), PGRES_COMMAND_OK)
- << " drop basics table failed: " << PQerrorMessage(conn_->handle());
+ << " drop basics table failed: " << PQerrorMessage(holderHandle);
}
}
/// Asserts if the result set status does not equal the expected outcome.
void runSql(PgSqlResultPtr& r, const std::string& sql, int exp_outcome,
int lineno) {
- r.reset(new PgSqlResult(PQexec(conn_->handle(), sql.c_str())));
+ PgSqlHolder& holderHandle = conn_->handle();
+
+ r.reset(new PgSqlResult(PQexec(holderHandle, sql.c_str())));
ASSERT_EQ(PQresultStatus(*r), exp_outcome)
<< " runSql at line: " << lineno << " failed, sql:[" << sql
- << "]\n reason: " << PQerrorMessage(conn_->handle());
+ << "]\n reason: " << PQerrorMessage(holderHandle);
}
/// @brief Executes a SQL statement and tests for an expected outcome
PgSqlTaggedStatement& statement,
PsqlBindArrayPtr bind_array, int exp_outcome,
int lineno) {
- r.reset(new PgSqlResult(PQexecPrepared(conn_->handle(), statement.name,
+ PgSqlHolder& holderHandle = conn_->handle();
+
+ r.reset(new PgSqlResult(PQexecPrepared(holderHandle, statement.name,
statement.nbparams,
&bind_array->values_[0],
&bind_array->lengths_[0],
ASSERT_EQ(PQresultStatus(*r), exp_outcome)
<< " runPreparedStatement at line: " << lineno
<< " statement name:[" << statement.name
- << "]\n reason: " << PQerrorMessage(conn_->handle());
+ << "]\n reason: " << PQerrorMessage(holderHandle);
}
/// @brief Fetches all of the rows currently in the table