From: JINMEI Tatuya Date: Sat, 14 Apr 2012 00:33:35 +0000 (-0700) Subject: [1781] introduced deleteRecordInNSEC3Zone DB accessor method for del'ing NSEC3. X-Git-Tag: trac2351_base~226^2~116^2~26^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ffbfe8fb2978b60c8309b3d7b7d006c98778b304;p=thirdparty%2Fkea.git [1781] introduced deleteRecordInNSEC3Zone DB accessor method for del'ing NSEC3. updated DatabaseUpdater::deleteRRset so it would use the new method when deleting NSEC3. --- diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 4f9ee307b4..2c395fea8c 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -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); + } } } diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index 47206be0e8..b760f04948 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -482,6 +482,9 @@ public: virtual void deleteRecordInZone( const std::string (¶ms)[DEL_PARAM_COUNT]) = 0; + virtual void deleteRecordInNSEC3Zone( + const std::string (¶ms)[DEL_PARAM_COUNT]) = 0; + /// \brief Start a general transaction. /// /// Each derived class version of this method starts a database diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc index 929010520d..96e964e3dc 100644 --- a/src/lib/datasrc/sqlite3_accessor.cc +++ b/src/lib/datasrc/sqlite3_accessor.cc @@ -1138,6 +1138,13 @@ SQLite3Accessor::deleteRecordInZone(const string (¶ms)[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, diff --git a/src/lib/datasrc/sqlite3_accessor.h b/src/lib/datasrc/sqlite3_accessor.h index bb93a1d15b..cf9f394e8a 100644 --- a/src/lib/datasrc/sqlite3_accessor.h +++ b/src/lib/datasrc/sqlite3_accessor.h @@ -220,6 +220,9 @@ public: virtual void deleteRecordInZone( const std::string (¶ms)[DEL_PARAM_COUNT]); + virtual void deleteRecordInNSEC3Zone( + const std::string (¶ms)[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. diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc index 99545f56df..ee68686c94 100644 --- a/src/lib/datasrc/tests/database_unittest.cc +++ b/src/lib/datasrc/tests/database_unittest.cc @@ -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 (¶ms)[DEL_PARAM_COUNT]) { + // Common subroutine for deleteRecordinZone and deleteRecordInNSEC3Zone. + void deleteRecord(Domains& domains, + const string (¶ms)[DEL_PARAM_COUNT]) + { vector >& 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 (¶ms)[DEL_PARAM_COUNT]) { + deleteRecord(*update_records_, params); + } + + virtual void deleteRecordInNSEC3Zone( + const string (¶ms)[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 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 finder(this->getFinder());