BIND 10 trac1183, updated. 6318db7dc90cb6656cc2a1f8e875f2258f6a4343 [1183] address review comments for tests

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Aug 19 14:20:40 UTC 2011


The branch, trac1183 has been updated
       via  6318db7dc90cb6656cc2a1f8e875f2258f6a4343 (commit)
       via  35a0136d56de7faca280666ba40bb1b87a85fff6 (commit)
       via  b97162729a3ad4214e5f6b85452a27904b8f34ca (commit)
      from  954143a2748110c720d28df49159ed4f0bc1a1a2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6318db7dc90cb6656cc2a1f8e875f2258f6a4343
Author: Jelte Jansen <jelte at isc.org>
Date:   Fri Aug 19 16:20:00 2011 +0200

    [1183] address review comments for tests

commit 35a0136d56de7faca280666ba40bb1b87a85fff6
Author: Jelte Jansen <jelte at isc.org>
Date:   Fri Aug 19 15:09:47 2011 +0200

    [1183] review comments on implementation

commit b97162729a3ad4214e5f6b85452a27904b8f34ca
Author: Jelte Jansen <jelte at isc.org>
Date:   Fri Aug 19 12:02:28 2011 +0200

    [1183] make name arg of getRecords std::string

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/database.cc                        |    2 +-
 src/lib/datasrc/database.h                         |  113 ++++++++------------
 src/lib/datasrc/sqlite3_accessor.cc                |   84 ++++++++-------
 src/lib/datasrc/sqlite3_accessor.h                 |    2 +-
 src/lib/datasrc/tests/database_unittest.cc         |   23 +++--
 src/lib/datasrc/tests/sqlite3_accessor_unittest.cc |  114 ++++++++++++++------
 6 files changed, 187 insertions(+), 151 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index c6f4c11..f0ac192 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -183,7 +183,7 @@ DatabaseClient::Finder::getRRset(const isc::dns::Name& name,
 
     // Request the context
     DatabaseAccessor::IteratorContextPtr
-        context(database_->getRecords(name, zone_id_));
+        context(database_->getRecords(name.toText(), zone_id_));
     // It must not return NULL, that's a bug of the implementation
     if (!context) {
         isc_throw(isc::Unexpected, "Iterator context null at " +
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index 6856859..95c1c5a 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -48,8 +48,27 @@ namespace datasrc {
  */
 class DatabaseAccessor : boost::noncopyable {
 public:
-    /// The number of fields the columns array passed to getNext should have
-    static const size_t COLUMN_COUNT = 5;
+    /**
+     * Definitions of the fields as they are required to be filled in
+     * by IteratorContext::getNext()
+     *
+     * When implementing getNext(), the columns array should
+     * be filled with the values as described in this enumeration,
+     * in this order, i.e. TYPE_COLUMN should be the first element
+     * (index 0) of the array, TTL_COLUMN should be the second element
+     * (index 1), etc.
+     */
+    enum RecordColumns {
+        TYPE_COLUMN = 0,    ///< The RRType of the record (A/NS/TXT etc.)
+        TTL_COLUMN = 1,     ///< The TTL of the record (a
+        SIGTYPE_COLUMN = 2, ///< For RRSIG records, this contains the RRTYPE
+                            ///< the RRSIG covers. In the current implementation,
+                            ///< this field is ignored.
+        RDATA_COLUMN = 3,   ///< Full text representation of the record's RDATA
+        NAME_COLUMN = 4,    ///< The domain name of this RR
+        COLUMN_COUNT = 5    ///< The total number of columns, MUST be value of
+                            ///< the largest other element in this enum plus 1.
+    };
 
     /**
      * \brief Destructor
@@ -110,9 +129,10 @@ public:
          *
          * Depending on how the iterator was constructed, there is a difference
          * in behaviour; for a 'full zone iterator', created with
-         * getAllRecords(), all 5 elements of the array are overwritten.
-         * For a 'name iterator', created with getRecords(), the fifth column
-         * (NAME_COLUMN) is untouched, since what would be added here is by
+         * getAllRecords(), all COLUMN_COUNT elements of the array are
+         * overwritten.
+         * For a 'name iterator', created with getRecords(), the column
+         * NAME_COLUMN is untouched, since what would be added here is by
          * definition already known to the caller (it already passes it as
          * an argument to getRecords()).
          *
@@ -137,87 +157,40 @@ public:
     /**
      * \brief Creates an iterator context for a specific name.
      *
-     * This should create a new iterator context to be used by
-     * DatabaseAccessor's ZoneIterator. It can be created based on the name
-     * or the ID (returned from getZone()), what is more comfortable for the
-     * database implementation. Both are provided (and are guaranteed to match,
-     * the DatabaseClient first looks up the zone ID and then calls this).
-     *
-     * The default implementation throws isc::NotImplemented, to allow
-     * "minimal" implementations of the connection not supporting optional
-     * functionality.
+     * Returns an IteratorContextPtr that contains all records of the
+     * given name from the given zone.
      *
      * The implementation of the iterator that is returned may leave the
-     * fifth column of the array passed to getNext() untouched, as that
+     * NAME_COLUMN column of the array passed to getNext() untouched, as that
      * data is already known (it is the same as the name argument here)
      *
-     * \param name The name to search for.
+     * \exception any Since any implementation can be used, the caller should
+     *            expect any exception to be thrown.
+     *
+     * \param name The name to search for. This should be a FQDN.
      * \param id The ID of the zone, returned from getZone().
      * \return Newly created iterator context. Must not be NULL.
      */
-    virtual IteratorContextPtr getRecords(const isc::dns::Name& name,
-                                          int id) const
-    {
-        /*
-         * This is a compromise. We need to document the parameters in doxygen,
-         * so they need a name, but then it complains about unused parameter.
-         * This is a NOP that "uses" the parameters.
-         */
-        static_cast<void>(name);
-        static_cast<void>(id);
-
-        isc_throw(isc::NotImplemented,
-                  "This database datasource can't be iterated");
-    }
+    virtual IteratorContextPtr getRecords(const std::string& name,
+                                          int id) const = 0;
 
     /**
      * \brief Creates an iterator context for the whole zone.
      *
-     * This should create a new iterator context to be used by
-     * DatabaseAccessor's ZoneIterator. It can be created based on the name
-     * or the ID (returned from getZone()), what is more comfortable for the
-     * database implementation. Both are provided (and are guaranteed to match,
-     * the DatabaseClient first looks up the zone ID and then calls this).
+     * Returns an IteratorContextPtr that contains all records of the
+     * zone with the given zone id.
      *
-     * The default implementation throws isc::NotImplemented, to allow
-     * "minimal" implementations of the connection not supporting optional
-     * functionality.
+     * Each call to getNext() on the returned iterator should copy all
+     * column fields of the array that is passed, as defined in the
+     * RecordColumns enum.
+     *
+     * \exception any Since any implementation can be used, the caller should
+     *            expect any exception to be thrown.
      *
      * \param id The ID of the zone, returned from getZone().
      * \return Newly created iterator context. Must not be NULL.
      */
-    virtual IteratorContextPtr getAllRecords(int id) const
-    {
-        /*
-         * This is a compromise. We need to document the parameters in doxygen,
-         * so they need a name, but then it complains about unused parameter.
-         * This is a NOP that "uses" the parameters.
-         */
-        static_cast<void>(id);
-
-        isc_throw(isc::NotImplemented,
-                  "This database datasource can't be iterated");
-    }
-
-    /**
-     * Definitions of the fields as they are required to be filled in
-     * by IteratorContext::getNext()
-     *
-     * When implementing getNext(), the columns array should
-     * be filled with the values as described in this enumeration,
-     * in this order, i.e. TYPE_COLUMN should be the first element
-     * (index 0) of the array, TTL_COLUMN should be the second element
-     * (index 1), etc.
-     */
-    enum RecordColumns {
-        TYPE_COLUMN = 0,    ///< The RRType of the record (A/NS/TXT etc.)
-        TTL_COLUMN = 1,     ///< The TTL of the record (a
-        SIGTYPE_COLUMN = 2, ///< For RRSIG records, this contains the RRTYPE
-                            ///< the RRSIG covers. In the current implementation,
-                            ///< this field is ignored.
-        RDATA_COLUMN = 3,   ///< Full text representation of the record's RDATA
-        NAME_COLUMN = 4     ///< The domain name of this RR
-    };
+    virtual IteratorContextPtr getAllRecords(int id) const = 0;
 
     /**
      * \brief Returns a string identifying this dabase backend
diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc
index 070c6c5..86487ae 100644
--- a/src/lib/datasrc/sqlite3_accessor.cc
+++ b/src/lib/datasrc/sqlite3_accessor.cc
@@ -336,34 +336,6 @@ SQLite3Database::getZone(const isc::dns::Name& name) const {
     return (std::pair<bool, int>(false, 0));
 }
 
-namespace {
-// This helper function converts from the unsigned char* type (used by
-// sqlite3) to char* (wanted by std::string). Technically these types
-// might not be directly convertable
-// In case sqlite3_column_text() returns NULL, we just make it an
-// empty string.
-// The sqlite3parameters value is only used to check the error code if
-// ucp == NULL
-const char*
-convertToPlainChar(const unsigned char* ucp,
-                   SQLite3Parameters* dbparameters) {
-    if (ucp == NULL) {
-        // The field can really be NULL, in which case we return an
-        // empty string, or sqlite may have run out of memory, in
-        // which case we raise an error
-        if (dbparameters != NULL &&
-            sqlite3_errcode(dbparameters->db_) == SQLITE_NOMEM) {
-            isc_throw(DataSourceError,
-                      "Sqlite3 backend encountered a memory allocation "
-                      "error in sqlite3_column_text()");
-        } else {
-            return ("");
-        }
-    }
-    const void* p = ucp;
-    return (static_cast<const char*>(p));
-}
-}
 
 class SQLite3Database::Context : public DatabaseAccessor::IteratorContext {
 public:
@@ -372,7 +344,8 @@ public:
     Context(const boost::shared_ptr<const SQLite3Database>& database, int id) :
         iterator_type_(ITT_ALL),
         database_(database),
-        statement_(NULL)
+        statement_(NULL),
+        name_("")
     {
         // We create the statement now and then just keep getting data from it
         statement_ = prepare(database->dbparameters_->db_, q_iterate_str);
@@ -382,15 +355,16 @@ public:
     // Construct an iterator for records with a specific name. When constructed
     // this way, the getNext() call will copy all fields except name
     Context(const boost::shared_ptr<const SQLite3Database>& database, int id,
-            const isc::dns::Name& name) :
+            const std::string& name) :
         iterator_type_(ITT_NAME),
         database_(database),
-        statement_(NULL)
+        statement_(NULL),
+        name_(name)
     {
         // We create the statement now and then just keep getting data from it
         statement_ = prepare(database->dbparameters_->db_, q_any_str);
         bindZoneId(id);
-        bindName(name);
+        bindName(name_);
     }
 
     bool getNext(std::string (&data)[COLUMN_COUNT]) {
@@ -412,11 +386,12 @@ public:
                       "Unexpected failure in sqlite3_step: " <<
                       sqlite3_errmsg(database_->dbparameters_->db_));
         }
+        finalize();
         return (false);
     }
 
     virtual ~Context() {
-        sqlite3_finalize(statement_);
+        finalize();
     }
 
 private:
@@ -430,35 +405,64 @@ private:
 
     void copyColumn(std::string (&data)[COLUMN_COUNT], int column) {
         data[column] = convertToPlainChar(sqlite3_column_text(statement_,
-                                                              column),
-                                          database_->dbparameters_.get());
+                                                              column));
     }
 
     void bindZoneId(const int zone_id) {
         if (sqlite3_bind_int(statement_, 1, zone_id) != SQLITE_OK) {
+            finalize();
             isc_throw(SQLite3Error, "Could not bind int " << zone_id <<
                       " to SQL statement: " <<
                       sqlite3_errmsg(database_->dbparameters_->db_));
         }
     }
 
-    void bindName(const isc::dns::Name& name) {
-        if (sqlite3_bind_text(statement_, 2, name.toText().c_str(), -1,
-                              SQLITE_TRANSIENT) != SQLITE_OK) {
+    void bindName(const std::string& name) {
+        if (sqlite3_bind_text(statement_, 2, name.c_str(), -1,
+                              SQLITE_STATIC) != SQLITE_OK) {
             const char* errmsg = sqlite3_errmsg(database_->dbparameters_->db_);
-            sqlite3_finalize(statement_);
+            finalize();
             isc_throw(SQLite3Error, "Could not bind text '" << name <<
                       "' to SQL statement: " << errmsg);
         }
     }
 
+    void finalize() {
+        sqlite3_finalize(statement_);
+        statement_ = NULL;
+    }
+
+    // This helper method converts from the unsigned char* type (used by
+    // sqlite3) to char* (wanted by std::string). Technically these types
+    // might not be directly convertable
+    // In case sqlite3_column_text() returns NULL, we just make it an
+    // empty string, unless it was caused by a memory error
+    const char* convertToPlainChar(const unsigned char* ucp) {
+        if (ucp == NULL) {
+            // The field can really be NULL, in which case we return an
+            // empty string, or sqlite may have run out of memory, in
+            // which case we raise an error
+            if (sqlite3_errcode(database_->dbparameters_->db_)
+                                == SQLITE_NOMEM) {
+                isc_throw(DataSourceError,
+                        "Sqlite3 backend encountered a memory allocation "
+                        "error in sqlite3_column_text()");
+            } else {
+                return ("");
+            }
+        }
+        const void* p = ucp;
+        return (static_cast<const char*>(p));
+    }
+
     const IteratorType iterator_type_;
     boost::shared_ptr<const SQLite3Database> database_;
     sqlite3_stmt *statement_;
+    const std::string name_;
 };
 
 DatabaseAccessor::IteratorContextPtr
-SQLite3Database::getRecords(const isc::dns::Name& name, int id) const {
+SQLite3Database::getRecords(const std::string& name, int id) const {
     return (IteratorContextPtr(new Context(shared_from_this(), id, name)));
 }
 
diff --git a/src/lib/datasrc/sqlite3_accessor.h b/src/lib/datasrc/sqlite3_accessor.h
index 6737c0b..50b15e7 100644
--- a/src/lib/datasrc/sqlite3_accessor.h
+++ b/src/lib/datasrc/sqlite3_accessor.h
@@ -104,7 +104,7 @@ public:
      * \param id the zone id, as returned by getZone()
      * \return Iterator that contains all records with the given name
      */
-    virtual IteratorContextPtr getRecords(const isc::dns::Name& name,
+    virtual IteratorContextPtr getRecords(const std::string& name,
                                           int id) const;
 
     /** \brief Look up all resource records for a zone
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index f3311a8..2153f01 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -62,6 +62,15 @@ public:
         return (database_name_);
     }
 
+    virtual IteratorContextPtr getRecords(const std::string&, int) const {
+        isc_throw(isc::NotImplemented,
+                  "This database datasource can't be iterated");
+    };
+
+    virtual IteratorContextPtr getAllRecords(int) const {
+        isc_throw(isc::NotImplemented,
+                  "This database datasource can't be iterated");
+    };
 private:
     const std::string database_name_;
 
@@ -84,12 +93,12 @@ private:
     class MockNameIteratorContext : public IteratorContext {
     public:
         MockNameIteratorContext(const MockAccessor& mock_accessor, int zone_id,
-                                const isc::dns::Name& name) :
-            searched_name_(name.toText()), cur_record_(0)
+                                const std::string& name) :
+            searched_name_(name), cur_record_(0)
         {
-            // 'hardcoded' name to trigger exceptions (for testing
-            // the error handling of find() (the other on is below in
-            // if the name is "exceptiononsearch" it'll raise an exception here
+            // 'hardcoded' names to trigger exceptions
+            // On these names some exceptions are throws, to test the robustness
+            // of the find() method.
             if (searched_name_ == "dsexception.in.search.") {
                 isc_throw(DataSourceError, "datasource exception on search");
             } else if (searched_name_ == "iscexception.in.search.") {
@@ -235,7 +244,7 @@ public:
         }
     }
 
-    virtual IteratorContextPtr getRecords(const Name& name, int id) const {
+    virtual IteratorContextPtr getRecords(const std::string& name, int id) const {
         if (id == 42) {
             return (IteratorContextPtr(new MockNameIteratorContext(*this, id, name)));
         } else {
@@ -424,7 +433,7 @@ private:
 
 // This tests the default getRecords behaviour, throwing NotImplemented
 TEST(DatabaseConnectionTest, getRecords) {
-    EXPECT_THROW(NopAccessor().getRecords(Name("."), 1),
+    EXPECT_THROW(NopAccessor().getRecords(".", 1),
                  isc::NotImplemented);
 }
 
diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
index a42eaad..295bed2 100644
--- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
@@ -35,6 +35,7 @@ std::string SQLITE_DBFILE_EXAMPLE_ROOT = TEST_DATA_DIR "/test-root.sqlite3";
 std::string SQLITE_DBNAME_EXAMPLE_ROOT = "sqlite3_test-root.sqlite3";
 std::string SQLITE_DBFILE_BROKENDB = TEST_DATA_DIR "/brokendb.sqlite3";
 std::string SQLITE_DBFILE_MEMORY = ":memory:";
+std::string SQLITE_DBFILE_EXAMPLE_ORG = TEST_DATA_DIR "/example.org.sqlite3";
 
 // The following file must be non existent and must be non"creatable";
 // the sqlite3 library will try to create a new DB file if it doesn't exist,
@@ -106,39 +107,89 @@ TEST_F(SQLite3Access, noClass) {
 // This tests the iterator context
 TEST_F(SQLite3Access, iterator) {
     // Our test zone is conveniently small, but not empty
-    initAccessor(SQLITE_DBFILE_EXAMPLE2, RRClass::IN());
+    initAccessor(SQLITE_DBFILE_EXAMPLE_ORG, RRClass::IN());
+
+    const std::pair<bool, int> zone_info(db->getZone(Name("example.org")));
+    ASSERT_TRUE(zone_info.first);
 
     // Get the iterator context
     DatabaseAccessor::IteratorContextPtr
-        context(db->getAllRecords(1));
+        context(db->getAllRecords(zone_info.second));
     ASSERT_NE(DatabaseAccessor::IteratorContextPtr(),
               context);
 
-    const size_t size(5);
-    std::string data[size];
+    std::string data[DatabaseAccessor::COLUMN_COUNT];
     // Get and check the first and only record
     EXPECT_TRUE(context->getNext(data));
-    EXPECT_EQ("example2.com.", data[4]);
-    EXPECT_EQ("SOA", data[0]);
-    EXPECT_EQ("master.example2.com. admin.example2.com. "
-              "1234 3600 1800 2419200 7200", data[3]);
-    EXPECT_EQ("3600", data[1]);
-    // Check there's no other
-    EXPECT_FALSE(context->getNext(data));
-}
+    EXPECT_EQ("DNAME", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("dname.example.info.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("dname.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
 
-TEST_F(SQLite3Access, iteratorColumnCount) {
-    // Our test zone is conveniently small, but not empty
-    initAccessor(SQLITE_DBFILE_EXAMPLE2, RRClass::IN());
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("DNAME", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("dname2.example.info.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("dname2.foo.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
 
-    // Get the iterator context
-    DatabaseAccessor::IteratorContextPtr
-        context(db->getAllRecords(1));
-    ASSERT_NE(DatabaseAccessor::IteratorContextPtr(),
-              context);
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("MX", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("10 mail.example.org.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("example.org.", data[DatabaseAccessor::NAME_COLUMN]);
 
-    std::string data[DatabaseAccessor::COLUMN_COUNT];
-    EXPECT_NO_THROW(context->getNext(data));
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("NS", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("ns1.example.org.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("NS", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("ns2.example.org.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("NS", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("ns3.example.org.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("SOA", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("ns1.example.org. admin.example.org. "
+              "1234 3600 1800 2419200 7200",
+              data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("A", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("192.0.2.10", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("mail.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("A", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("192.0.2.101", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("ns.sub.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("NS", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("ns.sub.example.org.", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("sub.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    EXPECT_TRUE(context->getNext(data));
+    EXPECT_EQ("A", data[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ("3600", data[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ("192.0.2.1", data[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ("www.example.org.", data[DatabaseAccessor::NAME_COLUMN]);
+
+    // Check there's no other
+    EXPECT_FALSE(context->getNext(data));
 }
 
 TEST(SQLite3Open, getDBNameExample2) {
@@ -161,11 +212,11 @@ checkRecordRow(const std::string columns[],
                const std::string& field3,
                const std::string& field4)
 {
-    EXPECT_EQ(field0, columns[0]);
-    EXPECT_EQ(field1, columns[1]);
-    EXPECT_EQ(field2, columns[2]);
-    EXPECT_EQ(field3, columns[3]);
-    EXPECT_EQ(field4, columns[4]);
+    EXPECT_EQ(field0, columns[DatabaseAccessor::TYPE_COLUMN]);
+    EXPECT_EQ(field1, columns[DatabaseAccessor::TTL_COLUMN]);
+    EXPECT_EQ(field2, columns[DatabaseAccessor::SIGTYPE_COLUMN]);
+    EXPECT_EQ(field3, columns[DatabaseAccessor::RDATA_COLUMN]);
+    EXPECT_EQ(field4, columns[DatabaseAccessor::NAME_COLUMN]);
 }
 
 TEST_F(SQLite3Access, getRecords) {
@@ -175,18 +226,17 @@ TEST_F(SQLite3Access, getRecords) {
     const int zone_id = zone_info.second;
     ASSERT_EQ(1, zone_id);
 
-    const size_t column_count = DatabaseAccessor::COLUMN_COUNT;
-    std::string columns[column_count];
+    std::string columns[DatabaseAccessor::COLUMN_COUNT];
 
     DatabaseAccessor::IteratorContextPtr
-        context(db->getRecords(Name("foo.bar"), 1));
+        context(db->getRecords("foo.bar", 1));
     ASSERT_NE(DatabaseAccessor::IteratorContextPtr(),
               context);
     EXPECT_FALSE(context->getNext(columns));
     checkRecordRow(columns, "", "", "", "", "");
 
     // now try some real searches
-    context = db->getRecords(Name("foo.example.com."), zone_id);
+    context = db->getRecords("foo.example.com.", zone_id);
     ASSERT_TRUE(context->getNext(columns));
     checkRecordRow(columns, "CNAME", "3600", "",
                    "cnametest.example.org.", "");
@@ -207,7 +257,7 @@ TEST_F(SQLite3Access, getRecords) {
                    "NSEC 5 3 7200 20100322084538 20100220084538 33495 "
                    "example.com. FAKEFAKEFAKEFAKE", "");
 
-    context = db->getRecords(Name("example.com."), zone_id);
+    context = db->getRecords("example.com.", zone_id);
     ASSERT_TRUE(context->getNext(columns));
     checkRecordRow(columns, "SOA", "3600", "",
                    "master.example.com. admin.example.com. "




More information about the bind10-changes mailing list