/// @brief Constructor
///
/// @param storage4 A pointer to the v4 lease storage to be counted
- MemfileAddressStatsQuery4(Lease4Storage& storage4);
+ MemfileAddressStatsQuery4(Lease4Storage& storage4)
+ : storage4_(storage4), rows_(0), next_pos_(rows_.end()) {
+ };
/// @brief Destructor
virtual ~MemfileAddressStatsQuery4() {};
///
/// The result is populated by iterating over the IPv4 leases in storage,
/// in ascending order by subnet ID, accumulating the lease state counts.
- /// At the completion of all entries for a given subnet, the counts are
- /// used to create AddressStatsRow4 instances which are appended to an
+ /// At the completion of all entries for a given subnet, the counts are
+ /// used to create AddressStatsRow4 instances which are appended to an
/// internal vector. The process results in a vector containing one entry
/// per state per subnet.
///
/// Currently the states counted are:
///
- /// - Lease::STATE_DEFAULT (i.e. assigned)
- /// - Lease::STATE_DECLINED
- virtual void start();
+ /// - Lease::STATE_DEFAULT (i.e. assigned)
+ /// - Lease::STATE_DECLINED
+ void start() {
+ // Get the subnet_id index
+ const Lease4StorageSubnetIdIndex& idx
+ = storage4_.get<SubnetIdIndexTag>();
+
+ // Iterate over the leases in order by subnet, accumulating per
+ // subnet counts for each state of interest. As we finish each
+ // subnet, add the appropriate rows to our result set.
+ SubnetID cur_id = 0;
+ int64_t assigned = 0;
+ int64_t declined = 0;
+ for(Lease4StorageSubnetIdIndex::const_iterator lease = idx.begin();
+ lease != idx.end(); ++lease) {
+
+ // If we've hit the next subnet, add rows for the current subnet
+ // and wipe the accumulators
+ if ((*lease)->subnet_id_ > cur_id) {
+ if (cur_id > 0) {
+ rows_.push_back(AddressStatsRow4(cur_id,
+ Lease::STATE_DEFAULT,
+ assigned));
+ assigned = 0;
+ rows_.push_back(AddressStatsRow4(cur_id,
+ Lease::STATE_DECLINED,
+ declined));
+ declined = 0;
+ }
+
+ // Update current subnet id
+ cur_id = (*lease)->subnet_id_;
+ }
+
+ // Bump the appropriate accumulator
+ switch ((*lease)->state_) {
+ case Lease::STATE_DEFAULT:
+ ++assigned;
+ break;
+ case Lease::STATE_DECLINED:
+ ++declined;
+ break;
+ default:
+ // Not one we're tracking.
+ break;
+ }
+ }
+
+ // Make the rows for last subnet, unless there were no rows
+ if (idx.begin() != idx.end()) {
+ rows_.push_back(AddressStatsRow4(cur_id, Lease::STATE_DEFAULT,
+ assigned));
+ rows_.push_back(AddressStatsRow4(cur_id, Lease::STATE_DECLINED,
+ declined));
+ }
+
+ // Set the next row position to the beginning of the rows.
+ next_pos_ = rows_.begin();
+ }
/// @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.
+ /// 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.
- virtual bool getNextRow(AddressStatsRow4& row);
+ virtual bool getNextRow(AddressStatsRow4& row) {
+ if (next_pos_ == rows_.end()) {
+ return (false);
+ }
+
+ row = *next_pos_;
+ ++next_pos_;
+ return (true);
+ }
/// @brief Returns the number of rows in the result set
- /// @todo, should this be a virtual member of the base class?
- int getRowCount();
+ int getRowCount() const {
+ return (rows_.size());
+ }
private:
/// @brief The Memfile storage containing the IPv4 leases to analyze
Lease4Storage& storage4_;
- /// @brief A vector containing the "result set"
+ /// @brief A vector containing the "result set"
std::vector<AddressStatsRow4> rows_;
/// @brief An iterator for accessing the next row within the result set
std::vector<AddressStatsRow4>::iterator next_pos_;
};
-MemfileAddressStatsQuery4::MemfileAddressStatsQuery4(Lease4Storage& storage4)
- : storage4_(storage4), rows_(0), next_pos_(rows_.end()) {};
-
-void
-MemfileAddressStatsQuery4::start() {
- // Get the subnet_id index
- const Lease4StorageSubnetIdIndex& idx = storage4_.get<SubnetIdIndexTag>();
-
- // Iterate over the leases in order by subnet, accumulating per
- // subnet counts for each state of interest. As we finish each
- // subnet, add the appropriate rows to our result set.
- SubnetID cur_id = 0;
- int64_t assigned = 0;
- int64_t declined = 0;
- for(Lease4StorageSubnetIdIndex::const_iterator lease = idx.begin();
- lease != idx.end(); ++lease) {
-
- // If we've hit the next subnet, add rows for the current subnet
- // and wipe the accumulators
- if ((*lease)->subnet_id_ > cur_id) {
- if (cur_id > 0) {
- rows_.push_back(AddressStatsRow4(cur_id,Lease::STATE_DEFAULT,
- assigned));
- assigned = 0;
- rows_.push_back(AddressStatsRow4(cur_id, Lease::STATE_DECLINED,
- declined));
- declined = 0;
- }
-
- // Update current subnet id
- cur_id = (*lease)->subnet_id_;
- }
-
- // Bump the appropriate accumulator
- switch ((*lease)->state_) {
- case Lease::STATE_DEFAULT:
- ++assigned;
- break;
- case Lease::STATE_DECLINED:
- ++declined;
- break;
- default:
- // Not one we're tracking.
- break;
- }
- }
-
- // Make the rows for last subnet, unless there were no rows
- if (idx.begin() != idx.end()) {
- rows_.push_back(AddressStatsRow4(cur_id, Lease::STATE_DEFAULT,
- assigned));
- rows_.push_back(AddressStatsRow4(cur_id, Lease::STATE_DECLINED,
- declined));
- }
-
- // Set the next row position to the beginning of the rows.
- next_pos_ = rows_.begin();
-}
-
-bool
-MemfileAddressStatsQuery4::getNextRow(AddressStatsRow4& row) {
- if (next_pos_ == rows_.end()) {
- return (false);
- }
-
- row = *next_pos_;
- ++next_pos_;
- return (true);
-}
-
-int
-MemfileAddressStatsQuery4::getRowCount() {
- return (rows_.size());
-}
/// @brief Memfile derivation of the IPv6 statistical lease data query
///
/// @brief Constructor
///
/// @param storage6 A pointer to the v6 lease storage to be counted
- MemfileAddressStatsQuery6(Lease6Storage& storage6);
+ MemfileAddressStatsQuery6(Lease6Storage& storage6)
+ : storage6_(storage6), rows_(0), next_pos_(rows_.end()) {
+ };
/// @brief Destructor
virtual ~MemfileAddressStatsQuery6() {};
///
/// The result is populated by iterating over the IPv6 leases in storage,
/// in ascending order by subnet ID, accumulating the lease state counts
- /// per lease type. At the completion of all entries for a given subnet,
- /// the counts are used to create AddressStatsRow5 instances which are
- /// appended to an internal vector. The process results in a vector
+ /// per lease type. At the completion of all entries for a given subnet,
+ /// the counts are used to create AddressStatsRow5 instances which are
+ /// appended to an internal vector. The process results in a vector
/// containing one entry per state per lease type per subnet.
///
/// Currently the states counted are:
///
- /// - Lease::STATE_DEFAULT (i.e. assigned)
- /// - Lease::STATE_DECLINED
- virtual void start();
+ /// - Lease::STATE_DEFAULT (i.e. assigned)
+ /// - Lease::STATE_DECLINED
+ virtual void start() {
+ // Get the subnet_id index
+ const Lease6StorageSubnetIdIndex& idx
+ = storage6_.get<SubnetIdIndexTag>();
+
+ // Iterate over the leases in order by subnet, accumulating per
+ // subnet counts for each state of interest. As we finish each
+ // subnet, add the appropriate rows to our result set.
+ SubnetID cur_id = 0;
+ int64_t assigned = 0;
+ int64_t declined = 0;
+ int64_t assigned_pds = 0;
+
+ for(Lease6StorageSubnetIdIndex::const_iterator lease = idx.begin();
+ lease != idx.end(); ++lease) {
+
+ // If we've hit the next subnet, add rows for the current subnet
+ // and wipe the accumulators
+ if ((*lease)->subnet_id_ > cur_id) {
+ if (cur_id > 0) {
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
+ Lease::STATE_DEFAULT,
+ assigned));
+ assigned = 0;
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
+ Lease::STATE_DECLINED,
+ declined));
+ declined = 0;
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_PD,
+ Lease::STATE_DEFAULT,
+ assigned_pds));
+ assigned_pds = 0;
+ }
+
+ // Update current subnet id
+ cur_id = (*lease)->subnet_id_;
+ }
+
+ // Bump the appropriate accumulator
+ switch ((*lease)->state_) {
+ case Lease::STATE_DEFAULT:
+ switch((*lease)->type_) {
+ case Lease::TYPE_NA:
+ ++assigned;
+ break;
+ case Lease::TYPE_PD:
+ ++assigned_pds;
+ break;
+ default:
+ break;
+ }
+ break;
+ case Lease::STATE_DECLINED:
+ // In theory only NAs can be declined
+ if (((*lease)->type_) == Lease::TYPE_NA) {
+ ++declined;
+ }
+ break;
+ default:
+ // Not one we're tracking.
+ break;
+ }
+ }
+
+ // Make the rows for last subnet, unless there were no rows
+ if (idx.begin() != idx.end()) {
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
+ Lease::STATE_DEFAULT,
+ assigned));
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
+ Lease::STATE_DECLINED,
+ declined));
+ rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_PD,
+ Lease::STATE_DEFAULT,
+ assigned_pds));
+ }
+
+ // Set the next row position to the beginning of the rows.
+ next_pos_ = rows_.begin();
+ }
/// @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.
+ /// 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.
- virtual bool getNextRow(AddressStatsRow6& row);
+ virtual bool getNextRow(AddressStatsRow6& row) {
+ if (next_pos_ == rows_.end()) {
+ return (false);
+ }
+
+ row = *next_pos_;
+ ++next_pos_;
+ return (true);
+ }
/// @brief Returns the number of rows in the result set
- /// @todo, should this be a virtual member of the base class?
- int getRowCount();
+ int getRowCount() {
+ return (rows_.size());
+ }
private:
/// @brief The Memfile storage containing the IPv6 leases to analyze
Lease6Storage& storage6_;
- /// @brief A vector containing the "result set"
+ /// @brief A vector containing the "result set"
std::vector<AddressStatsRow6> rows_;
/// @brief An iterator for accessing the next row within the result set
std::vector<AddressStatsRow6>::iterator next_pos_;
};
-MemfileAddressStatsQuery6::MemfileAddressStatsQuery6(Lease6Storage& storage6)
- : storage6_(storage6), rows_(0), next_pos_(rows_.end()) {};
-
-void
-MemfileAddressStatsQuery6::start() {
- // Get the subnet_id index
- const Lease6StorageSubnetIdIndex& idx = storage6_.get<SubnetIdIndexTag>();
-
- // Iterate over the leases in order by subnet, accumulating per
- // subnet counts for each state of interest. As we finish each
- // subnet, add the appropriate rows to our result set.
- SubnetID cur_id = 0;
- int64_t assigned = 0;
- int64_t declined = 0;
- int64_t assigned_pds = 0;
-
- for(Lease6StorageSubnetIdIndex::const_iterator lease = idx.begin();
- lease != idx.end(); ++lease) {
-
- // If we've hit the next subnet, add rows for the current subnet
- // and wipe the accumulators
- if ((*lease)->subnet_id_ > cur_id) {
- if (cur_id > 0) {
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
- Lease::STATE_DEFAULT,
- assigned));
- assigned = 0;
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
- Lease::STATE_DECLINED,
- declined));
- declined = 0;
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_PD,
- Lease::STATE_DEFAULT,
- assigned_pds));
- assigned_pds = 0;
- }
-
- // Update current subnet id
- cur_id = (*lease)->subnet_id_;
- }
-
- // Bump the appropriate accumulator
- switch ((*lease)->state_) {
- case Lease::STATE_DEFAULT:
- switch((*lease)->type_) {
- case Lease::TYPE_NA:
- ++assigned;
- break;
- case Lease::TYPE_PD:
- ++assigned_pds;
- break;
- default:
- break;
- }
- break;
- case Lease::STATE_DECLINED:
- // In theory only NAs can be declined
- if (((*lease)->type_) == Lease::TYPE_NA) {
- ++declined;
- }
- break;
- default:
- // Not one we're tracking.
- break;
- }
- }
-
- // Make the rows for last subnet, unless there were no rows
- if (idx.begin() != idx.end()) {
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
- Lease::STATE_DEFAULT,
- assigned));
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_NA,
- Lease::STATE_DECLINED,
- declined));
- rows_.push_back(AddressStatsRow6(cur_id, Lease::TYPE_PD,
- Lease::STATE_DEFAULT,
- assigned_pds));
- }
-
- // Set the next row position to the beginning of the rows.
- next_pos_ = rows_.begin();
-}
-
-bool
-MemfileAddressStatsQuery6::getNextRow(AddressStatsRow6& row) {
- if (next_pos_ == rows_.end()) {
- return (false);
- }
-
- row = *next_pos_;
- ++next_pos_;
- return (true);
-}
-
-int
-MemfileAddressStatsQuery6::getRowCount() {
- return (rows_.size());
-}
-
-
// Explicit definition of class static constants. Values are given in the
// declaration so they're not needed here.
const int Memfile_LeaseMgr::MAJOR_VERSION;
/// @brief Constructor
///
/// @param conn A open connection to the database housing the lease data
- MySqlAddressStatsQuery4(MySqlConnection& conn);
+ MySqlAddressStatsQuery4(MySqlConnection& conn)
+ : conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
+ ::RECOUNT_LEASE4_STATS]),
+ bind_(3) {
+ }
/// @brief Destructor
- virtual ~MySqlAddressStatsQuery4();
+ virtual ~MySqlAddressStatsQuery4() {
+ (void) mysql_stmt_free_result(statement_);
+ }
/// @brief Creates the IPv4 lease statistical data result set
///
/// MySqlLeaseMgr::RECOUNT_LEASE4_STATS. This method creates the binds
/// the statement to the output bind array and then executes the
/// statement.
- void start();
+ 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;
+
+ // state: uint32_t
+ bind_[1].buffer_type = MYSQL_TYPE_LONG;
+ bind_[1].buffer = reinterpret_cast<char*>(&lease_state_);
+ bind_[1].is_unsigned = MLM_TRUE;
+
+ // state_count_: uint32_t
+ bind_[2].buffer_type = MYSQL_TYPE_LONG;
+ bind_[2].buffer = reinterpret_cast<char*>(&state_count_);
+ bind_[2].is_unsigned = MLM_TRUE;
+
+ // 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
///
///
/// @return True if the fetch succeeded, false if there are no more
/// rows to fetch.
- bool getNextRow(AddressStatsRow4& row);
+ 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_ = static_cast<Lease::LeaseState>(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:
/// @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;
+ 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_;
uint32_t state_count_;
};
-MySqlAddressStatsQuery4::MySqlAddressStatsQuery4(MySqlConnection& conn)
- : conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
- ::RECOUNT_LEASE4_STATS]),
- bind_(3) {
-}
-
-MySqlAddressStatsQuery4::~MySqlAddressStatsQuery4() {
- (void) mysql_stmt_free_result(statement_);
-}
-
-
-void
-MySqlAddressStatsQuery4::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;
-
- // state: uint32_t
- bind_[1].buffer_type = MYSQL_TYPE_LONG;
- bind_[1].buffer = reinterpret_cast<char*>(&lease_state_);
- bind_[1].is_unsigned = MLM_TRUE;
-
- // state_count_: uint32_t
- bind_[2].buffer_type = MYSQL_TYPE_LONG;
- bind_[2].buffer = reinterpret_cast<char*>(&state_count_);
- bind_[2].is_unsigned = MLM_TRUE;
-
- // 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 setup failed");
-}
-
-bool
-MySqlAddressStatsQuery4::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_ = static_cast<Lease::LeaseState>(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);
-}
-
-void
-MySqlAddressStatsQuery4::checkError(int status, const char* what) const {
- conn_.checkError(status, MySqlLeaseMgr::RECOUNT_LEASE4_STATS, what);
-}
-
-AddressStatsQuery4Ptr
-MySqlLeaseMgr::startAddressStatsQuery4() {
- AddressStatsQuery4Ptr query(new MySqlAddressStatsQuery4(conn_));
- query->start();
- return(query);
-}
-
/// @brief MySql derivation of the IPv6 statistical lease data query
///
/// This class is used to recalculate IPv6 lease statistics for MySQL
/// @brief Constructor
///
/// @param conn A open connection to the database housing the lease data
- MySqlAddressStatsQuery6(MySqlConnection& conn);
+ MySqlAddressStatsQuery6(MySqlConnection& conn)
+ : conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
+ ::RECOUNT_LEASE6_STATS]),
+ bind_(4) {
+ }
/// @brief Destructor
- virtual ~MySqlAddressStatsQuery6();
+ virtual ~MySqlAddressStatsQuery6() {
+ (void) mysql_stmt_free_result(statement_);
+ }
/// @brief Creates the IPv6 lease statistical data result set
///
/// MySqlLeaseMgr::RECOUNT_LEASE6_STATS. This method creates the binds
/// the statement to the output bind array and then executes the
/// statement.
- void start();
+ 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
+ bind_[2].buffer_type = MYSQL_TYPE_LONG;
+ bind_[2].buffer = reinterpret_cast<char*>(&lease_state_);
+ bind_[2].is_unsigned = MLM_TRUE;
+
+ // state_count_: uint32_t
+ bind_[3].buffer_type = MYSQL_TYPE_LONG;
+ bind_[3].buffer = reinterpret_cast<char*>(&state_count_);
+ bind_[3].is_unsigned = MLM_TRUE;
+
+ // 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_LEASE6_STATS: outbound binding failed");
+
+ // Execute the statement
+ status = mysql_stmt_execute(statement_);
+ checkError(status, "RECOUNT_LEASE6_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_LEASE6_STATS: results storage failed");
+ }
+
/// @brief Fetches the next row in the result set
///
///
/// @return True if the fetch succeeded, false if there are no more
/// rows to fetch.
- bool getNextRow(AddressStatsRow6& row);
+ bool getNextRow(AddressStatsRow6& 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_type_ = static_cast<Lease::Type>(lease_type_);
+ row.lease_state_ = static_cast<Lease::LeaseState>(lease_state_);
+ row.state_count_ = state_count_;
+ have_row = true;
+ } else if (status != MYSQL_NO_DATA) {
+ checkError(status, "RECOUNT_LEASE6_STATS: getNextRow failed");
+ }
+
+ return (have_row);
+ }
+
private:
/// @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;
+ 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
MySqlConnection& conn_;
uint32_t state_count_;
};
-MySqlAddressStatsQuery6::MySqlAddressStatsQuery6(MySqlConnection& conn)
- : conn_(conn), statement_(conn_.statements_[MySqlLeaseMgr
- ::RECOUNT_LEASE6_STATS]),
- bind_(4) {
-}
-
-MySqlAddressStatsQuery6::~MySqlAddressStatsQuery6() {
- (void) mysql_stmt_free_result(statement_);
-}
-
-void
-MySqlAddressStatsQuery6::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
- bind_[2].buffer_type = MYSQL_TYPE_LONG;
- bind_[2].buffer = reinterpret_cast<char*>(&lease_state_);
- bind_[2].is_unsigned = MLM_TRUE;
-
- // state_count_: uint32_t
- bind_[3].buffer_type = MYSQL_TYPE_LONG;
- bind_[3].buffer = reinterpret_cast<char*>(&state_count_);
- bind_[3].is_unsigned = MLM_TRUE;
-
- // 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_LEASE6_STATS: outbound binding failed");
-
- // Execute the statement
- status = mysql_stmt_execute(statement_);
- checkError(status, "RECOUNT_LEASE6_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_LEASE6_STATS: results storage setup failed");
-}
-
-bool
-MySqlAddressStatsQuery6::getNextRow(AddressStatsRow6& 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_type_ = static_cast<Lease::Type>(lease_type_);
- row.lease_state_ = static_cast<Lease::LeaseState>(lease_state_);
- row.state_count_ = state_count_;
- have_row = true;
- } else if (status != MYSQL_NO_DATA) {
- checkError(status, "RECOUNT_LEASE6_STATS: getNextRow failed");
- }
-
- return (have_row);
-}
-
-void
-MySqlAddressStatsQuery6::checkError(int status, const char* what) const {
- conn_.checkError(status, MySqlLeaseMgr::RECOUNT_LEASE6_STATS, what);
-}
-
-AddressStatsQuery6Ptr
-MySqlLeaseMgr::startAddressStatsQuery6() {
- AddressStatsQuery6Ptr query(new MySqlAddressStatsQuery6(conn_));
- query->start();
- return(query);
-}
-
// MySqlLeaseMgr Constructor and Destructor
MySqlLeaseMgr::MySqlLeaseMgr(const MySqlConnection::ParameterMap& parameters)
return (std::make_pair(major, minor));
}
+AddressStatsQuery4Ptr
+MySqlLeaseMgr::startAddressStatsQuery4() {
+ AddressStatsQuery4Ptr query(new MySqlAddressStatsQuery4(conn_));
+ query->start();
+ return(query);
+}
+
+AddressStatsQuery6Ptr
+MySqlLeaseMgr::startAddressStatsQuery6() {
+ AddressStatsQuery6Ptr query(new MySqlAddressStatsQuery6(conn_));
+ query->start();
+ return(query);
+}
+
void
MySqlLeaseMgr::commit() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_COMMIT);
/// @brief Constructor
///
/// @param conn A open connection to the database housing the lease data
- PgSqlAddressStatsQuery4(PgSqlConnection& conn);
+ PgSqlAddressStatsQuery4(PgSqlConnection& conn)
+ : conn_(conn), statement_(tagged_statements[PgSqlLeaseMgr
+ ::RECOUNT_LEASE4_STATS]),
+ result_set_(), next_row_(0) {
+ }
/// @brief Destructor
virtual ~PgSqlAddressStatsQuery4() {};
/// The query used is the prepared statement identified by
/// PgSqlLeaseMgr::RECOUNT_LEASE4_STATS. This method executes the
/// statement which creates the result set.
- void start();
+ void start() {
+ // The query has no parameters, so we only need it's name.
+ result_set_.reset(new PgSqlResult(PQexecPrepared(conn_, statement_.name,
+ 0, NULL, NULL, NULL, 0)));
+
+ conn_.checkStatementError(*result_set_, statement_);
+ }
/// @brief Fetches the next row in the result set
///
///
/// @return True if the fetch succeeded, false if there are no more
/// rows to fetch.
- bool getNextRow(AddressStatsRow4& row);
-
-private:
+ bool getNextRow(AddressStatsRow4& row) {
+ // If we're past the end, punt.
+ if (next_row_ >= result_set_->getRows()) {
+ return (false);
+ }
- /// @brief Analyzes the given statement outcome status
- ///
- /// Wrapper method around the PgSqlConnection: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;
+ // Fetch the subnet id.
+ uint32_t col = 0;
+ uint32_t subnet_id;
+ PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
+ row.subnet_id_ = static_cast<SubnetID>(subnet_id);
+ ++col;
+
+ // Fetch the lease state.
+ uint32_t state;
+ PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state);
+ row.lease_state_ = static_cast<Lease::LeaseState>(state);
+ ++col;
+
+ // Fetch the state count.
+ PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
+ row.state_count_);
+
+ // Point to the next row.
+ ++next_row_;
+ return (true);
+ }
+private:
/// @brief Database connection to use to execute the query
PgSqlConnection& conn_;
uint32_t next_row_;
};
-PgSqlAddressStatsQuery4::PgSqlAddressStatsQuery4(PgSqlConnection& conn)
- : conn_(conn), statement_(tagged_statements[PgSqlLeaseMgr
- ::RECOUNT_LEASE4_STATS]),
- result_set_(), next_row_(0) {
-}
-
-void
-PgSqlAddressStatsQuery4::start() {
- // The query has no parameters, so we only need it's name.
- result_set_.reset(new PgSqlResult(PQexecPrepared(conn_, statement_.name,
- 0, NULL, NULL, NULL, 0)));
-
- conn_.checkStatementError(*result_set_, statement_);
-}
-
-bool
-PgSqlAddressStatsQuery4::getNextRow(AddressStatsRow4& row) {
- // If we're past the end, punt.
- if (next_row_ >= result_set_->getRows()) {
- return (false);
- }
-
- // Fetch the subnet id.
- uint32_t col = 0;
- uint32_t subnet_id;
- PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
- row.subnet_id_ = static_cast<SubnetID>(subnet_id);
- ++col;
-
- // Fetch the lease state.
- uint32_t state;
- PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state);
- row.lease_state_ = static_cast<Lease::LeaseState>(state);
- ++col;
-
- // Fetch the state count.
- PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
- row.state_count_);
-
- // Point to the next row.
- ++next_row_;
-
- return (true);
-}
-
-AddressStatsQuery4Ptr
-PgSqlLeaseMgr::startAddressStatsQuery4() {
- AddressStatsQuery4Ptr query(new PgSqlAddressStatsQuery4(conn_));
- query->start();
- return(query);
-}
-
/// @brief PgSql derivation of the IPv6 statistical lease data query
///
/// This class is used to recalculate IPv6 lease statistics for MySQL
/// @brief Constructor
///
/// @param conn A open connection to the database housing the lease data
- PgSqlAddressStatsQuery6(PgSqlConnection& conn);
+ PgSqlAddressStatsQuery6(PgSqlConnection& conn)
+ : conn_(conn), statement_(tagged_statements[PgSqlLeaseMgr
+ ::RECOUNT_LEASE6_STATS]),
+ result_set_(), next_row_(0) {
+ }
/// @brief Destructor
virtual ~PgSqlAddressStatsQuery6() {};
/// per subnet id. The query used is the prepared statement identified by
/// PgSqlLeaseMgr::RECOUNT_LEASE6_STATS. This method executes the
/// statement which creates the result set.
- void start();
+ void start() {
+ // The query has no parameters, so we only need it's name.
+ result_set_.reset(new PgSqlResult(PQexecPrepared(conn_, statement_.name,
+ 0, NULL, NULL, NULL,
+ 0)));
+
+ conn_.checkStatementError(*result_set_, statement_);
+ }
/// @brief Fetches the next row in the result set
///
///
/// @return True if the fetch succeeded, false if there are no more
/// rows to fetch.
- bool getNextRow(AddressStatsRow6& row);
-
-private:
+ bool getNextRow(AddressStatsRow6& row) {
+ // If we're past the end, punt.
+ if (next_row_ >= result_set_->getRows()) {
+ return (false);
+ }
- /// @brief Analyzes the given statement outcome status
- ///
- /// Wrapper method around the PgSqlConnection: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;
+ // Fetch the subnet id.
+ uint32_t col = 0;
+ uint32_t subnet_id;
+ PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
+ row.subnet_id_ = static_cast<SubnetID>(subnet_id);
+ ++col;
+
+ // Fetch the lease type.
+ uint32_t lease_type;
+ PgSqlExchange::getColumnValue(*result_set_, next_row_ , col,
+ lease_type);
+ row.lease_type_ = static_cast<Lease::Type>(lease_type);
+ ++col;
+
+ // Fetch the lease state.
+ uint32_t state;
+ PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state);
+ row.lease_state_ = static_cast<Lease::LeaseState>(state);
+ ++col;
+
+ // Fetch the state count.
+ PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
+ row.state_count_);
+
+ // Point to the next row.
+ ++next_row_;
+
+ return (true);
+ }
+private:
/// @brief Database connection to use to execute the query
PgSqlConnection& conn_;
uint32_t next_row_;
};
-PgSqlAddressStatsQuery6::PgSqlAddressStatsQuery6(PgSqlConnection& conn)
- : conn_(conn), statement_(tagged_statements[PgSqlLeaseMgr
- ::RECOUNT_LEASE6_STATS]),
- result_set_(), next_row_(0) {
-}
-
-void
-PgSqlAddressStatsQuery6::start() {
- // The query has no parameters, so we only need it's name.
- result_set_.reset(new PgSqlResult(PQexecPrepared(conn_, statement_.name,
- 0, NULL, NULL, NULL, 0)));
-
- conn_.checkStatementError(*result_set_, statement_);
-}
-
-bool
-PgSqlAddressStatsQuery6::getNextRow(AddressStatsRow6& row) {
- // If we're past the end, punt.
- if (next_row_ >= result_set_->getRows()) {
- return (false);
- }
-
- // Fetch the subnet id.
- uint32_t col = 0;
- uint32_t subnet_id;
- PgSqlExchange::getColumnValue(*result_set_, next_row_, col, subnet_id);
- row.subnet_id_ = static_cast<SubnetID>(subnet_id);
- ++col;
-
- // Fetch the lease type.
- uint32_t lease_type;
- PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, lease_type);
- row.lease_type_ = static_cast<Lease::Type>(lease_type);
- ++col;
-
- // Fetch the lease state.
- uint32_t state;
- PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state);
- row.lease_state_ = static_cast<Lease::LeaseState>(state);
- ++col;
-
- // Fetch the state count.
- PgSqlExchange::getColumnValue(*result_set_, next_row_, col, row.state_count_);
-
- // Point to the next row.
- ++next_row_;
-
- return (true);
-}
-
-AddressStatsQuery6Ptr
-PgSqlLeaseMgr::startAddressStatsQuery6() {
- AddressStatsQuery6Ptr query(new PgSqlAddressStatsQuery6(conn_));
- query->start();
- return(query);
-}
-
PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
: LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
exchange6_(new PgSqlLease6Exchange()), conn_(parameters) {
return (deleteLeaseCommon(statement_index, bind_array));
}
+AddressStatsQuery4Ptr
+PgSqlLeaseMgr::startAddressStatsQuery4() {
+ AddressStatsQuery4Ptr query(new PgSqlAddressStatsQuery4(conn_));
+ query->start();
+ return(query);
+}
+
+AddressStatsQuery6Ptr
+PgSqlLeaseMgr::startAddressStatsQuery6() {
+ AddressStatsQuery6Ptr query(new PgSqlAddressStatsQuery6(conn_));
+ query->start();
+ return(query);
+}
+
string
PgSqlLeaseMgr::getName() const {
string name = "";