un-deprecate repoManager::knownRepositories
[platform/upstream/libzypp.git] / zypp / RepoManager.h
index 4d5f3af..53ca2bb 100644 (file)
@@ -15,6 +15,8 @@
 #include <iosfwd>
 #include <list>
 
+#include <boost/iterator.hpp>
+
 #include "zypp/base/PtrTypes.h"
 #include "zypp/Pathname.h"
 #include "zypp/ZConfig.h"
@@ -27,6 +29,7 @@
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
+  class ServiceInfo; //predef
 
    /**
     * Parses \a repo_file and returns a list of \ref RepoInfo objects
@@ -47,15 +50,52 @@ namespace zypp
    */
   struct RepoManagerOptions
   {
-    RepoManagerOptions();
+    /** Default ctor following \ref ZConfig global settings.
+     * If an optional \c root_r directory is given, all paths  will
+     * be prefixed accordingly.
+     * \code
+     *    root_r\repoCachePath
+     *          \repoRawCachePath
+     *          \repoSolvCachePath
+     *          \repoPackagesCachePath
+     *          \knownReposPath
+     * \endcode
+     */
+    RepoManagerOptions( const Pathname & root_r = Pathname() );
+
+    /** Test setup adjusting all paths to be located below one \c root_r directory.
+     * \code
+     *    root_r\          - repoCachePath
+     *          \raw       - repoRawCachePath
+     *          \solv      - repoSolvCachePath
+     *          \packages  - repoPackagesCachePath
+     *          \repos.d   - knownReposPath
+     * \endcode
+     */
+    static RepoManagerOptions makeTestSetup( const Pathname & root_r );
 
     Pathname repoCachePath;
     Pathname repoRawCachePath;
+    Pathname repoSolvCachePath;
     Pathname repoPackagesCachePath;
     Pathname knownReposPath;
+    Pathname knownServicesPath;
     bool probe;
+    /**
+     * Target distro ID to be used when refreshing repo index services.
+     * Repositories not maching this ID will be skipped/removed.
+     *
+     * The value is initialized upon construction to
+     * \ref Target::targetDistribution() if the Target is already initialized,
+     * otherwise the value is initially empty.
+     *
+     * If empty, no repositories contained in the index will be skipped.
+     */
+    std::string servicesTargetDistro;
   };
 
+
+
   /**
    * \short creates and provides information about known sources.
    *
@@ -68,6 +108,16 @@ namespace zypp
     /** Implementation  */
     class Impl;
 
+    /** service typedefs */
+    typedef std::set<ServiceInfo> ServiceSet;
+    typedef ServiceSet::const_iterator ServiceConstIterator;
+    typedef ServiceSet::size_type ServiceSizeType;
+
+    /** RepoInfo typedefs */
+    typedef std::set<RepoInfo> RepoSet;
+    typedef RepoSet::const_iterator RepoConstIterator;
+    typedef RepoSet::size_type RepoSizeType;
+
   public:
    RepoManager( const RepoManagerOptions &options = RepoManagerOptions() );
    /** Dtor */
@@ -76,7 +126,8 @@ namespace zypp
     enum RawMetadataRefreshPolicy
     {
       RefreshIfNeeded,
-      RefreshForced
+      RefreshForced,
+      RefreshIfNeededIgnoreDelay
     };
 
     enum CacheBuildPolicy
@@ -100,12 +151,27 @@ namespace zypp
     */
    std::list<RepoInfo> knownRepositories() const;
 
+   bool repoEmpty() const;
+   RepoSizeType repoSize() const;
+   RepoConstIterator repoBegin() const;
+   RepoConstIterator repoEnd() const;
+
+
    /**
     * \short Status of local metadata
     */
     RepoStatus metadataStatus( const RepoInfo &info ) const;
 
     /**
+     * Possibly return state of checkIfRefreshMEtadata function
+     */
+    enum RefreshCheckStatus {
+      REFRESH_NEEDED,  /**< refresh is needed */
+      REPO_UP_TO_DATE, /**< repository not changed */
+      REPO_CHECK_DELAYED     /**< refresh is delayed due to settings */
+    };
+
+    /**
      * Checks whether to refresh metadata for specified repository and url.
      * <p>
      * The need for refresh is evaluated according to the following conditions,
@@ -133,7 +199,7 @@ namespace zypp
      *   {
      *     // check whether to refresh metadata
      *     // if the check fails for this url, it throws, so another url will be checked
-     *     if (!checkIfToRefreshMetadata(info, *it, policy))
+     *     if (checkIfToRefreshMetadata(info, *it, policy)!=RepoInfo::REFRESH_NEEDED)
      *       return;
      *
      *     // do the actual refresh
@@ -152,12 +218,14 @@ namespace zypp
      * \param info
      * \param url
      * \param policy
+     * \return state of repository
+     * \see RefreshCheckStatus
      * \throws RepoUnknownTypeException
      * \throws repo::RepoNoAliasException if can't figure an alias
      * \throws Exception on unknown error
      *
      */
-    bool checkIfToRefreshMetadata( const RepoInfo &info,
+    RefreshCheckStatus checkIfToRefreshMetadata( const RepoInfo &info,
                                    const Url &url,
                                    RawMetadataRefreshPolicy policy = RefreshIfNeeded);
 
@@ -173,6 +241,20 @@ namespace zypp
      */
     Pathname metadataPath( const RepoInfo &info ) const;
 
+
+    /**
+     * \short Path where the rpm packages are downloaded and kept
+     *
+     * Given a repoinfo, tells where \ref RepoProvidePackage will download
+     * and keep the .rpm files.
+     *
+     * \param info Repository information
+     *
+     * \throws repo::RepoNoAliasException if can't figure an alias
+     */
+    Pathname packagesPath( const RepoInfo &info ) const;
+
+
    /**
     * \short Refresh local raw cache
     *
@@ -256,11 +338,6 @@ namespace zypp
                     const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
 
    /**
-    * Clean target system (rpm db) cache.
-    */
-   void cleanTargetCache(const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc());
-
-   /**
     * \short Whether a repository exists in cache
     *
     * \param RepoInfo to be checked.
@@ -294,8 +371,11 @@ namespace zypp
     *
     * \throws repo::RepoAlreadyExistsException If the repo clash some
     *         unique attribute like alias
-    * \throws RepoUnknownType If repository type can't be determined
-    * \throws RepoException If the access to the url fails (while probing).
+    * \throws RepoUnknownType
+    *         If RepoManagerOptions::probe is true
+    *         and repository type can't be determined.
+    * \throws RepoException
+    *         If RepoManagerOptions::probe is true and access to the url fails.
     * \throws Exception On other errors.
     */
    void addRepository( const RepoInfo &info,
@@ -306,9 +386,7 @@ namespace zypp
     * \param url Url of the repo file
     *
     * \throws repo::RepoAlreadyExistsException If the repo clash some
-    * unique attribute like alias
-    *
-    * \throws RepoAlreadyExistsException
+    *         unique attribute like alias
     * \throws MediaException If the access to the url fails
     * \throws ParseException If the file parsing fails
     * \throws RepoUnknownType If repository type can't be determined
@@ -377,9 +455,169 @@ namespace zypp
                                 const url::ViewOption & urlview = url::ViewOption::DEFAULTS,
                                 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
 
+    /**
+     * Adds new service by it's alias and url
+     *
+     * \param alias unique identifier of the service
+     * \param url url to service
+     *
+     * \throws FIXME RepoAlreadyExistException and as reponame is service name
+     */
+    void addService( const std::string & alias, const Url& url );
+
+    /**
+     * Adds new service
+     *
+     * \param service service info
+     *
+     * \throws FIXME RepoAlreadyExistException and as reponame is service name
+     */
+    void addService( const ServiceInfo & service );
+
+    /**
+     * Removes service specified by its name
+     *
+     * \param alias unique indientifier of the service to remove
+     *
+     * \throws RepoException if service is not found or file with ServiceInfo cannot be deleted
+     * \throws Exception if file contain more services and rewrite file failed
+     */
+    void removeService( const std::string & alias );
+
+    void removeService( const ServiceInfo & service );
+
+    /**
+     * Gets true if no service is in RepoManager (so no one in specified location)
+     *
+     * \return true if any ServiceInfo is in RepoManager
+     */
+    bool serviceEmpty() const;
+
+    /**
+     * Gets count of service in RepoManager (in specified location)
+     *
+     * \return count of service
+     */
+    ServiceSizeType serviceSize() const;
+
+    /**
+     * Iterator to first service in internal storage.
+     * \note Iterator is immutable, so you cannot change pointed ServiceInfo
+     * \return Iterator to first service
+     */
+    ServiceConstIterator serviceBegin() const;
+
+    /**
+     * Iterator to place behind last service in internal storage.
+     * \return iterator to end
+     */
+    ServiceConstIterator serviceEnd() const;
+
+    /**
+     * Finds ServiceInfo by alias or return noService
+     *
+     * \param alias unique identifier of service
+     * \return information about service
+     */
+    ServiceInfo getService( const std::string & alias ) const;
+
+    /**
+     * Refreshes all enabled services.
+     *
+     * \see refreshService(ServiceInfo)
+     */
+    void refreshServices();
+
+    /**
+     * Refresh specific service.
+     *
+     * \param name service structure
+     * \throws MediaException If there's a problem downloading the repo index file.
+     */
+    void refreshService( const ServiceInfo & service );
+
+    /**
+     * Modifies service file (rewrites it with new values) and underlying
+     * repositories if needed.
+     *
+     * Modifications of a service can lead to rewrite of all .repo files of
+     * contained repositories. Particularily, disabling a service (changing
+     * ServiceInfo::enabled() from true to false) will disable all contained
+     * repositories. Renaming of a service will modify the "service" key
+     * of all contained repositories.
+     *
+     * \param oldAlias Old alias of the service
+     * \param service ServiceInfo object containing new data
+     *
+     * \throws RepoException if sservice with oldAlias is not known
+     * \throws Exception if have problems with files
+     */
+    void modifyService(const std::string & oldAlias, const ServiceInfo & service);
+
+  private:
+    /**
+     * Functor thats filter RepoInfo by service which belongs to.
+     */
+    struct MatchServiceAlias
+    {
+      private:
+        std::string alias;
+      public:
+        MatchServiceAlias( const std::string & alias_ ) : alias(alias_) {}
+        bool match( const RepoInfo & info ) { return info.service() == alias; }
+    };
+
+  public:
+
+    /**
+     * fill to output iterator repositories in service name. This output iterator can perform
+     * any action on with Repo or service Container, because it is sets and it isn't dynamic recreate.
+     *
+     * \note Don't use this function with RepoManager::removeRepository(), it will lead to segfaults
+     *       due to invalidated internal iterators. FIXME can this be solved (using STL) so that this
+     *       warning would not be needed?
+     *
+     * \param alias service alias
+     * \param out output iterator which get all the repositories belonging to
+     *   specified service
+     *
+     * example how set priority for each RepoInfo in this service:
+     * \code
+     * //functor
+     * class ChangePriority
+     * {
+     * private:
+     *   int priority;
+     * public:
+     *   ChangePriority(int prio) : priority(prio) {}
+     *   // missing rewrite priority back via RepoManager::modifyRepo
+     *   void doIt( RepoInfo info ) { info.setPriority(priority); }
+     * }
+     *
+     * //somewhere in code
+     * ChangePriority changer(10);
+     * getRepositoriesInService(name,
+     *   boost::make_function_output_iterator(
+     *     bind(&ChangePriority::doIt, &changer, _1)));
+     * \endcode
+     */
+    template<typename OutputIterator>
+    void getRepositoriesInService( const std::string & alias,
+                                   OutputIterator out ) const
+    {
+      MatchServiceAlias filter(alias);
+
+      std::copy(
+        boost::make_filter_iterator(
+          bind(&MatchServiceAlias::match, filter, _1), repoBegin(), repoEnd()),
+        boost::make_filter_iterator(
+          bind(&MatchServiceAlias::match, filter, _1), repoEnd(), repoEnd()),
+        out);
+    }
+
   protected:
     RepoStatus rawMetadataStatus( const RepoInfo &info );
-    void setCacheStatus( const std::string &alias, const RepoStatus &status );
+    void setCacheStatus( const RepoInfo &info, const RepoStatus &status );
 
     /**
      * Update timestamp of repository index file for the specified repository \a info.