Commit ffbfe8fb authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[1781] introduced deleteRecordInNSEC3Zone DB accessor method for del'ing NSEC3.

updated DatabaseUpdater::deleteRRset so it would use the new method when
deleting NSEC3.
parent fa7b9c53
......@@ -1284,7 +1284,7 @@ DatabaseUpdater::addRRset(const AbstractRRset& rrset) {
// the interface, but until then we have to conform to the schema.
sigtype = covered_type.toText();
}
const string rdata = it->getCurrent().toText();
const string& rdata = it->getCurrent().toText();
if (journaling_) {
const string journal[Accessor::DIFF_PARAM_COUNT] =
{ cvtr.getName(), cvtr.getType(), cvtr.getTTL(), rdata };
......@@ -1315,15 +1315,7 @@ DatabaseUpdater::deleteRRset(const AbstractRRset& rrset) {
validateAddOrDelete("delete", rrset, ADD, DELETE);
RdataIteratorPtr it = rrset.getRdataIterator();
string params[Accessor::DEL_PARAM_COUNT]; // initialized with ""
params[Accessor::DEL_NAME] = rrset.getName().toText();
params[Accessor::DEL_TYPE] = rrset.getType().toText();
string journal[Accessor::DIFF_PARAM_COUNT];
if (journaling_) {
journal[Accessor::DIFF_NAME] = params[Accessor::DEL_NAME];
journal[Accessor::DIFF_TYPE] = params[Accessor::DEL_TYPE];
journal[Accessor::DIFF_TTL] = rrset.getTTL().toText();
diff_phase_ = DELETE;
if (rrset.getType() == RRType::SOA()) {
serial_ =
......@@ -1331,14 +1323,25 @@ DatabaseUpdater::deleteRRset(const AbstractRRset& rrset) {
getSerial();
}
}
RRParameterConverter cvtr(rrset);
for (; !it->isLast(); it->next()) {
params[Accessor::DEL_RDATA] = it->getCurrent().toText();
bool nsec3_type = (rrset.getType() == RRType::NSEC3());
const string& rdata = it->getCurrent().toText();
if (journaling_) {
journal[Accessor::DIFF_RDATA] = params[Accessor::DEL_RDATA];
const string journal[Accessor::DIFF_PARAM_COUNT] =
{ cvtr.getName(), cvtr.getType(), cvtr.getTTL(), rdata };
accessor_->addRecordDiff(zone_id_, serial_.getValue(),
Accessor::DIFF_DELETE, journal);
}
accessor_->deleteRecordInZone(params);
const string params[Accessor::DEL_PARAM_COUNT] =
{ nsec3_type ? cvtr.getNSEC3Name() : cvtr.getName(),
cvtr.getType(), rdata };
if (nsec3_type) {
accessor_->deleteRecordInNSEC3Zone(params);
} else {
accessor_->deleteRecordInZone(params);
}
}
}
......
......@@ -482,6 +482,9 @@ public:
virtual void deleteRecordInZone(
const std::string (&params)[DEL_PARAM_COUNT]) = 0;
virtual void deleteRecordInNSEC3Zone(
const std::string (&params)[DEL_PARAM_COUNT]) = 0;
/// \brief Start a general transaction.
///
/// Each derived class version of this method starts a database
......
......@@ -1138,6 +1138,13 @@ SQLite3Accessor::deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
*dbparameters_, DEL_RECORD, params, "delete record from zone");
}
void
SQLite3Accessor::deleteRecordInNSEC3Zone(
const string (&/*params*/)[DEL_PARAM_COUNT])
{
isc_throw(NotImplemented, "not yet implemented");
}
void
SQLite3Accessor::addRecordDiff(int zone_id, uint32_t serial,
DiffOperation operation,
......
......@@ -220,6 +220,9 @@ public:
virtual void deleteRecordInZone(
const std::string (&params)[DEL_PARAM_COUNT]);
virtual void deleteRecordInNSEC3Zone(
const std::string (&params)[DEL_PARAM_COUNT]);
/// This derived version of the method prepares an SQLite3 statement
/// for adding the diff first time it's called, and if it fails throws
// an \c SQLite3Error exception.
......
......@@ -253,6 +253,7 @@ public:
virtual void addRecordToNSEC3Zone(const string (&)[ADD_NSEC3_COLUMN_COUNT])
{}
virtual void deleteRecordInZone(const string (&)[DEL_PARAM_COUNT]) {}
virtual void deleteRecordInNSEC3Zone(const string (&)[DEL_PARAM_COUNT]) {}
virtual void addRecordDiff(int, uint32_t, DiffOperation,
const std::string (&)[DIFF_PARAM_COUNT]) {}
......@@ -758,6 +759,7 @@ public:
addRecord(*update_nsec3_namespace_, normal_columns);
}
private:
// Helper predicate class used in deleteRecordInZone().
struct deleteMatch {
deleteMatch(const string& type, const string& rdata) :
......@@ -770,19 +772,33 @@ public:
const string& rdata_;
};
virtual void deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
// Common subroutine for deleteRecordinZone and deleteRecordInNSEC3Zone.
void deleteRecord(Domains& domains,
const string (&params)[DEL_PARAM_COUNT])
{
vector<vector<string> >& records =
(*update_records_)[params[DatabaseAccessor::DEL_NAME]];
domains[params[DatabaseAccessor::DEL_NAME]];
records.erase(remove_if(records.begin(), records.end(),
deleteMatch(
params[DatabaseAccessor::DEL_TYPE],
params[DatabaseAccessor::DEL_RDATA])),
records.end());
if (records.empty()) {
(*update_records_).erase(params[DatabaseAccessor::DEL_NAME]);
domains.erase(params[DatabaseAccessor::DEL_NAME]);
}
}
public:
virtual void deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
deleteRecord(*update_records_, params);
}
virtual void deleteRecordInNSEC3Zone(
const string (&params)[DEL_PARAM_COUNT])
{
deleteRecord(*update_nsec3_namespace_, params);
}
//
// Helper methods to keep track of some update related activities
//
......@@ -2761,6 +2777,8 @@ textToRRset(const string& text_rrset, const RRClass& rrclass = RRClass::IN()) {
const char* const nsec3_hash = "1BB7SO0452U1QHL98UISNDD9218GELR5";
const char* const nsec3_rdata = "1 1 12 AABBCCDD "
"2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA RRSIG NSEC3PARAM";
const char* const nsec3_rdata2 = "1 1 12 AABBCCDD "
"2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA RRSIG"; // differ in bitmaps
const char* const nsec3_sig_rdata = "NSEC3 5 3 3600 20000101000000 "
"20000201000000 12345 example.org. FAKEFAKEFAKE";
......@@ -2829,6 +2847,27 @@ TEST_F(MockDatabaseClientTest, addNSEC3AndRRSIGToZone) {
*this->current_accessor_);
}
TEST_F(MockDatabaseClientTest, deleteNSEC3InZone) {
// Add one NSEC3 RR to the zone, delete it, and add another one.
this->updater_ = this->client_->getUpdater(this->zname_, true);
ConstRRsetPtr nsec3_rrset =
textToRRset(string(nsec3_hash) + ".example.org. 3600 IN NSEC3 " +
string(nsec3_rdata));
ConstRRsetPtr nsec3_rrset2 =
textToRRset(string(nsec3_hash) + ".example.org. 3600 IN NSEC3 " +
string(nsec3_rdata2));
this->updater_->addRRset(*nsec3_rrset);
this->updater_->deleteRRset(*nsec3_rrset);
this->updater_->addRRset(*nsec3_rrset2);
this->updater_->commit();
// Check if we can get the expected record.
vector<ConstRRsetPtr> expected_rrsets;
expected_rrsets.push_back(nsec3_rrset2);
nsec3Check(expected_rrsets, this->zname_, nsec3_hash,
*this->current_accessor_);
}
TYPED_TEST(DatabaseClientTest, addRRsetToCurrentZone) {
// Similar to the previous test, but not replacing the existing data.
boost::shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
......
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