BIND 10 trac1329, updated. 0ea04c4bb216cc822be49626d4b0269956fd070e [1329] a snapshot push: including diffs table schema and initial code for adding diffs.

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Nov 3 16:44:10 UTC 2011


The branch, trac1329 has been updated
       via  0ea04c4bb216cc822be49626d4b0269956fd070e (commit)
      from  09e4d880b9e7260caf6b5ec763aa1e0712531657 (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 0ea04c4bb216cc822be49626d4b0269956fd070e
Author: JINMEI Tatuya <jinmei at isc.org>
Date:   Thu Nov 3 09:43:28 2011 -0700

    [1329] a snapshot push: including diffs table schema and initial code for
    adding diffs.

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

Summary of changes:
 src/lib/datasrc/database.h                         |   22 ++++++
 src/lib/datasrc/sqlite3_accessor.cc                |   74 +++++++++++++++++++-
 src/lib/datasrc/sqlite3_accessor.h                 |    8 ++
 src/lib/datasrc/tests/database_unittest.cc         |    2 +
 src/lib/datasrc/tests/sqlite3_accessor_unittest.cc |   66 +++++++++++++++++-
 src/lib/datasrc/tests/testdata/test.sqlite3        |  Bin 43008 -> 44032 bytes
 6 files changed, 167 insertions(+), 5 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index d80a4ab..3b1822f 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -113,6 +113,20 @@ public:
         DEL_PARAM_COUNT = 3 ///< Number of parameters
     };
 
+    /// TBD
+    enum DiffOperation {
+        DIFF_ADD = 0,
+        DIFF_DELETE = 1
+    };
+
+    enum DiffRecordParams {
+        DIFF_NAME = 0,
+        DIFF_TYPE = 1,
+        DIFF_TTL = 2,
+        DIFF_RDATA = 3,
+        DIFF_PARAM_COUNT = 4
+    };
+
     /**
      * \brief Destructor
      *
@@ -453,6 +467,14 @@ public:
     /// to the method or internal database error.
     virtual void rollback() = 0;
 
+    /// TBD
+    /// Must be in a transaction.  (should that be started by startUpdateZone,
+    /// or can that be any transaction? => probably yes in future, so include
+    /// zone_id in param, but for now assume using it with startUpdateZone)
+    virtual void addRecordDiff(
+        int zone_id, uint32_t serial, DiffOperation operation,
+        const std::string (&params)[DIFF_PARAM_COUNT]) = 0;
+
     /// Clone the accessor with the same configuration.
     ///
     /// Each derived class implementation of this method will create a new
diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc
index cf1593a..48d4ef1 100644
--- a/src/lib/datasrc/sqlite3_accessor.cc
+++ b/src/lib/datasrc/sqlite3_accessor.cc
@@ -52,7 +52,9 @@ enum StatementID {
     DEL_RECORD = 8,
     ITERATE = 9,
     FIND_PREVIOUS = 10,
-    NUM_STATEMENTS = 11
+    ADD_RECORD_DIFF = 11,
+    GET_RECORD_DIFF = 12,       // This is temporary for testing "add diff"
+    NUM_STATEMENTS = 13
 };
 
 const char* const text_statements[NUM_STATEMENTS] = {
@@ -81,7 +83,12 @@ const char* const text_statements[NUM_STATEMENTS] = {
      */
     "SELECT name FROM records " // FIND_PREVIOUS
     "WHERE zone_id=?1 AND rdtype = 'NSEC' AND "
-    "rname < $2 ORDER BY rname DESC LIMIT 1"
+    "rname < $2 ORDER BY rname DESC LIMIT 1",
+    "INSERT INTO diffs "        // ADD_RECORD_DIFF
+    "(zone_id, version, operation, name, rrtype, ttl, rdata) "
+    "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"
+    , "SELECT name, rrtype, ttl, rdata, version, operation " // GET_RECORD_DIFF
+    "FROM diffs WHERE zone_id = ?1 ORDER BY id, operation"
 };
 
 struct SQLite3Parameters {
@@ -206,6 +213,11 @@ const char* const SCHEMA_LIST[] = {
     "ttl INTEGER NOT NULL, rdtype STRING NOT NULL COLLATE NOCASE, "
     "rdata STRING NOT NULL)",
     "CREATE INDEX nsec3_byhash ON nsec3 (hash)",
+    "CREATE TABLE diffs (id INTEGER PRIMARY KEY, "
+    "zone_id INTEGER NOT NULL, version INTEGER NOT NULL, "
+    "operation INTEGER NOT NULL, name STRING NOT NULL COLLATE NOCASE, "
+    "rrtype STRING NOT NULL COLLATE NOCASE, ttl INTEGER NOT NULL, "
+    "rdata STRING NOT NULL)",
     NULL
 };
 
@@ -214,7 +226,7 @@ prepare(sqlite3* const db, const char* const statement) {
     sqlite3_stmt* prepared = NULL;
     if (sqlite3_prepare_v2(db, statement, -1, &prepared, NULL) != SQLITE_OK) {
         isc_throw(SQLite3Error, "Could not prepare SQLite statement: " <<
-                  statement);
+                  statement << ": " << sqlite3_errmsg(db));
     }
     return (prepared);
 }
@@ -681,6 +693,62 @@ SQLite3Accessor::deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
         *dbparameters_, DEL_RECORD, params, "delete record from zone");
 }
 
+void
+SQLite3Accessor::addRecordDiff(int zone_id, uint32_t serial,
+                               DiffOperation operation,
+                               const std::string (&params)[DIFF_PARAM_COUNT])
+{
+    // TBD condition check
+
+    sqlite3_stmt* const stmt = dbparameters_->statements_[ADD_RECORD_DIFF];
+    StatementProcessor executer(*dbparameters_, ADD_RECORD_DIFF,
+                                "add record diff");
+    int param_id = 0;
+    if (sqlite3_bind_int(stmt, ++param_id, zone_id)
+        != SQLITE_OK) {
+        isc_throw(DataSourceError, "failed to bind SQLite3 parameter: " <<
+                  sqlite3_errmsg(dbparameters_->db_));
+    }
+    if (sqlite3_bind_int64(stmt, ++param_id, serial)
+        != SQLITE_OK) {
+        isc_throw(DataSourceError, "failed to bind SQLite3 parameter: " <<
+                  sqlite3_errmsg(dbparameters_->db_));
+    }
+    if (sqlite3_bind_int(stmt, ++param_id, operation)
+        != SQLITE_OK) {
+        isc_throw(DataSourceError, "failed to bind SQLite3 parameter: " <<
+                  sqlite3_errmsg(dbparameters_->db_));
+    }
+    for (int i = 0; i < DIFF_PARAM_COUNT; ++i) {
+        if (sqlite3_bind_text(stmt, ++param_id, params[i].c_str(),
+                              -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+            isc_throw(DataSourceError, "failed to bind SQLite3 parameter: " <<
+                      sqlite3_errmsg(dbparameters_->db_));
+        }
+    }
+    executer.exec();
+}
+
+vector<vector<string> >
+SQLite3Accessor::getRecordDiff(int zone_id) {
+    sqlite3_stmt* const stmt = dbparameters_->statements_[GET_RECORD_DIFF];
+    sqlite3_bind_int(stmt, 1, zone_id);
+
+    vector<vector<string> > result;
+    while (sqlite3_step(stmt) == SQLITE_ROW) {
+        vector<string> row_result;
+        for (int i = 0; i < 6; ++i) {
+            row_result.push_back(convertToPlainChar(sqlite3_column_text(stmt,
+                                                                        i),
+                                                    dbparameters_->db_));
+        }
+        result.push_back(row_result);
+    }
+    sqlite3_reset(stmt);
+
+    return (result);
+}
+
 std::string
 SQLite3Accessor::findPreviousName(int zone_id, const std::string& rname)
     const
diff --git a/src/lib/datasrc/sqlite3_accessor.h b/src/lib/datasrc/sqlite3_accessor.h
index 3d1c85d..5f51e17 100644
--- a/src/lib/datasrc/sqlite3_accessor.h
+++ b/src/lib/datasrc/sqlite3_accessor.h
@@ -157,6 +157,14 @@ public:
     virtual void deleteRecordInZone(
         const std::string (&params)[DEL_PARAM_COUNT]);
 
+    virtual void addRecordDiff(
+        int zone_id, uint32_t serial, DiffOperation operation,
+        const std::string (&params)[DIFF_PARAM_COUNT]);
+
+    // A short term method for tests until we implement more complete
+    // API to retrieve diffs.
+    std::vector<std::vector<std::string> > getRecordDiff(int zone_id);
+
     /// The SQLite3 implementation of this method returns a string starting
     /// with a fixed prefix of "sqlite3_" followed by the DB file name
     /// removing any path name.  For example, for the DB file
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index 9775321..99d6667 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -233,6 +233,8 @@ public:
     virtual void rollback() {}
     virtual void addRecordToZone(const string (&)[ADD_COLUMN_COUNT]) {}
     virtual void deleteRecordInZone(const string (&)[DEL_PARAM_COUNT]) {}
+    virtual void addRecordDiff(int, uint32_t, DiffOperation,
+                               const std::string (&)[DIFF_PARAM_COUNT]) {}
 
     virtual const std::string& getDBName() const {
         return (database_name_);
diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
index 5d66737..03f7480 100644
--- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
@@ -22,6 +22,7 @@
 #include <dns/rrclass.h>
 
 #include <gtest/gtest.h>
+#include <boost/lexical_cast.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <fstream>
 #include <sqlite3.h>
@@ -29,6 +30,7 @@
 using namespace std;
 using namespace isc::datasrc;
 using boost::shared_ptr;
+using boost::lexical_cast;
 using isc::data::ConstElementPtr;
 using isc::data::Element;
 using isc::dns::RRClass;
@@ -214,8 +216,7 @@ TEST(SQLite3Open, getDBNameExampleROOT) {
     EXPECT_EQ(SQLITE_DBNAME_EXAMPLE_ROOT, accessor.getDBName());
 }
 
-// Simple function to cound the number of records for
-// any name
+// Simple function to match records
 void
 checkRecordRow(const std::string columns[],
                const std::string& field0,
@@ -518,6 +519,7 @@ protected:
     std::string get_columns[DatabaseAccessor::COLUMN_COUNT];
     std::string add_columns[DatabaseAccessor::ADD_COLUMN_COUNT];
     std::string del_params[DatabaseAccessor::DEL_PARAM_COUNT];
+    std::string diff_params[DatabaseAccessor::DIFF_PARAM_COUNT];
 
     vector<const char* const*> expected_stored; // placeholder for checkRecords
     vector<const char* const*> empty_stored; // indicate no corresponding data
@@ -844,4 +846,64 @@ TEST_F(SQLite3Update, concurrentTransactions) {
     accessor->commit();
     another_accessor->commit();
 }
+
+//
+// Commonly(?) used data for diff related tests.  The last entry is
+// a textual representation of "version".
+//
+const char* const DIFF_ADD_TEXT = "0";
+const char* const DIFF_DELETE_TEXT = "1";
+const char* const diff_begin_data[] = {
+    "example.com.", "SOA", "3600",
+    "ns.example.com. admin.example.com. 1234 3600 1800 2419200 7200",
+    "1234", DIFF_DELETE_TEXT
+};
+const char* const diff_end_data[] = {
+    "example.com.", "SOA", "3600",
+    "ns.example.com. admin.example.com. 1300 3600 1800 2419200 7200",
+    "1300", DIFF_ADD_TEXT
+};
+
+DatabaseAccessor::DiffOperation
+textToOp(const char* const text_op) {
+    return (static_cast<DatabaseAccessor::DiffOperation>(
+                lexical_cast<int>(text_op)));
+                
+}
+
+TEST_F(SQLite3Update, addRecordDiff) {
+    uint32_t version;
+    DatabaseAccessor::DiffOperation operation;
+    zone_id = accessor->startUpdateZone("example.com.", false).second;
+
+    copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
+         diff_params);
+    version = lexical_cast<uint32_t>(
+        diff_begin_data[DatabaseAccessor::DIFF_PARAM_COUNT]);
+    operation =
+        textToOp(diff_begin_data[DatabaseAccessor::DIFF_PARAM_COUNT + 1]);
+    accessor->addRecordDiff(zone_id, version, operation, diff_params);
+
+    copy(diff_end_data, diff_end_data + DatabaseAccessor::DIFF_PARAM_COUNT,
+         diff_params);
+    version = lexical_cast<uint32_t>(
+        diff_end_data[DatabaseAccessor::DIFF_PARAM_COUNT]);
+    operation =
+        textToOp(diff_end_data[DatabaseAccessor::DIFF_PARAM_COUNT + 1]);
+    accessor->addRecordDiff(zone_id, version, operation, diff_params); 
+
+    accessor->commit();
+
+    vector<vector<string> > committed_diffs = accessor->getRecordDiff(zone_id);
+    expected_stored.clear();
+    expected_stored.push_back(diff_begin_data);
+    expected_stored.push_back(diff_end_data);
+    vector<vector<string> >::const_iterator it;
+    vector<const char* const*>::const_iterator eit = expected_stored.begin();
+    for (it = committed_diffs.begin(); it != committed_diffs.end(); ++it, ++eit) {
+        for (int i = 0; i < (*it).size(); ++i) {
+            EXPECT_EQ((*eit)[i], (*it)[i]);
+        }
+    }
+}
 } // end anonymous namespace
diff --git a/src/lib/datasrc/tests/testdata/test.sqlite3 b/src/lib/datasrc/tests/testdata/test.sqlite3
index cc8cfc3..521cf31 100644
Binary files a/src/lib/datasrc/tests/testdata/test.sqlite3 and b/src/lib/datasrc/tests/testdata/test.sqlite3 differ




More information about the bind10-changes mailing list