mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[4294] Refactored MySql stats classes
src/lib/dhcpsrv/mysql_lease_mgr.h src/lib/dhcpsrv/mysql_lease_mgr.cc Replaced this class heirarchy: AddressStatsQuery4 <-- MySqlAddressStatsQuery4 AddressStatsQuery6 <-- MySqlAddressStatsQuery6 With this one: LeaseStatsQuery <-- MySqlLeaseStatsQuery
This commit is contained in:
@@ -1223,26 +1223,34 @@ private:
|
|||||||
uint32_t state_; ///< Lease state.
|
uint32_t state_; ///< Lease state.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief MySql derivation of the IPv4 statistical lease data query
|
/// @brief MySql derivation of the statistical lease data query
|
||||||
///
|
///
|
||||||
/// This class is used to recalculate IPv4 lease statistics for MySQL
|
/// This class is used to recalculate lease statistics for MySQL
|
||||||
/// lease storage. It does so by executing a query which returns a result
|
/// lease storage. It does so by executing a query which returns a result
|
||||||
/// containining contain one row per monitored state per subnet, ordered
|
/// containining contain one row per monitored state per lease type per
|
||||||
/// by subnet id in ascending order.
|
/// subnet, ordered by subnet id in ascending order.
|
||||||
///
|
///
|
||||||
class MySqlAddressStatsQuery4 : public AddressStatsQuery4 {
|
class MySqlLeaseStatsQuery : public LeaseStatsQuery {
|
||||||
public:
|
public:
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
///
|
///
|
||||||
/// @param conn A open connection to the database housing the lease data
|
/// @param conn A open connection to the database housing the lease data
|
||||||
MySqlAddressStatsQuery4(MySqlConnection& conn)
|
/// @brief statement_index Index of the query's prepared statement
|
||||||
: conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
|
/// @brief fetch_type Indicates if query supplies lease type
|
||||||
::RECOUNT_LEASE4_STATS]),
|
MySqlLeaseStatsQuery(MySqlConnection& conn, const size_t statement_index,
|
||||||
bind_(3) {
|
const bool fetch_type)
|
||||||
|
: conn_(conn), statement_index_(statement_index), statement_(NULL),
|
||||||
|
fetch_type_(fetch_type), bind_(fetch_type_ ? 4 : 3) {
|
||||||
|
if (statement_index_ >= MySqlLeaseMgr::NUM_STATEMENTS) {
|
||||||
|
isc_throw(BadValue, "MySqlLeaseStatsQuery"
|
||||||
|
" - invalid statement index" << statement_index_);
|
||||||
|
}
|
||||||
|
|
||||||
|
statement_ = conn.statements_[statement_index_];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Destructor
|
/// @brief Destructor
|
||||||
virtual ~MySqlAddressStatsQuery4() {
|
virtual ~MySqlLeaseStatsQuery() {
|
||||||
(void) mysql_stmt_free_result(statement_);
|
(void) mysql_stmt_free_result(statement_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,161 +1263,48 @@ public:
|
|||||||
/// the statement to the output bind array and then executes the
|
/// the statement to the output bind array and then executes the
|
||||||
/// statement.
|
/// statement.
|
||||||
void start() {
|
void start() {
|
||||||
|
int col = 0;
|
||||||
// subnet_id: unsigned int
|
// subnet_id: unsigned int
|
||||||
bind_[0].buffer_type = MYSQL_TYPE_LONG;
|
bind_[col].buffer_type = MYSQL_TYPE_LONG;
|
||||||
bind_[0].buffer = reinterpret_cast<char*>(&subnet_id_);
|
bind_[col].buffer = reinterpret_cast<char*>(&subnet_id_);
|
||||||
bind_[0].is_unsigned = MLM_TRUE;
|
bind_[col].is_unsigned = MLM_TRUE;
|
||||||
|
++col;
|
||||||
|
|
||||||
// state: uint32_t
|
// Fetch the lease type if we were told to do so.
|
||||||
bind_[1].buffer_type = MYSQL_TYPE_LONG;
|
if (fetch_type_) {
|
||||||
bind_[1].buffer = reinterpret_cast<char*>(&lease_state_);
|
// lease type: uint32_t
|
||||||
bind_[1].is_unsigned = MLM_TRUE;
|
bind_[col].buffer_type = MYSQL_TYPE_LONG;
|
||||||
|
bind_[col].buffer = reinterpret_cast<char*>(&lease_type_);
|
||||||
// state_count_: uint32_t
|
bind_[col].is_unsigned = MLM_TRUE;
|
||||||
bind_[2].buffer_type = MYSQL_TYPE_LONG;
|
++col;
|
||||||
bind_[2].buffer = reinterpret_cast<char*>(&state_count_);
|
} else {
|
||||||
bind_[2].is_unsigned = MLM_TRUE;
|
fetch_type_ = Lease::TYPE_NA;
|
||||||
|
|
||||||
// Set up the MYSQL_BIND array for the data being returned
|
|
||||||
// and bind it to the statement.
|
|
||||||
int status = mysql_stmt_bind_result(statement_, &bind_[0]);
|
|
||||||
checkError(status, "RECOUNT_LEASE4_STATS: outbound binding failed");
|
|
||||||
|
|
||||||
// Execute the statement
|
|
||||||
status = mysql_stmt_execute(statement_);
|
|
||||||
checkError(status, "RECOUNT_LEASE4_STATS: 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(statement_);
|
|
||||||
checkError(status, "RECOUNT_LEASE4_STATS: results storage failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Fetches the next row in the result set
|
|
||||||
///
|
|
||||||
/// Once the internal result set has been populated by invoking the
|
|
||||||
/// the start() method, this method is used to iterate over the
|
|
||||||
/// result set rows. Once the last row has been fetched, subsequent
|
|
||||||
/// calls will return false.
|
|
||||||
///
|
|
||||||
/// @param row Storage for the fetched row
|
|
||||||
///
|
|
||||||
/// @return True if the fetch succeeded, false if there are no more
|
|
||||||
/// rows to fetch.
|
|
||||||
bool getNextRow(AddressStatsRow4& row) {
|
|
||||||
bool have_row = false;
|
|
||||||
int status = mysql_stmt_fetch(statement_);
|
|
||||||
if (status == MLM_MYSQL_FETCH_SUCCESS) {
|
|
||||||
row.subnet_id_ = static_cast<SubnetID>(subnet_id_);
|
|
||||||
row.lease_state_ = lease_state_;
|
|
||||||
row.state_count_ = state_count_;
|
|
||||||
have_row = true;
|
|
||||||
} else if (status != MYSQL_NO_DATA) {
|
|
||||||
checkError(status, "RECOUNT_LEASE4_STATS: getNextRow failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (have_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// @brief Analyzes the given statement outcome status
|
|
||||||
///
|
|
||||||
/// Wrapper method around the MySqlConnection:checkError() that is
|
|
||||||
/// used to generate the appropriate exception if the status indicates
|
|
||||||
/// an error.
|
|
||||||
////
|
|
||||||
/// a DbOperation error
|
|
||||||
/// @param status The MySQL statement execution outcome status
|
|
||||||
/// @param what invocation context message which will be included in
|
|
||||||
/// any exception
|
|
||||||
void checkError(int status, const char* what) const {
|
|
||||||
conn_.checkError(status, MySqlLeaseMgr::RECOUNT_LEASE4_STATS, what);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Database connection to use to execute the query
|
|
||||||
MySqlConnection& conn_;
|
|
||||||
|
|
||||||
/// @brief The query's prepared statement
|
|
||||||
MYSQL_STMT *statement_;
|
|
||||||
|
|
||||||
/// @brief Bind array used to store the query result set;
|
|
||||||
std::vector<MYSQL_BIND> bind_;
|
|
||||||
|
|
||||||
/// @brief Receives subnet ID when fetching a row
|
|
||||||
uint32_t subnet_id_;
|
|
||||||
/// @brief Receives the lease state when fetching a row
|
|
||||||
uint32_t lease_state_;
|
|
||||||
/// @brief Receives the state count when fetching a row
|
|
||||||
uint32_t state_count_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief MySql derivation of the IPv6 statistical lease data query
|
|
||||||
///
|
|
||||||
/// This class is used to recalculate IPv6 lease statistics for MySQL
|
|
||||||
/// lease storage. It does so by executing a query which returns a result
|
|
||||||
/// containining contain one row per monitored state per subnet, ordered
|
|
||||||
/// by subnet id in ascending order.
|
|
||||||
///
|
|
||||||
class MySqlAddressStatsQuery6 : public AddressStatsQuery6 {
|
|
||||||
public:
|
|
||||||
/// @brief Constructor
|
|
||||||
///
|
|
||||||
/// @param conn A open connection to the database housing the lease data
|
|
||||||
MySqlAddressStatsQuery6(MySqlConnection& conn)
|
|
||||||
: conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
|
|
||||||
::RECOUNT_LEASE6_STATS]),
|
|
||||||
bind_(4) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Destructor
|
|
||||||
virtual ~MySqlAddressStatsQuery6() {
|
|
||||||
(void) mysql_stmt_free_result(statement_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Creates the IPv6 lease statistical data result set
|
|
||||||
///
|
|
||||||
/// The result set is populated by executing an SQL query against the
|
|
||||||
/// lease6 table which sums the leases per lease state per lease type
|
|
||||||
/// per subnet id. The query used is the prepared statement identified by
|
|
||||||
/// MySqlLeaseMgr::RECOUNT_LEASE6_STATS. This method creates the binds
|
|
||||||
/// the statement to the output bind array and then executes the
|
|
||||||
/// statement.
|
|
||||||
void start() {
|
|
||||||
// subnet_id: unsigned int
|
|
||||||
bind_[0].buffer_type = MYSQL_TYPE_LONG;
|
|
||||||
bind_[0].buffer = reinterpret_cast<char*>(&subnet_id_);
|
|
||||||
bind_[0].is_unsigned = MLM_TRUE;
|
|
||||||
|
|
||||||
// lease type: uint32_t
|
|
||||||
bind_[1].buffer_type = MYSQL_TYPE_LONG;
|
|
||||||
bind_[1].buffer = reinterpret_cast<char*>(&lease_type_);
|
|
||||||
bind_[1].is_unsigned = MLM_TRUE;
|
|
||||||
|
|
||||||
// state: uint32_t
|
// state: uint32_t
|
||||||
bind_[2].buffer_type = MYSQL_TYPE_LONG;
|
bind_[col].buffer_type = MYSQL_TYPE_LONG;
|
||||||
bind_[2].buffer = reinterpret_cast<char*>(&lease_state_);
|
bind_[col].buffer = reinterpret_cast<char*>(&lease_state_);
|
||||||
bind_[2].is_unsigned = MLM_TRUE;
|
bind_[col].is_unsigned = MLM_TRUE;
|
||||||
|
++col;
|
||||||
|
|
||||||
// state_count_: uint32_t
|
// state_count_: uint32_t
|
||||||
bind_[3].buffer_type = MYSQL_TYPE_LONG;
|
bind_[col].buffer_type = MYSQL_TYPE_LONG;
|
||||||
bind_[3].buffer = reinterpret_cast<char*>(&state_count_);
|
bind_[col].buffer = reinterpret_cast<char*>(&state_count_);
|
||||||
bind_[3].is_unsigned = MLM_TRUE;
|
bind_[col].is_unsigned = MLM_TRUE;
|
||||||
|
|
||||||
// Set up the MYSQL_BIND array for the data being returned
|
// Set up the MYSQL_BIND array for the data being returned
|
||||||
// and bind it to the statement.
|
// and bind it to the statement.
|
||||||
int status = mysql_stmt_bind_result(statement_, &bind_[0]);
|
int status = mysql_stmt_bind_result(statement_, &bind_[0]);
|
||||||
checkError(status, "RECOUNT_LEASE6_STATS: outbound binding failed");
|
conn_.checkError(status, statement_index_, "outbound binding failed");
|
||||||
|
|
||||||
// Execute the statement
|
// Execute the statement
|
||||||
status = mysql_stmt_execute(statement_);
|
status = mysql_stmt_execute(statement_);
|
||||||
checkError(status, "RECOUNT_LEASE6_STATS: unable to execute");
|
conn_.checkError(status, statement_index_, "unable to execute");
|
||||||
|
|
||||||
// Ensure that all the lease information is retrieved in one go to avoid
|
// Ensure that all the lease information is retrieved in one go to avoid
|
||||||
// overhead of going back and forth between client and server.
|
// overhead of going back and forth between client and server.
|
||||||
status = mysql_stmt_store_result(statement_);
|
status = mysql_stmt_store_result(statement_);
|
||||||
checkError(status, "RECOUNT_LEASE6_STATS: results storage failed");
|
conn_.checkError(status, statement_index_, "results storage failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1424,7 +1319,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// @return True if the fetch succeeded, false if there are no more
|
/// @return True if the fetch succeeded, false if there are no more
|
||||||
/// rows to fetch.
|
/// rows to fetch.
|
||||||
bool getNextRow(AddressStatsRow6& row) {
|
bool getNextRow(LeaseStatsRow& row) {
|
||||||
bool have_row = false;
|
bool have_row = false;
|
||||||
int status = mysql_stmt_fetch(statement_);
|
int status = mysql_stmt_fetch(statement_);
|
||||||
if (status == MLM_MYSQL_FETCH_SUCCESS) {
|
if (status == MLM_MYSQL_FETCH_SUCCESS) {
|
||||||
@@ -1434,35 +1329,25 @@ public:
|
|||||||
row.state_count_ = state_count_;
|
row.state_count_ = state_count_;
|
||||||
have_row = true;
|
have_row = true;
|
||||||
} else if (status != MYSQL_NO_DATA) {
|
} else if (status != MYSQL_NO_DATA) {
|
||||||
checkError(status, "RECOUNT_LEASE6_STATS: getNextRow failed");
|
conn_.checkError(status, statement_index_, "getNextRow failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (have_row);
|
return (have_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief Analyzes the given statement outcome status
|
|
||||||
///
|
|
||||||
/// Wrapper method around the MySqlConnection:checkError() that is
|
|
||||||
/// used to generate the appropriate exception if the status indicates
|
|
||||||
/// an error.
|
|
||||||
////
|
|
||||||
/// a DbOperation error
|
|
||||||
/// @param status The MySQL statement execution outcome status
|
|
||||||
/// @param what invocation context message which will be included in
|
|
||||||
/// any exception
|
|
||||||
void checkError(int status, const char* what) const {
|
|
||||||
conn_.checkError(status, MySqlLeaseMgr::RECOUNT_LEASE6_STATS, what);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Database connection to use to execute the query
|
/// @brief Database connection to use to execute the query
|
||||||
MySqlConnection& conn_;
|
MySqlConnection& conn_;
|
||||||
|
|
||||||
|
/// @brief Index of the query's prepared statement
|
||||||
|
size_t statement_index_;
|
||||||
|
|
||||||
/// @brief The query's prepared statement
|
/// @brief The query's prepared statement
|
||||||
MYSQL_STMT *statement_;
|
MYSQL_STMT *statement_;
|
||||||
|
|
||||||
|
/// @brief Indicates if query supplies lease type
|
||||||
|
bool fetch_type_;
|
||||||
|
|
||||||
/// @brief Bind array used to store the query result set;
|
/// @brief Bind array used to store the query result set;
|
||||||
std::vector<MYSQL_BIND> bind_;
|
std::vector<MYSQL_BIND> bind_;
|
||||||
|
|
||||||
@@ -2284,16 +2169,20 @@ MySqlLeaseMgr::getVersion() const {
|
|||||||
return (std::make_pair(major, minor));
|
return (std::make_pair(major, minor));
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressStatsQuery4Ptr
|
LeaseStatsQueryPtr
|
||||||
MySqlLeaseMgr::startAddressStatsQuery4() {
|
MySqlLeaseMgr::startLeaseStatsQuery4() {
|
||||||
AddressStatsQuery4Ptr query(new MySqlAddressStatsQuery4(conn_));
|
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
|
||||||
|
RECOUNT_LEASE4_STATS,
|
||||||
|
false));
|
||||||
query->start();
|
query->start();
|
||||||
return(query);
|
return(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressStatsQuery6Ptr
|
LeaseStatsQueryPtr
|
||||||
MySqlLeaseMgr::startAddressStatsQuery6() {
|
MySqlLeaseMgr::startLeaseStatsQuery6() {
|
||||||
AddressStatsQuery6Ptr query(new MySqlAddressStatsQuery6(conn_));
|
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
|
||||||
|
RECOUNT_LEASE6_STATS,
|
||||||
|
true));
|
||||||
query->start();
|
query->start();
|
||||||
return(query);
|
return(query);
|
||||||
}
|
}
|
||||||
|
@@ -593,23 +593,23 @@ private:
|
|||||||
|
|
||||||
/// @brief Creates and runs the IPv4 lease stats query
|
/// @brief Creates and runs the IPv4 lease stats query
|
||||||
///
|
///
|
||||||
/// It creates an instance of a MySqlAddressStatsQuery4 and then
|
/// It creates an instance of a MySqlLeaseStatsQuery4 and then
|
||||||
/// invokes its start method, which fetches its statistical data
|
/// invokes its start method, which fetches its statistical data
|
||||||
/// result set by executing the RECOUNT_LEASE_STATS4 query.
|
/// result set by executing the RECOUNT_LEASE_STATS4 query.
|
||||||
/// The query object is then returned.
|
/// The query object is then returned.
|
||||||
///
|
///
|
||||||
/// @return The populated query as a pointer to an AddressStatsQuery4
|
/// @return The populated query as a pointer to an LeaseStatsQuery
|
||||||
virtual AddressStatsQuery4Ptr startAddressStatsQuery4();
|
virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
|
||||||
|
|
||||||
/// @brief Creates and runs the IPv6 lease stats query
|
/// @brief Creates and runs the IPv6 lease stats query
|
||||||
///
|
///
|
||||||
/// It creates an instance of a MySqlAddressStatsQuery6 and then
|
/// It creates an instance of a MySqlLeaseStatsQuery6 and then
|
||||||
/// invokes its start method, which fetches its statistical data
|
/// invokes its start method, which fetches its statistical data
|
||||||
/// result set by executing the RECOUNT_LEASE_STATS4 query.
|
/// result set by executing the RECOUNT_LEASE_STATS6 query.
|
||||||
/// The query object is then returned.
|
/// The query object is then returned.
|
||||||
///
|
///
|
||||||
/// @return The populated query as a pointer to an AddressStatsQuery6
|
/// @return The populated query as a pointer to an LeaseStatsQuery
|
||||||
virtual AddressStatsQuery6Ptr startAddressStatsQuery6();
|
virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
|
||||||
|
|
||||||
/// @brief Check Error and Throw Exception
|
/// @brief Check Error and Throw Exception
|
||||||
///
|
///
|
||||||
|
@@ -760,6 +760,8 @@ public:
|
|||||||
lease_type);
|
lease_type);
|
||||||
row.lease_type_ = static_cast<Lease::Type>(lease_type);
|
row.lease_type_ = static_cast<Lease::Type>(lease_type);
|
||||||
++col;
|
++col;
|
||||||
|
} else {
|
||||||
|
row.lease_type_ = Lease::TYPE_NA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the lease state.
|
// Fetch the lease state.
|
||||||
|
@@ -478,13 +478,13 @@ TEST_F(MySqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that IPv4 lease statistics can be recalculated.
|
// Verifies that IPv4 lease statistics can be recalculated.
|
||||||
TEST_F(MySqlLeaseMgrTest, recountAddressStats4) {
|
TEST_F(MySqlLeaseMgrTest, recountLeaseStats4) {
|
||||||
testRecountAddressStats4();
|
testRecountLeaseStats4();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that IPv6 lease statistics can be recalculated.
|
// Verifies that IPv6 lease statistics can be recalculated.
|
||||||
TEST_F(MySqlLeaseMgrTest, recountAddressStats6) {
|
TEST_F(MySqlLeaseMgrTest, recountLeaseStats6) {
|
||||||
testRecountAddressStats6();
|
testRecountLeaseStats6();
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // Of anonymous namespace
|
}; // Of anonymous namespace
|
||||||
|
Reference in New Issue
Block a user