Michal 'vorner' Vaner 13 years ago
parent
commit
36efa7d10e

+ 13 - 2
src/lib/datasrc/sqlite3_accessor.cc

@@ -93,8 +93,19 @@ const char* const text_statements[NUM_STATEMENTS] = {
         "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
     "DELETE FROM records WHERE zone_id=?1 AND name=?2 " // DEL_RECORD
         "AND rdtype=?3 AND rdata=?4",
-    "SELECT rdtype, ttl, sigtype, rdata, name FROM records " // ITERATE
-        "WHERE zone_id = ?1 ORDER BY rname, rdtype",
+    // The following iterates the whole zone. As the NSEC3 records
+    // (and corresponding RRSIGs) live in separate table, we need to
+    // take both of them. As the RRSIGs are for NSEC3s in the other
+    // table, we can easily hardcode the sigtype.
+    //
+    // The extra column is so we can order it by rname. This is to
+    // preserve the previous order, mostly for tests.
+    // TODO: Is it possible to get rid of the ordering?
+    "SELECT rdtype, ttl, sigtype, rdata, name, rname FROM records " // ITERATE
+        "WHERE zone_id = ?1 "
+        "UNION "
+        "SELECT rdtype, ttl, \"NSEC3\", rdata, owner, owner FROM nsec3 "
+        "WHERE zone_id = ?1 ORDER by rname, rdtype",
     /*
      * This one looks for previous name with NSEC record. It is done by
      * using the reversed name. The NSEC is checked because we need to

+ 43 - 0
src/lib/datasrc/tests/sqlite3_accessor_unittest.cc

@@ -194,6 +194,49 @@ TEST_F(SQLite3AccessorTest, iterator) {
     EXPECT_FALSE(context->getNext(data));
 }
 
+// This tests the iterator through the whole zone returns NSEC3 records as
+// well. We test this specifically, as it lives in separate table and needs
+// extra handling.
+TEST_F(SQLite3AccessorTest, nsec3Iterator) {
+    // Get the zone
+    const std::pair<bool, int>
+        zone_info(accessor->getZone("sql2.example.com."));
+    ASSERT_TRUE(zone_info.first);
+
+    // Iterate through it
+    DatabaseAccessor::IteratorContextPtr
+        context(accessor->getAllRecords(zone_info.second));
+
+    // We just pick a random NSEC3 to check, the check of complete iterator
+    // is in the above test. In addition, we count the number of NSEC3, RRSIG
+    // and all records, as some kind of check it returns all the data.
+    std::string data[DatabaseAccessor::COLUMN_COUNT];
+
+    size_t nsec3count(0), rrsigcount(0), recordcount(0);
+    bool nsec3match(false);
+    while (context->getNext(data)) {
+        if (data[DatabaseAccessor::TYPE_COLUMN] == "NSEC3") {
+            nsec3count ++;
+            if (data[DatabaseAccessor::NAME_COLUMN] ==
+                "1BB7SO0452U1QHL98UISNDD9218GELR5.sql2.example.com.") {
+                nsec3match = true;
+                EXPECT_EQ("7200", data[DatabaseAccessor::TTL_COLUMN]);
+                EXPECT_EQ("1 0 10 FEEDABEE 4KLSVDE8KH8G95VU68R7AHBE1CPQN38J",
+                          data[DatabaseAccessor::RDATA_COLUMN]);
+            }
+        } else if (data[DatabaseAccessor::TYPE_COLUMN] == "RRSIG") {
+            rrsigcount ++;
+        }
+        recordcount ++;
+    }
+
+    // We counted everything now, so check there's nothing else to count
+    EXPECT_EQ(11, nsec3count);
+    EXPECT_EQ(22, rrsigcount);
+    EXPECT_EQ(46, recordcount);
+    EXPECT_TRUE(nsec3match) << "No NSEC3 found when iterating the zone";
+}
+
 // This tests getting NSEC3 records
 TEST_F(SQLite3AccessorTest, nsec3) {
     const std::pair<bool, int>