BIND 10 trac1760_2, updated. abd717cfc9b0b01bfe6a5d651a2d34ffaf61d055 [1760] Use ?, not $ for parameter substitution
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Mar 19 13:54:46 UTC 2012
The branch, trac1760_2 has been updated
via abd717cfc9b0b01bfe6a5d651a2d34ffaf61d055 (commit)
via c2b8d8433c9a4ec5fb6817a104b6a6309d413f7e (commit)
via 37960ee83cb33be5cd683fb0d458343752caa01a (commit)
from 8f36290ceaae7abb6ee5b5affdf0c7bb31e5bea5 (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 abd717cfc9b0b01bfe6a5d651a2d34ffaf61d055
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Mar 19 14:41:15 2012 +0100
[1760] Use ?, not $ for parameter substitution
Unrelated cleanup.
They are equivalent, but this looks more consistent.
commit c2b8d8433c9a4ec5fb6817a104b6a6309d413f7e
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Mar 19 14:38:25 2012 +0100
[1760] Implement the SQLite3 findPreviousNSEC3Hash
It is very similar to the findPreviousName, just that it wraps around
when no hash is found.
commit 37960ee83cb33be5cd683fb0d458343752caa01a
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Mar 19 13:56:35 2012 +0100
[1760] Tests for sqlite3 findPRevioushNSEC3Hash
Naturally, the tests fail, the method is not implemented.
-----------------------------------------------------------------------
Summary of changes:
src/lib/datasrc/sqlite3_accessor.cc | 83 ++++++++++++++++++-
src/lib/datasrc/tests/sqlite3_accessor_unittest.cc | 67 ++++++++++++++++
2 files changed, 145 insertions(+), 5 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc
index 1f50aaf..308df60 100644
--- a/src/lib/datasrc/sqlite3_accessor.cc
+++ b/src/lib/datasrc/sqlite3_accessor.cc
@@ -55,7 +55,9 @@ enum StatementID {
HIGH_DIFF_ID = 14,
DIFF_RECS = 15,
NSEC3 = 16,
- NUM_STATEMENTS = 17
+ NSEC3_PREVIOUS = 17,
+ NSEC3_LAST = 18,
+ NUM_STATEMENTS = 19
};
const char* const text_statements[NUM_STATEMENTS] = {
@@ -84,7 +86,7 @@ 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)",
@@ -112,7 +114,13 @@ const char* const text_statements[NUM_STATEMENTS] = {
// expected position, so we can reuse the same code as for other
// lookups.
"SELECT rdtype, ttl, 1, rdata FROM nsec3 WHERE zone_id=?1 AND "
- "hash=?2"
+ "hash=?2",
+ // For getting the previous NSEC3 hash
+ "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 AND hash < ?2 "
+ "ORDER BY hash DESC LIMIT 1",
+ // And for wrap-around
+ "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 "
+ "ORDER BY hash DESC LIMIT 1",
};
struct SQLite3Parameters {
@@ -1142,8 +1150,73 @@ SQLite3Accessor::findPreviousName(int zone_id, const std::string& rname)
}
std::string
-SQLite3Accessor::findPreviousNSEC3Hash(int, const std::string&) const {
- isc_throw(NotImplemented, "Not implemented yet, see #1760");
+SQLite3Accessor::findPreviousNSEC3Hash(int zone_id, const std::string& hash)
+ const
+{
+ sqlite3_stmt* const stmt = dbparameters_->getStatement(NSEC3_PREVIOUS);
+ sqlite3_reset(stmt);
+ sqlite3_clear_bindings(stmt);
+
+ if (sqlite3_bind_int(stmt, 1, zone_id) != SQLITE_OK) {
+ isc_throw(SQLite3Error, "Could not bind zone ID " << zone_id <<
+ " to SQL statement (find previous NSEC3): " <<
+ sqlite3_errmsg(dbparameters_->db_));
+ }
+ if (sqlite3_bind_text(stmt, 2, hash.c_str(), -1, SQLITE_STATIC) !=
+ SQLITE_OK) {
+ isc_throw(SQLite3Error, "Could not bind hash " << hash <<
+ " to SQL statement (find previous NSEC3): " <<
+ sqlite3_errmsg(dbparameters_->db_));
+ }
+
+ std::string result;
+ const int rc = sqlite3_step(stmt);
+ if (rc == SQLITE_ROW) {
+ // We found it
+ result = convertToPlainChar(sqlite3_column_text(stmt, 0),
+ dbparameters_->db_);
+ }
+ sqlite3_reset(stmt);
+
+ if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
+ // Some kind of error
+ isc_throw(SQLite3Error, "Could not get data for previous hash");
+ }
+
+ if (rc == SQLITE_DONE) {
+ // No NSEC3 records before this hash. This means we should wrap
+ // around and take the last one.
+ sqlite3_stmt* const stmt = dbparameters_->getStatement(NSEC3_LAST);
+ sqlite3_reset(stmt);
+ sqlite3_clear_bindings(stmt);
+
+ if (sqlite3_bind_int(stmt, 1, zone_id) != SQLITE_OK) {
+ isc_throw(SQLite3Error, "Could not bind zone ID " << zone_id <<
+ " to SQL statement (find last NSEC3): " <<
+ sqlite3_errmsg(dbparameters_->db_));
+ }
+
+ const int rc = sqlite3_step(stmt);
+ if (rc == SQLITE_ROW) {
+ // We found it
+ result = convertToPlainChar(sqlite3_column_text(stmt, 0),
+ dbparameters_->db_);
+ }
+ sqlite3_reset(stmt);
+
+ if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
+ // Some kind of error
+ isc_throw(SQLite3Error, "Could not get data for last hash");
+ }
+
+ if (rc == SQLITE_DONE) {
+ // No NSEC3 at all in the zone. Well, bad luck, but you should not
+ // have asked in the first place.
+ isc_throw(DataSourceError, "No NSEC3 in this zone");
+ }
+ }
+
+ return (result);
}
} // end of namespace datasrc
diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
index 5f6682a..4f7a5d8 100644
--- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
@@ -208,6 +208,73 @@ TEST_F(SQLite3AccessorTest, nsec3) {
EXPECT_FALSE(context->getNext(data));
}
+// This tests getting a previoeus hash in the NSEC3 namespace of a zone,
+// including a wrap-around and asking for a hash that does not exist in the.
+// zone at all.
+TEST_F(SQLite3AccessorTest, nsec3Previous) {
+ // Get the zone
+ const std::pair<bool, int>
+ zone_info(accessor->getZone("sql2.example.com."));
+ ASSERT_TRUE(zone_info.first);
+
+ std::string data[DatabaseAccessor::COLUMN_COUNT];
+
+ // Test a previous hash for something that is in the zone
+ // (ensuring it is really there)
+ DatabaseAccessor::IteratorContextPtr
+ context(accessor->getNSEC3Records("703OOGCKF8VEV1N7U64D1JG19URETN8N",
+ zone_info.second));
+ EXPECT_TRUE(context->getNext(data));
+ EXPECT_EQ("56IEQ664LHDAKVPE2FL179MSM3QAOFVC", accessor->
+ findPreviousNSEC3Hash(zone_info.second,
+ "703OOGCKF8VEV1N7U64D1JG19URETN8N"));
+
+ // Test a previous hash for something that is not in the
+ // zone
+ context = accessor->getNSEC3Records("702OOGCKF8VEV1N7U64D1JG19URETN8N",
+ zone_info.second);
+ EXPECT_FALSE(context->getNext(data));
+ EXPECT_EQ("56IEQ664LHDAKVPE2FL179MSM3QAOFVC", accessor->
+ findPreviousNSEC3Hash(zone_info.second,
+ "702OOGCKF8VEV1N7U64D1JG19URETN8N"));
+
+ // Search at the first item, should wrap around
+ context = accessor->getNSEC3Records("1BB7SO0452U1QHL98UISNDD9218GELR5",
+ zone_info.second);
+ EXPECT_TRUE(context->getNext(data));
+ EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
+ findPreviousNSEC3Hash(zone_info.second,
+ "1BB7SO0452U1QHL98UISNDD9218GELR5"));
+
+ // Search before the first item, should wrap around
+ context = accessor->getNSEC3Records("0BB7SO0452U1QHL98UISNDD9218GELR5",
+ zone_info.second);
+ EXPECT_FALSE(context->getNext(data));
+ EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
+ findPreviousNSEC3Hash(zone_info.second,
+ "0BB7SO0452U1QHL98UISNDD9218GELR5"));
+
+ // Search after the last item (should return the last one)
+ context = accessor->getNSEC3Records("RRBUCQT8T78GV6QBCGBHCHC019LG73SJ",
+ zone_info.second);
+ EXPECT_FALSE(context->getNext(data));
+ EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
+ findPreviousNSEC3Hash(zone_info.second,
+ "RRBUCQT8T78GV6QBCGBHCHC019LG73SJ"));
+}
+
+// Check it throws when we want a previous NSEC3 hash in an unsigned zone
+TEST_F(SQLite3AccessorTest, nsec3PreviousUnsigned) {
+ // This zone did not look signed in the test file.
+ const std::pair<bool, int>
+ unsigned_zone_info(accessor->getZone("example.com."));
+
+ EXPECT_THROW(accessor->
+ findPreviousNSEC3Hash(unsigned_zone_info.second,
+ "0BB7SO0452U1QHL98UISNDD9218GELR5"),
+ DataSourceError);
+}
+
// This tests the difference iterator context
// Test that at attempt to create a difference iterator for a serial number
More information about the bind10-changes
mailing list