Commit eb211d7c authored by Stephen Morris's avatar Stephen Morris
Browse files

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

parent 0a14e05f
......@@ -532,12 +532,20 @@ MySqlLeaseMgr::prepareStatements() {
"SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len "
"FROM lease6 WHERE address = ?");
"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 = ?");
"FROM lease6 "
"WHERE duid = ? AND iaid = ?");
prepareStatement(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 = ?");
prepareStatement(GET_VERSION,
"SELECT version, minor FROM schema_version");
prepareStatement(INSERT_LEASE6,
......@@ -549,7 +557,8 @@ MySqlLeaseMgr::prepareStatements() {
"UPDATE lease6 SET address = ?, duid = ?, "
"valid_lifetime = ?, expire = ?, subnet_id = ?, "
"pref_lifetime = ?, lease_type = ?, iaid = ?, "
"prefix_len = ? WHERE address = ?");
"prefix_len = ? "
"WHERE address = ?");
}
bool
......@@ -778,11 +787,87 @@ MySqlLeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
}
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 {
// 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_[GET_LEASE6_DUID_IAID_SUBID], inbind);
checkError(status, GET_LEASE6_DUID_IAID_SUBID, "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_[GET_LEASE6_DUID_IAID_SUBID], &outbind[0]);
checkError(status, GET_LEASE6_DUID_IAID_SUBID, "unable to bind SELECT clause parameters");
// Execute the query.
status = mysql_stmt_execute(statements_[GET_LEASE6_DUID_IAID_SUBID]);
checkError(status, GET_LEASE6_DUID_IAID_SUBID, "unable to execute");
Lease6Ptr result;
status = mysql_stmt_fetch(statements_[GET_LEASE6_DUID_IAID_SUBID]);
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_[GET_LEASE6_DUID_IAID_SUBID]);
// Lease type is returned, to rethrow the exception with a bit
// more data.
isc_throw(BadValue, ex.what() << ". Statement is <" <<
text_statements_[GET_LEASE6_DUID_IAID_SUBID] << ">");
}
// 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, GET_LEASE6_DUID_IAID_SUBID, "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_[GET_LEASE6_DUID_IAID_SUBID]);
return (result);
}
void
......
......@@ -334,6 +334,7 @@ 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
......
......@@ -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);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment