NSEC3_PREVIOUS = 17,
NSEC3_LAST = 18,
ADD_NSEC3_RECORD = 19,
- NUM_STATEMENTS = 20
+ DEL_ZONE_NSEC3_RECORDS = 20,
+ NUM_STATEMENTS = 21
};
const char* const text_statements[NUM_STATEMENTS] = {
"ORDER BY hash DESC LIMIT 1",
// ADD_NSEC3_RECORD: Add NSEC3-related (NSEC3 or NSEC3-covering RRSIG) RR
"INSERT INTO nsec3 (zone_id, hash, owner, ttl, rdtype, rdata) "
- "VALUES (?1, ?2, '', ?3, ?4, ?5)"
+ "VALUES (?1, ?2, '', ?3, ?4, ?5)",
+ // DEL_ZONE_NSEC3_RECORDS: delete all NSEC3-related records from the zone
+ "DELETE FROM nsec3 WHERE zone_id=?1"
};
struct SQLite3Parameters {
"start an SQLite3 update transaction").exec();
if (replace) {
+ // First, clear all current data from tables.
+ typedef pair<StatementID, const char* const> StatementSpec;
+ const StatementSpec delzone_stmts[] =
+ { StatementSpec(DEL_ZONE_RECORDS, "delete zone records"),
+ StatementSpec(DEL_ZONE_NSEC3_RECORDS,
+ "delete zone NSEC3 records") };
try {
- StatementProcessor delzone_exec(*dbparameters_, DEL_ZONE_RECORDS,
- "delete zone records");
-
- sqlite3_stmt* stmt = dbparameters_->getStatement(DEL_ZONE_RECORDS);
- sqlite3_clear_bindings(stmt);
- if (sqlite3_bind_int(stmt, 1, zone_info.second) != SQLITE_OK) {
- isc_throw(DataSourceError,
- "failed to bind SQLite3 parameter: " <<
- sqlite3_errmsg(dbparameters_->db_));
+ for (size_t i = 0;
+ i < sizeof(delzone_stmts) / sizeof(delzone_stmts[0]);
+ ++i) {
+ StatementProcessor delzone_exec(*dbparameters_,
+ delzone_stmts[i].first,
+ delzone_stmts[i].second);
+ sqlite3_stmt* stmt =
+ dbparameters_->getStatement(delzone_stmts[i].first);
+ sqlite3_clear_bindings(stmt);
+ if (sqlite3_bind_int(stmt, 1, zone_info.second) != SQLITE_OK) {
+ isc_throw(DataSourceError,
+ "failed to bind SQLite3 parameter: " <<
+ sqlite3_errmsg(dbparameters_->db_));
+ }
+ delzone_exec.exec();
}
-
- delzone_exec.exec();
} catch (const DataSourceError&) {
// Once we start a transaction, if something unexpected happens
// we need to rollback the transaction so that a subsequent update
StatementProcessor(*dbparameters_, COMMIT,
"commit an SQLite3 transaction").exec();
dbparameters_->in_transaction = false;
+ dbparameters_->updating_zone = false;
dbparameters_->updated_zone_id = -1;
}
checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
}
+TEST_F(SQLite3Update, flushZoneWithNSEC3) {
+ // Similar to the previous case, but make sure the separate nsec3 table
+ // is also cleared. We first need to add something to the table.
+ zone_id = accessor->startUpdateZone("example.com.", false).second;
+ copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
+ add_nsec3_columns);
+ accessor->addNSEC3RecordToZone(add_nsec3_columns);
+ accessor->commit();
+
+ // Confirm it surely exists.
+ expected_stored.clear();
+ expected_stored.push_back(nsec3_data);
+ checkNSEC3Records(*accessor, zone_id, apex_hash, expected_stored);
+
+ // Then starting zone replacement. the NSEC3 record should have been
+ // removed.
+ zone_id = accessor->startUpdateZone("example.com.", true).second;
+ checkNSEC3Records(*accessor, zone_id, apex_hash, empty_stored);
+}
+
TEST_F(SQLite3Update, readWhileUpdate) {
zone_id = accessor->startUpdateZone("example.com.", true).second;
checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);