At least its basic version. Error handling must still be tested and done.
// Use the loader to load an unsigned zone.
TEST_F(ZoneLoaderTest, copyUnsigned) {
- prepareSource(Name("example.org"), "example.org");
- ZoneLoader loader(destination_client_, Name("example.org"),
+ prepareSource(Name::ROOT_NAME(), "root.zone");
+ ZoneLoader loader(destination_client_, Name::ROOT_NAME(),
source_client_);
// It gets the updater directly in the constructor
ASSERT_EQ(1, destination_client_.provided_updaters_.size());
- EXPECT_EQ(Name("example.org"), destination_client_.provided_updaters_[0]);
+ EXPECT_EQ(Name::ROOT_NAME(), destination_client_.provided_updaters_[0]);
// Now load the whole zone
loader.load();
EXPECT_TRUE(destination_client_.commit_called_);
// We don't check the whole zone. We check the first and last and the
// count, which should be enough.
- EXPECT_EQ(7, destination_client_.rrsets_.size());
+
+ // The count is 34 because we expect the RRs to be separated.
+ EXPECT_EQ(34, destination_client_.rrsets_.size());
// Ensure known order.
std::sort(destination_client_.rrsets_.begin(),
destination_client_.rrsets_.end());
- EXPECT_EQ("TODO - check manually and copy-paste",
+ EXPECT_EQ(". 518400 IN NS a.root-servers.net.\n",
destination_client_.rrsets_.front());
- EXPECT_EQ("TODO - check manually and copy-paste",
+ EXPECT_EQ("m.root-servers.net. 3600000 IN AAAA 2001:dc3::35\n",
destination_client_.rrsets_.back());
}
// PERFORMANCE OF THIS SOFTWARE.
#include <datasrc/zone_loader.h>
+
+#include <datasrc/client.h>
+#include <datasrc/data_source.h>
+#include <datasrc/iterator.h>
+#include <datasrc/zone.h>
+
+#include <dns/rrset.h>
+
+using isc::dns::Name;
+using isc::dns::ConstRRsetPtr;
+
+namespace isc {
+namespace datasrc {
+
+ZoneLoader::ZoneLoader(DataSourceClient& destination, const Name& zone_name,
+ DataSourceClient& source) :
+ // Separate the RRsets as that is possibly faster (the data source doesn't
+ // have to aggregate them) and also because our limit semantics.
+ iterator_(source.getIterator(zone_name, true)),
+ updater_(destination.getUpdater(zone_name, true, false))
+{
+ // The getIterator should never return NULL. So we check it.
+ // Or should we throw instead?
+ assert(iterator_ != ZoneIteratorPtr());
+ // In case the zone doesn't exist in the destination, throw
+ if (updater_ == ZoneUpdaterPtr()) {
+ isc_throw(DataSourceError, "Zone " << zone_name << " not found in "
+ "destination data source, can't fill it with data");
+ }
+}
+
+namespace {
+
+// Copy up to limit RRsets from source to destination
+bool
+copyRRsets(const ZoneUpdaterPtr& destination, const ZoneIteratorPtr& source,
+ size_t limit)
+{
+ size_t loaded = 0;
+ while (loaded < limit) {
+ const ConstRRsetPtr rrset(source->getNextRRset());
+ if (rrset == ConstRRsetPtr()) {
+ // Done loading, no more RRsets in the input.
+ return (true);
+ } else {
+ destination->addRRset(*rrset);
+ }
+ ++loaded;
+ }
+ return (false); // Not yet, there may be more
+}
+
+}
+
+bool
+ZoneLoader::loadIncremental(size_t limit) {
+ if (iterator_ != ZoneIteratorPtr()) {
+ if (copyRRsets(updater_, iterator_, limit)) {
+ updater_->commit();
+ return (true);
+ } else {
+ return (false);
+ }
+ } else {
+ isc_throw(isc::NotImplemented, "The master file way is not ready yet");
+ }
+}
+
+}
+}
#define DATASRC_ZONE_LOADER_H
#include <cstdlib> // For size_t
+#include <boost/shared_ptr.hpp>
namespace isc {
namespace dns {
}
namespace datasrc {
-// Forward declaration
+// Forward declarations
class DataSourceClient;
+class ZoneIterator;
+typedef boost::shared_ptr<ZoneIterator> ZoneIteratorPtr;
+class ZoneUpdater;
+typedef boost::shared_ptr<ZoneUpdater> ZoneUpdaterPtr;
/// \brief Class to load data into a data source client.
///
/// before this call.
/// \throw DataSourceError in case some error (possibly low-level) happens.
void load() {
- while (~loadIncremental(1000)) { // 1000 is arbitrary largish number
+ while (!loadIncremental(1000)) { // 1000 is arbitrary largish number
// Body intentionally left blank.
}
}
/// true).
/// \throw DataSourceError in case some error (possibly low-level) happens.
bool loadIncremental(size_t limit);
+private:
+ /// \brief The iterator used as source of data in case of the copy mode.
+ const ZoneIteratorPtr iterator_;
+ /// \brief The destination zone updater
+ const ZoneUpdaterPtr updater_;
};
}