Browse Source

[4294] More clean up

Thomas Markwalder 8 years ago
parent
commit
d619d5e38b
3 changed files with 414 additions and 496 deletions
  1. 180 198
      src/lib/dhcpsrv/memfile_lease_mgr.cc
  2. 133 157
      src/lib/dhcpsrv/mysql_lease_mgr.cc
  3. 101 141
      src/lib/dhcpsrv/pgsql_lease_mgr.cc

+ 180 - 198
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<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
 ///
@@ -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<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;

+ 133 - 157
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<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
     ///
@@ -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<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:
 
@@ -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<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
@@ -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<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
     ///
@@ -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<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:
 
@@ -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<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)
@@ -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);

+ 101 - 141
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<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_;
 
@@ -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<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
@@ -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<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_;
 
@@ -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<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) {
@@ -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 = "";