// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #ifndef DATASRC_ZONE_LOADER_H #define DATASRC_ZONE_LOADER_H #include #include #include // For size_t #include #include namespace isc { namespace dns { // Forward declaration class Name; } namespace datasrc { // Forward declarations class DataSourceClient; class ZoneIterator; typedef boost::shared_ptr ZoneIteratorPtr; class ZoneUpdater; typedef boost::shared_ptr ZoneUpdaterPtr; /// \brief Exception thrown when there's a problem with master file. /// /// This is thrown by the ZoneLoader when there's a fatal problem with /// a master file being loaded. class MasterFileError : public DataSourceError { public: MasterFileError(const char* file, size_t line, const char* what) : DataSourceError(file, line, what) {} }; /// \brief Class to load data into a data source client. /// /// This is a small wrapper class that is able to load data into a data source. /// It can load either from another data source or from a master file. The /// purpose of the class is only to hold the state for incremental loading. /// /// The old content of zone is discarded and no journal is stored. class ZoneLoader { public: /// \brief Constructor from master file. /// /// This initializes the zone loader to load from a master file. /// /// \param destination The data source into which the loaded data should /// go. /// \param zone_name The origin of the zone. The class is implicit in the /// destination. /// \param master_file Path to the master file to read data from. /// \throw DataSourceError in case the zone does not exist in destination. /// This class does not support creating brand new zones, only loading /// data into them. In case a new zone is needed, it must be created /// beforehand. /// \throw DataSourceError in case of other (possibly low-level) errors, /// such as read-only data source or database error. ZoneLoader(DataSourceClient& destination, const isc::dns::Name& zone_name, const char* master_file); /// \brief Constructor from another data source. /// /// This initializes the zone loader to read from another data source. /// It'll effectively copy data from one data source to another. /// /// \param destination The data source into which the loaded data should /// go. /// \param zone_name The origin of the zone. /// \param source The data source from which the data would be read. /// \throw InvalidParameter in case the class of destination and source /// differs. /// \throw NotImplemented in case the source data source client doesn't /// provide an iterator. /// \throw DataSourceError in case the zone does not exist in destination. /// This class does not support creating brand new zones, only loading /// data into them. In case a new zone is needed, it must be created /// beforehand. /// \throw DataSourceError in case the zone does not exist in the source. /// \throw DataSourceError in case of other (possibly low-level) errors, /// such as read-only data source or database error. ZoneLoader(DataSourceClient& destination, const isc::dns::Name& zone_name, DataSourceClient& source); /// \brief Perform the whole load. /// /// This performs the whole loading operation. It may take a long time. /// /// \throw InvalidOperation in case the loading was already completed /// before this call. /// \throw DataSourceError in case some error (possibly low-level) happens. /// \throw MasterFileError when the master_file is badly formatted or some /// similar problem is found when loading the master file. void load() { while (!loadIncremental(1000)) { // 1000 is arbitrary largish number // Body intentionally left blank. } } /// \brief Load up to limit RRs. /// /// This performs a part of the loading. In case there's enough data in the /// source, it copies limit RRs. It can copy less RRs during the final call /// (when there's less than limit left). /// /// This can be called repeatedly until the whole zone is loaded, having /// pauses in the loading for some purposes (for example reporting /// progress). /// /// \param limit The maximum allowed number of RRs to be loaded during this /// call. /// \return True in case the loading is completed, false if there's more /// to load. /// \throw InvalidOperation in case the loading was already completed /// before this call (by load() or by a loadIncremental that returned /// true). /// \throw DataSourceError in case some error (possibly low-level) happens. /// \throw MasterFileError when the master_file is badly formatted or some /// similar problem is found when loading the master file. /// \note If the limit is exactly the number of RRs available to be loaded, /// the method still returns false and true'll be returned on the next /// call (which will load 0 RRs). This is because the end of iterator or /// master file is detected when reading past the end, not when the last /// one is read. 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_; /// \brief The master loader (for the master file mode) boost::scoped_ptr loader_; /// \brief Indicator if loading was completed bool complete_; /// \brief Was the loading successful? bool loaded_ok_; }; } } #endif