Browse Source

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

updated DatabaseUpdater::deleteRRset so it would use the new method when
deleting NSEC3.
JINMEI Tatuya 13 years ago
parent
commit
ffbfe8fb29

+ 15 - 12
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);
+        }
     }
 }
 

+ 3 - 0
src/lib/datasrc/database.h

@@ -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

+ 7 - 0
src/lib/datasrc/sqlite3_accessor.cc

@@ -1139,6 +1139,13 @@ SQLite3Accessor::deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
 }
 
 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,
                                const std::string (&params)[DIFF_PARAM_COUNT])

+ 3 - 0
src/lib/datasrc/sqlite3_accessor.h

@@ -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.

+ 42 - 3
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 (&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());