Browse Source

[1177] The findPreviousName

But only if the underlying DB supports it. The SQLite3 one needs to be
still implemented.
Michal 'vorner' Vaner 13 years ago
parent
commit
38af8a4225

+ 2 - 2
src/lib/datasrc/database.cc

@@ -565,8 +565,8 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
 }
 
 Name
-DatabaseClient::Finder::findPreviousName(const Name&) const {
-    return (Name::ROOT_NAME()); // TODO Implement
+DatabaseClient::Finder::findPreviousName(const Name& name) const {
+    return (Name(accessor_->findPreviousName(zone_id_, name.toText())));
 }
 
 Name

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

@@ -474,6 +474,22 @@ public:
      * \return the name of the database
      */
     virtual const std::string& getDBName() const = 0;
+
+    /**
+     * \brief It returns the previous name in DNSSEC/NSEC order.
+     *
+     * This is used in DatabaseClient::findPreviousName and does more
+     * or less the real work, except for working on strings.
+     *
+     * \param name The name to ask for previous of.
+     * \param zone_id The zone to look through.
+     * \return The previous name.
+     *
+     * \throw DataSourceError if there's a problem with the database.
+     * \throw NotImplemented if this database doesn't support DNSSEC.
+     */
+    virtual std::string findPreviousName(int zone_id,
+                                         const std::string& name) const = 0;
 };
 
 /**

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

@@ -658,5 +658,10 @@ SQLite3Accessor::deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
         *dbparameters_, DEL_RECORD, params, "delete record from zone");
 }
 
+std::string
+SQLite3Accessor::findPreviousName(int , const std::string&) const {
+    return ("."); // TODO Test and implement
+}
+
 }
 }

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

@@ -170,6 +170,10 @@ public:
     /// "sqlite3_bind10.sqlite3".
     virtual const std::string& getDBName() const { return (database_name_); }
 
+    /// \brief Concrete implementation of the pure virtual method
+    virtual std::string findPreviousName(int zone_id, const std::string& name)
+        const;
+
 private:
     /// \brief Private database data
     boost::scoped_ptr<SQLite3Parameters> dbparameters_;

+ 31 - 0
src/lib/datasrc/tests/database_unittest.cc

@@ -229,6 +229,10 @@ public:
                   "This database datasource can't be iterated");
     }
 
+    virtual std::string findPreviousName(int, const std::string&) const {
+        isc_throw(isc::NotImplemented,
+                  "This data source doesn't support DNSSEC");
+    }
 private:
     const std::string database_name_;
 
@@ -535,6 +539,26 @@ public:
         return (latest_clone_);
     }
 
+    virtual std::string findPreviousName(int id, const std::string& name)
+        const
+    {
+        // Hardcoded for now, but we could compute it from the data
+        // Maybe do it when it is needed some time in future?
+        if (id == -1) {
+            isc_throw(isc::NotImplemented, "Test not implemented behaviour");
+        } else if (id == 42) {
+            if (name == "example.org.") {
+                return ("zzz.example.org.");
+            } else if (name == "www2.example.org.") {
+                return ("www.example.org.");
+            } else {
+                isc_throw(isc::Unexpected, "Unexpected name");
+            }
+        } else {
+            isc_throw(isc::Unexpected, "Unknown zone ID");
+        }
+    }
+
 private:
     // The following member variables are storage and/or update work space
     // of the test zone.  The "master"s are the real objects that contain
@@ -2204,6 +2228,13 @@ TYPED_TEST(DatabaseClientTest, previous) {
     // Check wrap around
     EXPECT_EQ(Name("zzz.example.org."),
               finder->findPreviousName(Name("example.org.")));
+    // Check it doesn't crash or anything if the underlying DB throws
+    DataSourceClient::FindResult
+        zone(this->client_->findZone(Name("bad.example.org")));
+    finder = dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder);
+
+    EXPECT_THROW(finder->findPreviousName(Name("bad.example.org")),
+                 isc::NotImplemented);
 }
 
 }

+ 2 - 2
src/lib/datasrc/zone.h

@@ -211,8 +211,8 @@ public:
 
     /// \brief Get previous name in the zone
     ///
-    /// Gets the previous name in the DNSSEC order. This can be used
-    /// to find the correct NSEC or NSEC3 records for proving nonexistenc
+    /// Gets the previous name in the DNSSEC/NSEC order. This can be used
+    /// to find the correct NSEC records for proving nonexistenc
     /// of domains.
     ///
     /// The concrete implementation might throw anything it thinks appropriate,