zone_loader.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef DATASRC_ZONE_LOADER_H
  15. #define DATASRC_ZONE_LOADER_H
  16. #include <datasrc/data_source.h>
  17. #include <dns/master_loader.h>
  18. #include <cstdlib> // For size_t
  19. #include <boost/shared_ptr.hpp>
  20. #include <boost/scoped_ptr.hpp>
  21. namespace isc {
  22. namespace dns {
  23. // Forward declaration
  24. class Name;
  25. }
  26. namespace datasrc {
  27. // Forward declarations
  28. class DataSourceClient;
  29. class ZoneIterator;
  30. typedef boost::shared_ptr<ZoneIterator> ZoneIteratorPtr;
  31. class ZoneUpdater;
  32. typedef boost::shared_ptr<ZoneUpdater> ZoneUpdaterPtr;
  33. /// \brief Exception thrown when there's a problem with master file.
  34. ///
  35. /// This is thrown by the ZoneLoader when there's a fatal problem with
  36. /// a master file being loaded.
  37. class MasterFileError : public DataSourceError {
  38. public:
  39. MasterFileError(const char* file, size_t line, const char* what) :
  40. DataSourceError(file, line, what)
  41. {}
  42. };
  43. /// \brief Class to load data into a data source client.
  44. ///
  45. /// This is a small wrapper class that is able to load data into a data source.
  46. /// It can load either from another data source or from a master file. The
  47. /// purpose of the class is only to hold the state for incremental loading.
  48. ///
  49. /// The old content of zone is discarded and no journal is stored.
  50. class ZoneLoader {
  51. public:
  52. /// \brief Constructor from master file.
  53. ///
  54. /// This initializes the zone loader to load from a master file.
  55. ///
  56. /// \param destination The data source into which the loaded data should
  57. /// go.
  58. /// \param zone_name The origin of the zone. The class is implicit in the
  59. /// destination.
  60. /// \param master_file Path to the master file to read data from.
  61. /// \throw DataSourceError in case the zone does not exist in destination.
  62. /// This class does not support creating brand new zones, only loading
  63. /// data into them. In case a new zone is needed, it must be created
  64. /// beforehand.
  65. /// \throw DataSourceError in case of other (possibly low-level) errors,
  66. /// such as read-only data source or database error.
  67. ZoneLoader(DataSourceClient& destination, const isc::dns::Name& zone_name,
  68. const char* master_file);
  69. /// \brief Constructor from another data source.
  70. ///
  71. /// This initializes the zone loader to read from another data source.
  72. /// It'll effectively copy data from one data source to another.
  73. ///
  74. /// \param destination The data source into which the loaded data should
  75. /// go.
  76. /// \param zone_name The origin of the zone.
  77. /// \param source The data source from which the data would be read.
  78. /// \throw InvalidParameter in case the class of destination and source
  79. /// differs.
  80. /// \throw NotImplemented in case the source data source client doesn't
  81. /// provide an iterator.
  82. /// \throw DataSourceError in case the zone does not exist in destination.
  83. /// This class does not support creating brand new zones, only loading
  84. /// data into them. In case a new zone is needed, it must be created
  85. /// beforehand.
  86. /// \throw DataSourceError in case the zone does not exist in the source.
  87. /// \throw DataSourceError in case of other (possibly low-level) errors,
  88. /// such as read-only data source or database error.
  89. ZoneLoader(DataSourceClient& destination, const isc::dns::Name& zone_name,
  90. DataSourceClient& source);
  91. /// \brief Perform the whole load.
  92. ///
  93. /// This performs the whole loading operation. It may take a long time.
  94. ///
  95. /// \throw InvalidOperation in case the loading was already completed
  96. /// before this call.
  97. /// \throw DataSourceError in case some error (possibly low-level) happens.
  98. /// \throw MasterFileError when the master_file is badly formatted or some
  99. /// similar problem is found when loading the master file.
  100. void load() {
  101. while (!loadIncremental(1000)) { // 1000 is arbitrary largish number
  102. // Body intentionally left blank.
  103. }
  104. }
  105. /// \brief Load up to limit RRs.
  106. ///
  107. /// This performs a part of the loading. In case there's enough data in the
  108. /// source, it copies limit RRs. It can copy less RRs during the final call
  109. /// (when there's less than limit left).
  110. ///
  111. /// This can be called repeatedly until the whole zone is loaded, having
  112. /// pauses in the loading for some purposes (for example reporting
  113. /// progress).
  114. ///
  115. /// \param limit The maximum allowed number of RRs to be loaded during this
  116. /// call.
  117. /// \return True in case the loading is completed, false if there's more
  118. /// to load.
  119. /// \throw InvalidOperation in case the loading was already completed
  120. /// before this call (by load() or by a loadIncremental that returned
  121. /// true).
  122. /// \throw DataSourceError in case some error (possibly low-level) happens.
  123. /// \throw MasterFileError when the master_file is badly formatted or some
  124. /// similar problem is found when loading the master file.
  125. /// \note If the limit is exactly the number of RRs available to be loaded,
  126. /// the method still returns false and true'll be returned on the next
  127. /// call (which will load 0 RRs). This is because the end of iterator or
  128. /// master file is detected when reading past the end, not when the last
  129. /// one is read.
  130. bool loadIncremental(size_t limit);
  131. private:
  132. /// \brief The iterator used as source of data in case of the copy mode.
  133. const ZoneIteratorPtr iterator_;
  134. /// \brief The destination zone updater
  135. const ZoneUpdaterPtr updater_;
  136. /// \brief The master loader (for the master file mode)
  137. boost::scoped_ptr<isc::dns::MasterLoader> loader_;
  138. /// \brief Indicator if loading was completed
  139. bool complete_;
  140. /// \brief Was the loading successful?
  141. bool loaded_ok_;
  142. };
  143. }
  144. }
  145. #endif