BIND 10 trac2342, updated. 1ed8ce0cc009b89158583d462e96b42e160dbe3e [2342] Move all SQL statement definitions to head of file

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Nov 4 20:27:20 UTC 2012


The branch, trac2342 has been updated
       via  1ed8ce0cc009b89158583d462e96b42e160dbe3e (commit)
       via  eb211d7cfc40962bd64193b3a91ecd2560edf3f3 (commit)
      from  0a14e05f428a3c6494a6f92f032ca9ecbb401919 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1ed8ce0cc009b89158583d462e96b42e160dbe3e
Author: Stephen Morris <stephen at isc.org>
Date:   Sun Nov 4 20:20:21 2012 +0000

    [2342] Move all SQL statement definitions to head of file
    
    It is easier to add a new statement to the head of the file rather
    than searching through the file for the method in which the prepared
    statements are created.

commit eb211d7cfc40962bd64193b3a91ecd2560edf3f3
Author: Stephen Morris <stephen at isc.org>
Date:   Sun Nov 4 19:57:05 2012 +0000

    [2342] Add getLease6 selecting by DUID, IAID and Subnet ID

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dhcp/mysql_lease_mgr.cc                |  265 +++++++++++++++++-------
 src/lib/dhcp/mysql_lease_mgr.h                 |    5 +-
 src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc |   55 ++++-
 3 files changed, 247 insertions(+), 78 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/mysql_lease_mgr.cc b/src/lib/dhcp/mysql_lease_mgr.cc
index e03237f..d3523e9 100644
--- a/src/lib/dhcp/mysql_lease_mgr.cc
+++ b/src/lib/dhcp/mysql_lease_mgr.cc
@@ -23,6 +23,7 @@
 #include <asiolink/io_address.h>
 
 using namespace isc;
+using namespace isc::dhcp;
 using namespace std;
 
 namespace {
@@ -41,8 +42,56 @@ namespace {
 const size_t ADDRESS6_TEXT_MAX_LEN = 42;    // Max size of a IPv6 text buffer
 const size_t DUID_MAX_LEN = 128;            // Max size of a DUID
 ///@}
+
+/// @brief MySQL Selection Statements
+///
+/// Each statement is associated with the index, used by the various methods
+/// to access the prepared statement.
+struct TaggedStatement {
+    MySqlLeaseMgr::StatementIndex index;
+    const char*                   text;
 };
 
+TaggedStatement tagged_statements[] = {
+    {MySqlLeaseMgr::DELETE_LEASE6,
+                    "DELETE FROM lease6 WHERE address = ?"},
+    {MySqlLeaseMgr::GET_LEASE6_ADDR,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len "
+                            "FROM lease6 "
+                            "WHERE address = ?"},
+    {MySqlLeaseMgr::GET_LEASE6_DUID_IAID,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len "
+                            "FROM lease6 "
+                            "WHERE duid = ? AND iaid = ?"},
+    {MySqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len "
+                            "FROM lease6 "
+                            "WHERE duid = ? AND iaid = ? AND subnet_id = ?"},
+    {MySqlLeaseMgr::GET_VERSION,
+                    "SELECT version, minor FROM schema_version"},
+    {MySqlLeaseMgr::INSERT_LEASE6,
+                    "INSERT INTO lease6(address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len) "
+                            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"},
+    {MySqlLeaseMgr::UPDATE_LEASE6,
+                    "UPDATE lease6 SET address = ?, duid = ?, "
+                        "valid_lifetime = ?, expire = ?, subnet_id = ?, "
+                        "pref_lifetime = ?, lease_type = ?, iaid = ?, "
+                        "prefix_len = ? "
+                            "WHERE address = ?"},
+    // End of list sentinel
+    {MySqlLeaseMgr::NUM_STATEMENTS, NULL}
+};
+
+};  // Anonymous namespace
+
 namespace isc {
 namespace dhcp {
 
@@ -525,31 +574,11 @@ MySqlLeaseMgr::prepareStatements() {
     text_statements_.clear();
     text_statements_.resize(NUM_STATEMENTS, std::string(""));
 
-    // Now allocate the statements
-    prepareStatement(DELETE_LEASE6,
-                     "DELETE FROM lease6 WHERE address = ?");
-    prepareStatement(GET_LEASE6_ADDR,
-                     "SELECT address, duid, valid_lifetime, "
-                         "expire, subnet_id, pref_lifetime, "
-                         "lease_type, iaid, prefix_len "
-                         "FROM lease6 WHERE address = ?");
-    prepareStatement(GET_LEASE6_DUID_IAID,
-                     "SELECT address, duid, valid_lifetime, "
-                         "expire, subnet_id, pref_lifetime, "
-                         "lease_type, iaid, prefix_len "
-                         "FROM lease6 WHERE duid = ? AND iaid = ?");
-    prepareStatement(GET_VERSION,
-                     "SELECT version, minor FROM schema_version");
-    prepareStatement(INSERT_LEASE6,
-                     "INSERT INTO lease6(address, duid, valid_lifetime, "
-                         "expire, subnet_id, pref_lifetime, "
-                         "lease_type, iaid, prefix_len) "
-                         "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
-    prepareStatement(UPDATE_LEASE6,
-                     "UPDATE lease6 SET address = ?, duid = ?, "
-                         "valid_lifetime = ?, expire = ?, subnet_id = ?, "
-                         "pref_lifetime = ?, lease_type = ?, iaid = ?, "
-                         "prefix_len = ? WHERE address = ?");
+    // Created the MySQL prepared statements for each DML statement.
+    for (int i = 0; tagged_statements[i].text != NULL; ++i) {
+        prepareStatement(tagged_statements[i].index,
+                         tagged_statements[i].text);
+    }
 }
 
 bool
@@ -561,6 +590,7 @@ MySqlLeaseMgr::addLease(const Lease4Ptr& /* lease */) {
 
 bool
 MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
+    const StatementIndex stindex = INSERT_LEASE6;
 
     // Create the MYSQL_BIND array for the lease
     MySqlLease6Exchange exchange;
@@ -568,11 +598,11 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
     exchange.createBindForSend(lease, bind);
 
     // Bind the parameters to the statement
-    int status = mysql_stmt_bind_param(statements_[INSERT_LEASE6], &bind[0]);
-    checkError(status, INSERT_LEASE6, "unable to bind parameters");
+    int status = mysql_stmt_bind_param(statements_[stindex], &bind[0]);
+    checkError(status, stindex, "unable to bind parameters");
 
     // Execute the statement
-    status = mysql_stmt_execute(statements_[INSERT_LEASE6]);
+    status = mysql_stmt_execute(statements_[stindex]);
     if (status != 0) {
 
         // Failure: check for the special case of duplicate entry.  If this is
@@ -581,7 +611,7 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
         if (mysql_errno(mysql_) == ER_DUP_ENTRY) {
             return (false);
         }
-        checkError(status, INSERT_LEASE6, "unable to execute");
+        checkError(status, stindex, "unable to execute");
     }
 
     // Insert succeeded
@@ -635,6 +665,8 @@ MySqlLeaseMgr::getLease4(const ClientId& /* clientid */,
 
 Lease6Ptr
 MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
+    const StatementIndex stindex = GET_LEASE6_ADDR;
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[1];
     memset(inbind, 0, sizeof(inbind));
@@ -648,8 +680,8 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
     inbind[0].length = &addr6_length;
 
     // Bind the input parameters to the statement
-    int status = mysql_stmt_bind_param(statements_[GET_LEASE6_ADDR], inbind);
-    checkError(status, GET_LEASE6_ADDR, "unable to bind WHERE clause parameter");
+    int status = mysql_stmt_bind_param(statements_[stindex], inbind);
+    checkError(status, stindex, "unable to bind WHERE clause parameter");
 
     // Set up the SELECT clause
     MySqlLease6Exchange exchange;
@@ -657,15 +689,15 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
     exchange.createBindForReceive(outbind);
 
     // Bind the output parameters to the statement
-    status = mysql_stmt_bind_result(statements_[GET_LEASE6_ADDR], &outbind[0]);
-    checkError(status, GET_LEASE6_ADDR, "unable to bind SELECT caluse parameters");
+    status = mysql_stmt_bind_result(statements_[stindex], &outbind[0]);
+    checkError(status, stindex, "unable to bind SELECT caluse parameters");
 
     // Execute the statement
-    status = mysql_stmt_execute(statements_[GET_LEASE6_ADDR]);
-    checkError(status, GET_LEASE6_ADDR, "unable to execute");
+    status = mysql_stmt_execute(statements_[stindex]);
+    checkError(status, stindex, "unable to execute");
 
     // Fetch the data.
-    status = mysql_stmt_fetch(statements_[GET_LEASE6_ADDR]);
+    status = mysql_stmt_fetch(statements_[stindex]);
 
     Lease6Ptr result;
     if (status == 0) {
@@ -674,11 +706,11 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
         } catch (const isc::BadValue& ex) {
             // Free up result set.
 
-            (void) mysql_stmt_free_result(statements_[GET_LEASE6_ADDR]);
+            (void) mysql_stmt_free_result(statements_[stindex]);
             // Lease type is returned, to rethrow the exception with a bit
             // more data.
             isc_throw(BadValue, ex.what() << ". Statement is <" <<
-                      text_statements_[GET_LEASE6_ADDR] << ">");
+                      text_statements_[stindex] << ">");
         }
 
         // As the address is the primary key in the table, we can't return
@@ -686,7 +718,7 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
         // been returned.
 
     } else if (status == 1) {
-        checkError(status, GET_LEASE6_ADDR, "unable to fetch results");
+        checkError(status, stindex, "unable to fetch results");
 
     } else {
         // @TODO Handle truncation
@@ -696,12 +728,14 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
     }
 
     // Free data structures associated with information returned.
-    (void) mysql_stmt_free_result(statements_[GET_LEASE6_ADDR]);
+    (void) mysql_stmt_free_result(statements_[stindex]);
     return (result);
 }
 
 Lease6Collection
 MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
+    const StatementIndex stindex = GET_LEASE6_DUID_IAID;
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
     memset(inbind, 0, sizeof(inbind));
@@ -724,8 +758,8 @@ MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
     inbind[1].is_unsigned = static_cast<my_bool>(1);
 
     // Bind the input parameters to the statement
-    int status = mysql_stmt_bind_param(statements_[GET_LEASE6_DUID_IAID], inbind);
-    checkError(status, GET_LEASE6_DUID_IAID, "unable to bind WHERE clause parameter");
+    int status = mysql_stmt_bind_param(statements_[stindex], inbind);
+    checkError(status, stindex, "unable to bind WHERE clause parameter");
 
     // Set up the SELECT clause
     MySqlLease6Exchange exchange;
@@ -733,56 +767,134 @@ MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
     exchange.createBindForReceive(outbind);
 
     // Bind the output parameters to the statement
-    status = mysql_stmt_bind_result(statements_[GET_LEASE6_DUID_IAID], &outbind[0]);
-    checkError(status, GET_LEASE6_DUID_IAID, "unable to bind SELECT clause parameters");
+    status = mysql_stmt_bind_result(statements_[stindex], &outbind[0]);
+    checkError(status, stindex, "unable to bind SELECT clause parameters");
 
     // Execute the query.
-    status = mysql_stmt_execute(statements_[GET_LEASE6_DUID_IAID]);
-    checkError(status, GET_LEASE6_DUID_IAID, "unable to execute");
+    status = mysql_stmt_execute(statements_[stindex]);
+    checkError(status, stindex, "unable to execute");
 
     // Ensure that all the lease information is retrieved in one go to avoid overhead
     // of going back and forth between client and server.
-    status = mysql_stmt_store_result(statements_[GET_LEASE6_DUID_IAID]);
-    checkError(status, GET_LEASE6_DUID_IAID, "unable to set up for storing all results");
+    status = mysql_stmt_store_result(statements_[stindex]);
+    checkError(status, stindex, "unable to set up for storing all results");
 
     // Fetch the data.  There could be multiple rows, so we need to iterate
     // until all data has been retrieved.
     Lease6Collection result;
-    while ((status = mysql_stmt_fetch(statements_[GET_LEASE6_DUID_IAID])) == 0) {
+    while ((status = mysql_stmt_fetch(statements_[stindex])) == 0) {
         try {
             Lease6Ptr lease = exchange.getLeaseData();
             result.push_back(lease);
 
         } catch (const isc::BadValue& ex) {
             // Free up result set.
-            (void) mysql_stmt_free_result(statements_[GET_LEASE6_DUID_IAID]);
+            (void) mysql_stmt_free_result(statements_[stindex]);
 
             // Rethrow the exception with a bit more data.
             isc_throw(BadValue, ex.what() << ". Statement is <" <<
-                      text_statements_[GET_LEASE6_DUID_IAID] << ">");
+                      text_statements_[stindex] << ">");
         }
     }
 
     // How did the fetch end?
     if (status == 1) {
         // Error - unable to fecth results
-        checkError(status, GET_LEASE6_DUID_IAID, "unable to fetch results");
+        checkError(status, stindex, "unable to fetch results");
     } else if (status == MYSQL_DATA_TRUNCATED) {
         // @TODO Handle truncation
         ;
     }
 
     // Free up resources assoicated with the fetched data.
-    (void) mysql_stmt_free_result(statements_[GET_LEASE6_DUID_IAID]);
+    (void) mysql_stmt_free_result(statements_[stindex]);
     return (result);
 }
 
 Lease6Ptr
-MySqlLeaseMgr::getLease6(const DUID& /* duid */, uint32_t /* iaid */,
-                         SubnetID /* subnet_id */) const {
-    isc_throw(NotImplemented, "MySqlLeaseMgr::getLease4(const DUID&, SubnetID) "
-              "not implemented yet");
-    return (Lease6Ptr());
+MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
+                         SubnetID subnet_id) const {
+    const StatementIndex stindex = GET_LEASE6_DUID_IAID_SUBID;
+
+    // Set up the WHERE clause value
+    MYSQL_BIND inbind[3];
+    memset(inbind, 0, sizeof(inbind));
+
+    // DUID.  The complex casting is needed to obtain the "const" vector of
+    // uint8_t from the DUID, point to the start of it (discarding the
+    // "const"ness) and finally casing it to "char*" for the MySQL buffer
+    // element.
+    const vector<uint8_t>& duid_vector = duid.getDuid();
+    unsigned long duid_length = duid_vector.size();
+    inbind[0].buffer_type = MYSQL_TYPE_BLOB;
+    inbind[0].buffer = reinterpret_cast<char*>(
+            const_cast<uint8_t*>(&duid_vector[0]));
+    inbind[0].buffer_length = duid_length;
+    inbind[0].length = &duid_length;
+
+    // IAID
+    inbind[1].buffer_type = MYSQL_TYPE_LONG;
+    inbind[1].buffer = reinterpret_cast<char*>(&iaid);
+    inbind[1].is_unsigned = static_cast<my_bool>(1);
+
+    // Subnet ID
+    inbind[2].buffer_type = MYSQL_TYPE_LONG;
+    inbind[2].buffer = reinterpret_cast<char*>(&subnet_id);
+    inbind[2].is_unsigned = static_cast<my_bool>(1);
+
+    // Bind the input parameters to the statement
+    int status = mysql_stmt_bind_param(statements_[stindex], inbind);
+    checkError(status, stindex, "unable to bind WHERE clause parameter");
+
+    // Set up the SELECT clause
+    MySqlLease6Exchange exchange;
+    std::vector<MYSQL_BIND> outbind;
+    exchange.createBindForReceive(outbind);
+
+    // Bind the output parameters to the statement
+    status = mysql_stmt_bind_result(statements_[stindex], &outbind[0]);
+    checkError(status, stindex, "unable to bind SELECT clause parameters");
+
+    // Execute the query.
+    status = mysql_stmt_execute(statements_[stindex]);
+    checkError(status, stindex, "unable to execute");
+
+    Lease6Ptr result;
+    status = mysql_stmt_fetch(statements_[stindex]);
+    if (status == 0) {
+        try {
+            result = exchange.getLeaseData();
+
+            // TODO: check for more than one row returned.  At present, just ignore
+            // the excess and take the first.
+
+        } catch (const isc::BadValue& ex) {
+            // Free up result set.
+
+            (void) mysql_stmt_free_result(statements_[stindex]);
+            // Lease type is returned, to rethrow the exception with a bit
+            // more data.
+            isc_throw(BadValue, ex.what() << ". Statement is <" <<
+                      text_statements_[stindex] << ">");
+        }
+
+        // As the address is the primary key in the table, we can't return
+        // two rows, so we don't bother checking whether multiple rows have
+        // been returned.
+
+    } else if (status == 1) {
+        checkError(status, stindex, "unable to fetch results");
+
+    } else {
+        // @TODO Handle truncation
+        // We are ignoring truncation for now, so the only other result is
+        // no data was found.  In that case, we return a null Lease6 structure.
+        // This has already been set, so the action is a no-op.
+    }
+
+    // Free data structures associated with information returned.
+    (void) mysql_stmt_free_result(statements_[stindex]);
+    return (result);
 }
 
 void
@@ -793,6 +905,8 @@ MySqlLeaseMgr::updateLease4(const Lease4Ptr& /* lease4 */) {
 
 void
 MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
+    const StatementIndex stindex = UPDATE_LEASE6;
+
     // Create the MYSQL_BIND array for the data being updated
     MySqlLease6Exchange exchange;
     std::vector<MYSQL_BIND> bind;
@@ -812,16 +926,16 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     bind.push_back(where);
 
     // Bind the parameters to the statement
-    int status = mysql_stmt_bind_param(statements_[UPDATE_LEASE6], &bind[0]);
-    checkError(status, UPDATE_LEASE6, "unable to bind parameters");
+    int status = mysql_stmt_bind_param(statements_[stindex], &bind[0]);
+    checkError(status, stindex, "unable to bind parameters");
 
     // Execute
-    status = mysql_stmt_execute(statements_[UPDATE_LEASE6]);
-    checkError(status, UPDATE_LEASE6, "unable to execute");
+    status = mysql_stmt_execute(statements_[stindex]);
+    checkError(status, stindex, "unable to execute");
 
     // See how many rows were affected.  The statement should only delete a
     // single row.
-    int affected_rows = mysql_stmt_affected_rows(statements_[UPDATE_LEASE6]);
+    int affected_rows = mysql_stmt_affected_rows(statements_[stindex]);
     if (affected_rows == 0) {
         isc_throw(NoSuchLease, "unable to update lease for address " <<
                   addr6 << " as it does not exist");
@@ -842,6 +956,7 @@ MySqlLeaseMgr::deleteLease4(const isc::asiolink::IOAddress& /* addr */) {
 
 bool
 MySqlLeaseMgr::deleteLease6(const isc::asiolink::IOAddress& addr) {
+    const StatementIndex stindex = DELETE_LEASE6;
 
     // Set up the WHERE clause value
     MYSQL_BIND inbind[1];
@@ -856,16 +971,16 @@ MySqlLeaseMgr::deleteLease6(const isc::asiolink::IOAddress& addr) {
     inbind[0].length = &addr6_length;
 
     // Bind the input parameters to the statement
-    int status = mysql_stmt_bind_param(statements_[DELETE_LEASE6], inbind);
-    checkError(status, DELETE_LEASE6, "unable to bind WHERE clause parameter");
+    int status = mysql_stmt_bind_param(statements_[stindex], inbind);
+    checkError(status, stindex, "unable to bind WHERE clause parameter");
 
     // Execute
-    status = mysql_stmt_execute(statements_[DELETE_LEASE6]);
-    checkError(status, DELETE_LEASE6, "unable to execute");
+    status = mysql_stmt_execute(statements_[stindex]);
+    checkError(status, stindex, "unable to execute");
 
     // See how many rows were affected.  Note that the statement may delete
     // multiple rows.
-    return (mysql_stmt_affected_rows(statements_[DELETE_LEASE6]) > 0);
+    return (mysql_stmt_affected_rows(statements_[stindex]) > 0);
 
     return false;
 }
@@ -888,14 +1003,16 @@ MySqlLeaseMgr::getDescription() const {
 
 std::pair<uint32_t, uint32_t>
 MySqlLeaseMgr::getVersion() const {
+    const StatementIndex stindex = GET_VERSION;
+
     uint32_t    major;      // Major version number
     uint32_t    minor;      // Minor version number
 
     // Execute the prepared statement
-    int status = mysql_stmt_execute(statements_[GET_VERSION]);
+    int status = mysql_stmt_execute(statements_[stindex]);
     if (status != 0) {
         isc_throw(DbOperationError, "unable to execute <"
-                  << text_statements_[GET_VERSION] << "> - reason: " <<
+                  << text_statements_[stindex] << "> - reason: " <<
                   mysql_error(mysql_));
     }
 
@@ -913,21 +1030,21 @@ MySqlLeaseMgr::getVersion() const {
     bind[1].buffer = &minor;
     bind[1].buffer_length = sizeof(minor);
 
-    status = mysql_stmt_bind_result(statements_[GET_VERSION], bind);
+    status = mysql_stmt_bind_result(statements_[stindex], bind);
     if (status != 0) {
         isc_throw(DbOperationError, "unable to bind result set: " <<
                   mysql_error(mysql_));
     }
 
     // Get the result
-    status = mysql_stmt_fetch(statements_[GET_VERSION]);
+    status = mysql_stmt_fetch(statements_[stindex]);
     if (status != 0) {
-        (void) mysql_stmt_free_result(statements_[GET_VERSION]);
+        (void) mysql_stmt_free_result(statements_[stindex]);
         isc_throw(DbOperationError, "unable to obtain result set: " <<
                   mysql_error(mysql_));
     }
 
-    (void) mysql_stmt_free_result(statements_[GET_VERSION]);
+    (void) mysql_stmt_free_result(statements_[stindex]);
     return (std::make_pair(major, minor));
 }
 
diff --git a/src/lib/dhcp/mysql_lease_mgr.h b/src/lib/dhcp/mysql_lease_mgr.h
index 3ecd14f..6a542f6 100644
--- a/src/lib/dhcp/mysql_lease_mgr.h
+++ b/src/lib/dhcp/mysql_lease_mgr.h
@@ -322,11 +322,8 @@ public:
     static
     void convertFromDatabaseTime(const MYSQL_TIME& expire, 
                                  uint32_t valid_lifetime, time_t& cltt);
-
     ///@}
 
-
-private:
     /// @brief Statement Tags
     ///
     /// The contents of the enum are indexes into the list of SQL statements
@@ -334,12 +331,14 @@ private:
         DELETE_LEASE6,              // Delete from lease6 by address
         GET_LEASE6_ADDR,            // Get lease6 by address
         GET_LEASE6_DUID_IAID,       // Get lease6 by DUID and IAID
+        GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and Subnet ID
         GET_VERSION,                // Obtain version number
         INSERT_LEASE6,              // Add entry to lease6 table
         UPDATE_LEASE6,              // Update a Lease6 entry
         NUM_STATEMENTS              // Number of statements
     };
 
+private:
     /// @brief Prepare Single Statement
     ///
     /// Creates a prepared statement from the text given and adds it to the
diff --git a/src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc
index b698c8b..87afe78 100644
--- a/src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc
@@ -541,7 +541,6 @@ TEST_F(MySqlLeaseMgrTest, BasicLease6) {
     detailCompareLease6(leases[2], l_returned);
 }
 
-
 // @brief Check GetLease6 methods - Access by DUID/IAID
 //
 // Adds leases to the database and checks that they can be accessed via
@@ -573,6 +572,60 @@ TEST_F(MySqlLeaseMgrTest, GetLease6Extended1) {
     EXPECT_EQ(L1_ADDRESS, addresses[0]);
     EXPECT_EQ(L4_ADDRESS, addresses[1]);
     EXPECT_EQ(L5_ADDRESS, addresses[2]);
+
+    // Check that nothing is returned when either the IAID or DUID match
+    // nothing.
+    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1);
+    EXPECT_EQ(0, returned.size());
+
+    // Alter the leases[1] DUID to match nothing in the database.
+    vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
+    ++duid_vector[0];
+    DUID new_duid(duid_vector);
+    returned = lmptr_->getLease6(new_duid, leases[1]->iaid_);
+    EXPECT_EQ(0, returned.size());
+}
+
+
+
+// @brief Check GetLease6 methods - Access by DUID/IAID/SubnetID
+//
+// Adds leases to the database and checks that they can be accessed via
+// a combination of DIUID and IAID.
+TEST_F(MySqlLeaseMgrTest, GetLease6Extended2) {
+    // Get the leases to be used for the test.
+    vector<Lease6Ptr> leases = createLeases6();
+    EXPECT_LE(6, leases.size());    // Expect to access leases 0 through 5
+
+    // Add them to the database
+    for (int i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // Get the leases matching the DUID and IAID of lease[1].
+    Lease6Ptr returned = lmptr_->getLease6(*leases[1]->duid_,
+                                           leases[1]->iaid_,
+                                           leases[1]->subnet_id_);
+    ASSERT_TRUE(returned);
+    EXPECT_TRUE(*returned == *leases[1]);
+
+    // Modify each of the three parameters (DUID, IAID, Subnet ID) and
+    // check that nothing is returned.
+    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1,
+                                 leases[1]->subnet_id_);
+    EXPECT_FALSE(returned);
+
+    returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_,
+                                 leases[1]->subnet_id_ + 1);
+    EXPECT_FALSE(returned);
+
+    // Alter the leases[1] DUID to match nothing in the database.
+    vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
+    ++duid_vector[0];
+    DUID new_duid(duid_vector);
+    returned = lmptr_->getLease6(new_duid, leases[1]->iaid_,
+                                 leases[1]->subnet_id_);
+    EXPECT_FALSE(returned);
 }
 
 



More information about the bind10-changes mailing list