From: Thomas Markwalder Date: Wed, 17 Aug 2016 13:48:32 +0000 (-0400) Subject: [4294] More clean up X-Git-Tag: trac4631_base~6^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d619d5e38b7fce28316619779684ae8e758eef7e;p=thirdparty%2Fkea.git [4294] More clean up --- diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index ceed6f473d..2ffaa7c114 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -271,7 +271,9 @@ public: /// @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() {}; @@ -280,118 +282,109 @@ public: /// /// 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(); + + // 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 rows_; /// @brief An iterator for accessing the next row within the result set std::vector::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(); - - // 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 /// @@ -407,7 +400,9 @@ public: /// @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() {}; @@ -416,145 +411,132 @@ public: /// /// 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(); + + // 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 rows_; /// @brief An iterator for accessing the next row within the result set std::vector::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(); - - // 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; diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc index 52ed485d51..199911767a 100644 --- a/src/lib/dhcpsrv/mysql_lease_mgr.cc +++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc @@ -1235,10 +1235,16 @@ public: /// @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 /// @@ -1248,7 +1254,37 @@ public: /// 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(&subnet_id_); + bind_[0].is_unsigned = MLM_TRUE; + + // state: uint32_t + bind_[1].buffer_type = MYSQL_TYPE_LONG; + bind_[1].buffer = reinterpret_cast(&lease_state_); + bind_[1].is_unsigned = MLM_TRUE; + + // state_count_: uint32_t + bind_[2].buffer_type = MYSQL_TYPE_LONG; + bind_[2].buffer = reinterpret_cast(&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 /// @@ -1261,7 +1297,20 @@ public: /// /// @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(subnet_id_); + row.lease_state_ = static_cast(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: @@ -1275,7 +1324,9 @@ 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_; @@ -1294,77 +1345,6 @@ private: 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(&subnet_id_); - bind_[0].is_unsigned = MLM_TRUE; - - // state: uint32_t - bind_[1].buffer_type = MYSQL_TYPE_LONG; - bind_[1].buffer = reinterpret_cast(&lease_state_); - bind_[1].is_unsigned = MLM_TRUE; - - // state_count_: uint32_t - bind_[2].buffer_type = MYSQL_TYPE_LONG; - bind_[2].buffer = reinterpret_cast(&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(subnet_id_); - row.lease_state_ = static_cast(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 @@ -1377,10 +1357,16 @@ public: /// @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 /// @@ -1390,7 +1376,42 @@ public: /// 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(&subnet_id_); + bind_[0].is_unsigned = MLM_TRUE; + + // lease type: uint32_t + bind_[1].buffer_type = MYSQL_TYPE_LONG; + bind_[1].buffer = reinterpret_cast(&lease_type_); + bind_[1].is_unsigned = MLM_TRUE; + + // state: uint32_t + bind_[2].buffer_type = MYSQL_TYPE_LONG; + bind_[2].buffer = reinterpret_cast(&lease_state_); + bind_[2].is_unsigned = MLM_TRUE; + + // state_count_: uint32_t + bind_[3].buffer_type = MYSQL_TYPE_LONG; + bind_[3].buffer = reinterpret_cast(&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 /// @@ -1403,7 +1424,22 @@ public: /// /// @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(subnet_id_); + row.lease_type_ = static_cast(lease_type_); + row.lease_state_ = static_cast(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: @@ -1417,7 +1453,9 @@ 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_; @@ -1438,82 +1476,6 @@ private: 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(&subnet_id_); - bind_[0].is_unsigned = MLM_TRUE; - - // lease type: uint32_t - bind_[1].buffer_type = MYSQL_TYPE_LONG; - bind_[1].buffer = reinterpret_cast(&lease_type_); - bind_[1].is_unsigned = MLM_TRUE; - - // state: uint32_t - bind_[2].buffer_type = MYSQL_TYPE_LONG; - bind_[2].buffer = reinterpret_cast(&lease_state_); - bind_[2].is_unsigned = MLM_TRUE; - - // state_count_: uint32_t - bind_[3].buffer_type = MYSQL_TYPE_LONG; - bind_[3].buffer = reinterpret_cast(&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(subnet_id_); - row.lease_type_ = static_cast(lease_type_); - row.lease_state_ = static_cast(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) @@ -2322,6 +2284,20 @@ MySqlLeaseMgr::getVersion() const { 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); diff --git a/src/lib/dhcpsrv/pgsql_lease_mgr.cc b/src/lib/dhcpsrv/pgsql_lease_mgr.cc index 751f636004..13c3c2ee4d 100644 --- a/src/lib/dhcpsrv/pgsql_lease_mgr.cc +++ b/src/lib/dhcpsrv/pgsql_lease_mgr.cc @@ -706,7 +706,11 @@ public: /// @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() {}; @@ -718,7 +722,13 @@ public: /// 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 /// @@ -731,22 +741,35 @@ public: /// /// @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(subnet_id); + ++col; + + // Fetch the lease state. + uint32_t state; + PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state); + row.lease_state_ = static_cast(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_; @@ -760,58 +783,6 @@ private: 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(subnet_id); - ++col; - - // Fetch the lease state. - uint32_t state; - PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state); - row.lease_state_ = static_cast(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 @@ -824,7 +795,11 @@ public: /// @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() {}; @@ -836,7 +811,14 @@ public: /// 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 /// @@ -849,22 +831,43 @@ public: /// /// @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(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); + ++col; + + // Fetch the lease state. + uint32_t state; + PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state); + row.lease_state_ = static_cast(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_; @@ -878,63 +881,6 @@ private: 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(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); - ++col; - - // Fetch the lease state. - uint32_t state; - PgSqlExchange::getColumnValue(*result_set_, next_row_ , col, state); - row.lease_state_ = static_cast(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) { @@ -1476,6 +1422,20 @@ PgSqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs, 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 = "";