improve service handling and write tests for it.
authorJosef Reidinger <jreidinger@suse.cz>
Fri, 20 Jun 2008 14:13:07 +0000 (14:13 +0000)
committerJosef Reidinger <jreidinger@suse.cz>
Fri, 20 Jun 2008 14:13:07 +0000 (14:13 +0000)
12 files changed:
tests/zypp/Deltarpm_test.cc
tests/zypp/RepoManager_test.cc
tests/zypp/data/RepoManager/repo/repoindex.xml [new file with mode: 0644]
tests/zypp/data/RepoManager/second/repo/repoindex.xml [new file with mode: 0644]
zypp/RepoInfo.cc
zypp/RepoInfo.h
zypp/RepoManager.cc
zypp/RepoManager.h
zypp/Service.cc
zypp/Service.h
zypp/parser/RepoFileReader.cc
zypp/parser/ServiceFileReader.cc

index b3a3223..7dd0f58 100644 (file)
@@ -33,6 +33,9 @@ BOOST_AUTO_TEST_CASE(delta)
   RepoManagerOptions opts(rootdir);
   opts.repoRawCachePath = rootdir;
   opts.repoSolvCachePath = rootdir;
+  opts.knownReposPath = rootdir;
+  opts.knownServicesPath = rootdir;
+
   RepoManager rm(opts);
 
   RepoInfo updates;
index eade55e..7f617ae 100644 (file)
@@ -10,6 +10,7 @@
 #include "zypp/PublicKey.h"
 #include "zypp/TmpPath.h"
 #include "zypp/PathInfo.h"
+#include "zypp/Service.h"
 
 #include "zypp/RepoManager.h"
 
@@ -34,6 +35,7 @@ BOOST_AUTO_TEST_CASE(repomanager_test)
   RepoManagerOptions opts( RepoManagerOptions::makeTestSetup( tmpCachePath ) ) ;
 
   filesystem::mkdir( opts.knownReposPath );
+  filesystem::mkdir( opts.knownServicesPath );
   BOOST_CHECK_EQUAL( filesystem::copy_dir_content( DATADIR + "/repos.d", opts.knownReposPath ), 0 );
 
   RepoManager manager(opts);
@@ -73,11 +75,34 @@ BOOST_AUTO_TEST_CASE(repomanager_test)
   RepoInfo macromedia;
   macromedia.setAlias("macromedia");
   manager.removeRepository(macromedia);
-  repos = manager.knownRepositories();
-  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 4);
+  BOOST_CHECK_EQUAL(manager.repoSize(), (unsigned) 4);
   // the file should not exist anymore
   BOOST_CHECK( ! PathInfo(opts.knownReposPath + "/proprietary.repo_1").isExist() );
 
+  //test service
+  Url urlS;
+  urlS.setPathName(DATADIR.asString());
+  urlS.setScheme("dir");
+  Service service("test",urlS);
+
+  manager.addService(service);
+  manager.refreshServices();
+  BOOST_CHECK_EQUAL(manager.repoSize(), (unsigned) 7); //+3 from repoindex
+
+  //simulate change of repoindex.xml
+  urlS.setPathName((DATADIR+"second").asString());
+  urlS.setScheme("dir");
+  service.setUrl(urlS);
+
+  manager.modifyService(service.name(),service);
+  manager.refreshServices();
+  BOOST_CHECK_EQUAL(manager.repoSize(), (unsigned) 6); //-1 from new repoindex
+
+  std::list<RepoInfo> infos;
+  manager.getRepositoriesInService("test",
+    insert_iterator<std::list<RepoInfo> >(infos,infos.begin()));
+  BOOST_CHECK_EQUAL(infos.size(), 2); //2 from new repoindex
+
 
   // let test cache creation
 
diff --git a/tests/zypp/data/RepoManager/repo/repoindex.xml b/tests/zypp/data/RepoManager/repo/repoindex.xml
new file mode 100644 (file)
index 0000000..06632c8
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repoindex>
+  <repo name="SLES10-SP2-Online" 
+        alias="SLES10-SP2-Online" 
+        description="SLES10-SP2-Online for sles-10-i586" 
+        distro_target="sles-10-i586" path="$RCE/SLES10-SP2-Online/sles-10-i586" 
+        priority="0" 
+        pub="0" />
+  <repo name="SLE10-SP2-Debuginfo-Updates" 
+        alias="SLE10-SP2-Debuginfo-Updates" 
+        description="SLE10-SP2-Debuginfo-Updates for sles-10-i586" 
+        distro_target="sles-10-i586"
+        path="$RCE/SLE10-SP2-Debuginfo-Updates/sles-10-i586" 
+        priority="0" 
+        pub="0" />
+  <repo name="SLES10-SP2-Updates" 
+        alias="SLES10-SP2-Updates" 
+        description="SLES10-SP2-Updates for sles-10-i586" 
+        distro_target="sles-10-i586" 
+        path="$RCE/SLES10-SP2-Updates/sles-10-i586" 
+        priority="0" 
+        pub="0" />
+</repoindex>
+
diff --git a/tests/zypp/data/RepoManager/second/repo/repoindex.xml b/tests/zypp/data/RepoManager/second/repo/repoindex.xml
new file mode 100644 (file)
index 0000000..3e87256
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repoindex>
+  <repo name="SLES10-SP2-Online" 
+        alias="SLES10-SP2-Online" 
+        description="SLES10-SP2-Online for sles-10-i586" 
+        distro_target="sles-10-i586" path="$RCE/SLES10-SP2-Online/sles-10-i586" 
+        priority="0" 
+        pub="0" />
+  <repo name="SLES10-SP2-Updates" 
+        alias="SLES10-SP2-Updates" 
+        description="SLES10-SP2-Updates for sles-10-i586" 
+        distro_target="sles-10-i586" 
+        path="$RCE/SLES10-SP2-Updates/sles-10-i586" 
+        priority="0" 
+        pub="0" />
+</repoindex>
+
index a2adf61..07d67f6 100644 (file)
@@ -77,6 +77,7 @@ namespace zypp
     std::string alias;
     std::string escaped_alias;
     std::string name;
+    std::string service;
     Pathname filepath;
     Pathname metadatapath;
     Pathname packagespath;
@@ -255,6 +256,12 @@ namespace zypp
     return *this;
   }
 
+  RepoInfo & RepoInfo::setService( const std::string& name )
+  {
+    _pimpl->service = name;
+    return *this;
+  }
+
   bool RepoInfo::enabled() const
   { return _pimpl->enabled; }
 
@@ -317,6 +324,9 @@ namespace zypp
   Pathname RepoInfo::path() const
   { return _pimpl->path; }
 
+  std::string RepoInfo::service() const
+  { return _pimpl->service; }
+
   RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const
   {
     return make_transform_iterator( _pimpl->baseUrls.begin(),
@@ -359,6 +369,7 @@ namespace zypp
     str << "- gpgcheck    : " << gpgCheck() << std::endl;
     str << "- gpgkey      : " << gpgKeyUrl() << std::endl;
     str << "- keeppackages: " << keepPackages() << std::endl;
+    str << "- service     : " << service() << std::endl;
 
     return str;
   }
@@ -397,6 +408,9 @@ namespace zypp
 
     str << "keeppackages=" << keepPackages() << endl;
 
+    if( ! service().empty() )
+      str << "service=" << service() << endl;
+
     return str;
   }
 
index 0a0bab6..327a78b 100644 (file)
@@ -238,6 +238,12 @@ namespace zypp
      */
     bool keepPackages() const;
 
+    /**
+     * Gets service name which add it or empty string if this repository
+     * is added manually.
+     */
+    std::string service() const;
+
     public:
     /**
      * Add a base url. \see baseUrls
@@ -366,6 +372,11 @@ namespace zypp
     RepoInfo & setKeepPackages( bool keep );
 
     /**
+     * sets service which added this repository
+     */
+    RepoInfo & setService( const std::string& name );
+
+    /**
      * Write a human-readable representation of this RepoInfo object
      * into the \a str stream. Useful for logging.
      */
@@ -386,6 +397,9 @@ namespace zypp
   /** \relates RepoInfo Stream output */
   std::ostream & operator<<( std::ostream & str, const RepoInfo & obj );
 
+  inline bool operator<( const RepoInfo& lhs, const RepoInfo & rhs )
+  { return lhs.alias() < rhs.alias(); }
+
   typedef std::list<RepoInfo> RepoInfoList;
 
   /////////////////////////////////////////////////////////////////
index 99cf548..641ab01 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "zypp/parser/RepoFileReader.h"
 #include "zypp/parser/ServiceFileReader.h"
+#include "zypp/parser/RepoindexFileReader.h"
 #include "zypp/repo/yum/Downloader.h"
 #include "zypp/parser/yum/RepoParser.h"
 #include "zypp/repo/susetags/Downloader.h"
@@ -239,6 +240,8 @@ namespace zypp
     Impl( const RepoManagerOptions &opt )
       : options(opt)
     {
+      knownServices();
+      knownRepositories();
 
     }
 
@@ -249,7 +252,7 @@ namespace zypp
 
     RepoManagerOptions options;
 
-    map<string, RepoInfo> _repoinfos;
+    RepoSet repos;
     
     ServiceSet services;
 
@@ -261,7 +264,7 @@ namespace zypp
       return _nullimpl;
     }
 
-    void saveService( const Service& service );
+    void saveService( const Service& service ) const;
   
     Pathname generateNonExistingName( const Pathname &dir,
                                          const std::string &basefilename ) const;
@@ -278,6 +281,8 @@ namespace zypp
 
     void knownServices();
 
+    void knownRepositories();
+
   private:
     friend Impl * rwcowClone<Impl>( const Impl * rhs );
     /** clone for RWCOW_pointer */
@@ -310,31 +315,44 @@ namespace zypp
 
   ////////////////////////////////////////////////////////////////////////////
 
+  bool RepoManager::repoEmpty() const { return _pimpl->repos.empty(); }
+  RepoManager::RepoSizeType RepoManager::repoSize() const
+  { return _pimpl->repos.size(); }
+  RepoManager::RepoConstIterator RepoManager::repoBegin() const
+  { return _pimpl->repos.begin(); }
+  RepoManager::RepoConstIterator RepoManager::repoEnd() const
+  { return _pimpl->repos.end(); }
+
+
   std::list<RepoInfo> RepoManager::knownRepositories() const
   {
-    MIL << endl;
+    return std::list<RepoInfo>(repoBegin(),repoEnd());
+  }
 
-    if ( PathInfo(_pimpl->options.knownReposPath).isExist() )
+  void RepoManager::Impl::knownRepositories()
+  {
+    MIL << "start construct known repos" << endl;
+
+    if ( PathInfo(options.knownReposPath).isExist() )
     {
-      RepoInfoList repos = repositories_in_dir(_pimpl->options.knownReposPath);
-      for ( RepoInfoList::iterator it = repos.begin();
-            it != repos.end();
+      RepoInfoList repol = repositories_in_dir(options.knownReposPath);
+      for ( RepoInfoList::iterator it = repol.begin();
+            it != repol.end();
             ++it )
       {
         // set the metadata path for the repo
-        Pathname metadata_path = rawcache_path_for_repoinfo(_pimpl->options, (*it));
+        Pathname metadata_path = rawcache_path_for_repoinfo(options, (*it));
         (*it).setMetadataPath(metadata_path);
 
        // set the downloaded packages path for the repo
-       Pathname packages_path = packagescache_path_for_repoinfo(_pimpl->options, (*it));
+       Pathname packages_path = packagescache_path_for_repoinfo(options, (*it));
        (*it).setPackagesPath(packages_path);
+
+        repos.insert(*it);
       }
-      return repos;
     }
-    else
-      return std::list<RepoInfo>();
 
-    MIL << endl;
+    MIL << "end construct known repos" << endl;
   }
 
   ////////////////////////////////////////////////////////////////////////////
@@ -599,9 +617,7 @@ namespace zypp
               // Adjust the probed type in RepoInfo
               info.setProbedType( repokind ); // lazy init!
               //save probed type only for repos in system
-              std::list<RepoInfo> repos = knownRepositories();
-              for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-                   it != repos.end(); ++it )
+              for_( it, repoBegin(), repoEnd() )
               {
                 if ( info.alias() == (*it).alias() )
                 {
@@ -639,10 +655,7 @@ namespace zypp
            * repo has the same file, it will not download it
            * but copy it from the other repository
            */
-          std::list<RepoInfo> repos = knownRepositories();
-          for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-                it != repos.end();
-                ++it )
+          for_( it, repoBegin(), repoEnd() )
           {
             Pathname cachepath(rawcache_path_for_repoinfo( _pimpl->options, *it ));
             if ( PathInfo(cachepath).isExist() )
@@ -1056,16 +1069,10 @@ namespace zypp
     progress.name(str::form(_("Adding repository '%s'"), info.name().c_str()));
     progress.toMin();
 
-    std::list<RepoInfo> repos = knownRepositories();
-    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-          it != repos.end();
-          ++it )
-    {
-      if ( info.alias() == (*it).alias() )
+    RepoInfo tosave = info;
+    if(_pimpl->repos.find(tosave)!= _pimpl->repos.end())
         ZYPP_THROW(RepoAlreadyExistsException(info));
-    }
 
-    RepoInfo tosave = info;
 
     // check the first url for now
     if ( _pimpl->options.probe )
@@ -1099,6 +1106,8 @@ namespace zypp
     }
 
     tosave.dumpRepoOn(file);
+    tosave.setFilepath(repofile);
+    _pimpl->repos.insert(tosave);
     progress.toMax();
     MIL << "done" << endl;
   }
@@ -1106,16 +1115,13 @@ namespace zypp
   void RepoManager::addRepositories( const Url &url,
                                      const ProgressData::ReceiverFnc & progressrcv )
   {
-    std::list<RepoInfo> knownrepos = knownRepositories();
     std::list<RepoInfo> repos = readRepoFile(url);
     for ( std::list<RepoInfo>::const_iterator it = repos.begin();
           it != repos.end();
           ++it )
     {
       // look if the alias is in the known repos.
-      for ( std::list<RepoInfo>::const_iterator kit = knownrepos.begin();
-          kit != knownrepos.end();
-          ++kit )
+      for_ ( kit, repoBegin(), repoEnd() )
       {
         if ( (*it).alias() == (*kit).alias() )
         {
@@ -1142,12 +1148,14 @@ namespace zypp
       ZYPP_THROW (Exception( "Can't open " + repofile.asString() ) );
     }
 
-    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
+    for ( std::list<RepoInfo>::iterator it = repos.begin();
           it != repos.end();
           ++it )
     {
       MIL << "Saving " << (*it).alias() << endl;
-      (*it).dumpRepoOn(file);
+      it->setFilepath(repofile.asString());
+      it->dumpRepoOn(file);
+      _pimpl->repos.insert(*it);
     }
     MIL << "done" << endl;
   }
@@ -1164,10 +1172,7 @@ namespace zypp
 
     MIL << "Going to delete repo " << info.alias() << endl;
 
-    std::list<RepoInfo> repos = knownRepositories();
-    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-          it != repos.end();
-          ++it )
+    for_( it, repoBegin(), repoEnd() )
     {
       // they can be the same only if the provided is empty, that means
       // the provided repo has no alias
@@ -1228,6 +1233,7 @@ namespace zypp
           cleanCache( todelete, subprogrcv);
         // now delete metadata (#301037)
         cleanMetadata( todelete, cleansubprogrcv);
+        _pimpl->repos.erase(todelete);
         MIL << todelete.alias() << " sucessfully deleted." << endl;
         return;
       } // else filepath is empty
@@ -1248,10 +1254,7 @@ namespace zypp
     // check if the new alias already exists when renaming the repo
     if (alias != newinfo.alias())
     {
-      std::list<RepoInfo> repos = knownRepositories();
-      for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-            it != repos.end();
-            ++it )
+      for_( it, repoBegin(), repoEnd() )
       {
         if ( newinfo.alias() == (*it).alias() )
           ZYPP_THROW(RepoAlreadyExistsException(newinfo));
@@ -1291,6 +1294,9 @@ namespace zypp
           else
             newinfo.dumpRepoOn(file);
       }
+
+      _pimpl->repos.erase(toedit);
+      _pimpl->repos.insert(newinfo);
     }
   }
 
@@ -1299,17 +1305,13 @@ namespace zypp
   RepoInfo RepoManager::getRepositoryInfo( const std::string &alias,
                                            const ProgressData::ReceiverFnc & progressrcv )
   {
-    std::list<RepoInfo> repos = knownRepositories();
-    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-          it != repos.end();
-          ++it )
-    {
-      if ( (*it).alias() == alias )
-        return *it;
-    }
     RepoInfo info;
     info.setAlias(info.alias());
-    ZYPP_THROW(RepoNotFoundException(info));
+    RepoConstIterator it = _pimpl->repos.find( info );
+    if( it == repoEnd() )
+      ZYPP_THROW(RepoNotFoundException(info));
+    else
+      return *it;
   }
 
   ////////////////////////////////////////////////////////////////////////////
@@ -1318,10 +1320,7 @@ namespace zypp
                                            const url::ViewOption & urlview,
                                            const ProgressData::ReceiverFnc & progressrcv )
   {
-    std::list<RepoInfo> repos = knownRepositories();
-    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
-          it != repos.end();
-          ++it )
+    for_( it, repoBegin(), repoEnd() )
     {
       for(RepoInfo::urls_const_iterator urlit = (*it).baseUrlsBegin();
           urlit != (*it).baseUrlsEnd();
@@ -1332,22 +1331,24 @@ namespace zypp
       }
     }
     RepoInfo info;
-    info.setAlias(info.alias());
     info.setBaseUrl(url);
     ZYPP_THROW(RepoNotFoundException(info));
   }
-
+  
   void RepoManager::addService( const std::string& name, const Url& url )
   {
-    Service service(name, url);
+    addService( Service(name,url) );
+  }
 
+  void RepoManager::addService( const Service& service )
+  {
     //check if service isn't already exist
     if( _pimpl->services.find(service)!= _pimpl->services.end() )
       return; //TODO throw exception
 
-    _pimpl->services.insert( service );
+    const Service& savedService = *(_pimpl->services.insert( service )).first;
 
-    _pimpl->saveService( service );
+    _pimpl->saveService( savedService );
   }
 
   void RepoManager::removeService( const string& name)
@@ -1390,12 +1391,12 @@ namespace zypp
     }
 
     //now remove all repositories added by this service
-    for_( it, service.begin(), service.end() )
-      removeRepository(getRepositoryInfo(*it));
+    getRepositoriesInService( name, 
+      boost::make_function_output_iterator(bind(&RepoManager::removeRepository, this, _1, ProgressData::ReceiverFnc()) ) );
   }
 
 
-  void RepoManager::Impl::saveService( const Service& service )
+  void RepoManager::Impl::saveService( const Service& service ) const
   {
     filesystem::assert_dir( options.knownServicesPath );
 
@@ -1411,7 +1412,7 @@ namespace zypp
 
     service.dumpServiceOn( file );
 
-    service.setLocation( servfile );
+    const_cast<Service&>(service).setLocation( servfile );
     MIL << "done" << endl;
   }
 
@@ -1450,15 +1451,83 @@ namespace zypp
     for (std::set<Service>::iterator it = _pimpl->services.begin();
       it != _pimpl->services.end(); ++it)
     {
-      it->refresh(*this);
+      MIL << "refresh: "<<it->name() << " with url: "<< it->url().asString() << endl;
+      refreshService(*it);
     }
   }
 
-  void RepoManager::modifyService(const Service& service) const
+  void RepoManager::refreshService( const Service& service )
   {
-    MIL << "Going to modify service " << service.name() << endl;
+    //download index file
+    media::MediaManager mediamanager;
+    media::MediaAccessId mid = mediamanager.open( service.url() );
+    mediamanager.attachDesiredMedia( mid );
+    mediamanager.provideFile( mid, "repo/repoindex.xml" );
+    Pathname path = mediamanager.localPath(mid, "repo/repoindex.xml" );
+
+    //parse it
+    RepoCollector collector;
+    parser::RepoindexFileReader reader( path,
+      bind( &RepoCollector::collect, &collector, _1 ) );
+    mediamanager.release( mid );
+    mediamanager.close( mid );
 
-    Pathname location = service.location();
+    // set base url for all collected repositories
+    for_( it, collector.repos.begin(), collector.repos.end())
+    {
+      it->setBaseUrl( service.url() );
+      it->setService(service.name());
+    }
+
+    //compare old and new repositories (hope not to much, if it change
+    // then construct set and use set operation on it)
+    
+    std::list<RepoInfo> oldRepos;
+    getRepositoriesInService(service.name(),
+        insert_iterator<std::list<RepoInfo> >
+        (oldRepos,oldRepos.begin()));
+
+    //find old to remove
+    for_( it, oldRepos.begin(), oldRepos.end() )
+    {
+      bool found = false;
+
+      for_( it2, collector.repos.begin(), collector.repos.end() )
+        if ( it->alias() == it2->alias() )
+        {
+          found = true;
+          break;
+        }
+
+      if( !found )
+        removeRepository( *it );
+    }
+
+    //find new to add
+    for_( it, collector.repos.begin(), collector.repos.end() )
+    {
+      bool found = false;
+
+      for_( it2, oldRepos.begin(), oldRepos.end() )
+        if( it->alias() == it2->alias() )
+        {
+          found = true;
+          break;
+        }
+
+      if (!found)
+        addRepository( *it );
+    }
+
+  }
+
+  void RepoManager::modifyService(const std::string& oldName, const Service& service)
+  {
+    MIL << "Going to modify service " << oldName << endl;
+
+    const Service& oldService = getService(oldName);
+
+    Pathname location = oldService.location();
     if( location.empty() )
     {
       ZYPP_THROW(RepoException("Can't figure where the service is stored"));
@@ -1476,13 +1545,29 @@ namespace zypp
 
     for_(it, tmpSet.begin(), tmpSet.end())
     {
-      if( *it != service )
+      if( *it != oldName )
         it->dumpServiceOn(file);
     }
 
     service.dumpServiceOn(file);
 
     file.close();
+
+    _pimpl->services.erase(oldName);
+    _pimpl->services.insert(service);
+
+    if( oldName != service.name() ) //changed name, must change also repository
+    {
+      std::vector<RepoInfo> toModify;
+      getRepositoriesInService(oldName,
+        insert_iterator<std::vector<RepoInfo> >( toModify, toModify.begin() ));
+      for_( it, toModify.begin(), toModify.end() )
+      {
+        it->setService(service.name());
+        modifyRepository(it->alias(), *it);
+      }
+    }
+
   }
 
   void RepoManager::Impl::knownServices()
index cfcfa1c..2da84e8 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"
@@ -100,6 +102,11 @@ namespace zypp
     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 */
@@ -129,9 +136,16 @@ namespace zypp
     * The known repositories are read from
     * \ref RepoManagerOptions::knownReposPath passed on the Ctor.
     * Which defaults to ZYpp global settings.
+    * \deprecated use iterator instead which read only one time directory
     * \return found list<RepoInfo>
     */
-   std::list<RepoInfo> knownRepositories() const;
+   ZYPP_DEPRECATED std::list<RepoInfo> knownRepositories() const;
+
+   bool repoEmpty() const;
+   RepoSizeType repoSize() const;
+   RepoConstIterator repoBegin() const;
+   RepoConstIterator repoEnd() const;
+
 
    /**
     * \short Status of local metadata
@@ -431,6 +445,7 @@ namespace zypp
                                 const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
 
     void addService( const std::string& name, const Url& url );
+    void addService( const Service& name );
 
     void removeService( const std::string& name );
 
@@ -446,11 +461,35 @@ namespace zypp
 
     void refreshServices();
 
+    void refreshService( const Service& name );
+
     /**
-     * modify service, except name change
-     * ( you need remove and add if you want change name )
+     * modify service
      */
-    void modifyService(const Service& service) const;
+    void modifyService(const std::string& oldName, const Service& service);
+
+    struct MatchServiceName {
+      private:
+        std::string name;
+      public:
+        MatchServiceName( const std::string& name_ ) : name(name_) {}
+        bool match( const RepoInfo& info ) { return info.service()==name; }
+    };
+
+    /**
+     * fill to output iterator repositories in service name
+     */ 
+
+    template<typename OutputIterator>
+    void getRepositoriesInService( const std::string& name, OutputIterator out ) const
+    {
+      MatchServiceName filter(name);
+
+      std::copy(boost::make_filter_iterator(bind(&MatchServiceName::match, 
+          filter, _1),repoBegin(),repoEnd()), boost::make_filter_iterator(
+          bind(&MatchServiceName::match, filter, _1),repoEnd(),repoEnd()),
+          out );
+    }
 
   protected:
     RepoStatus rawMetadataStatus( const RepoInfo &info );
index 4852cfa..981e7c3 100644 (file)
@@ -24,13 +24,17 @@ namespace zypp
 
   class Service::Impl{
     public:
-      RepoContainer repos;
       string name;
       Url url;
       Pathname loc;
       Impl() : name("") {};
       Impl(const string& name_) : name(name_) {};
       Impl(const string& name_, const Url& url_) : name(name_), url(url_) {};
+    private:
+      friend Impl * rwcowClone<Impl>( const Impl * rhs );
+      /** clone for RWCOW_pointer */
+      Impl * clone() const
+      { return new Impl( *this ); }
   };
 
   Service::Service() : _pimpl( new Impl() ) {};
@@ -42,115 +46,27 @@ namespace zypp
   const Service Service::noService;
 
   string Service::name() const { return _pimpl->name; }
-  Url Service::url() const { return _pimpl->url; }
 
-  void Service::setUrl( const Url& url ) { _pimpl->url = url; }
+  void Service::setName( const std::string& name ) { _pimpl->name = name; }
 
-  bool Service::empty() const { return _pimpl->repos.empty(); }
-  Service::size_type Service::size() const { return _pimpl->repos.size(); }
-  Service::const_iterator Service::begin() const { return _pimpl->repos.begin(); }
-  Service::const_iterator Service::end() const { return _pimpl->repos.end(); }
+  Url Service::url() const { return _pimpl->url; }
 
-  void Service::addRepo( const std::string& alias )
-  {
-    _pimpl->repos.push_back(alias);
-  }
+  void Service::setUrl( const Url& url ) { _pimpl->url = url; }
 
   void Service::dumpServiceOn( std::ostream& str ) const
   {
     str << endl;
     str << "[" << name() << "]" << endl;
     str << "url = " << url() << endl;
-    for_( it, begin(), end() )
-    {
-      str << "alias = " << *it << endl;
-    }
     str << endl;
   }
 
-  void Service::refresh( RepoManager& repomanager ) const
-  {
-    //download index file
-    media::MediaManager mediamanager;
-    media::MediaAccessId mid = mediamanager.open( url() );
-    mediamanager.provideFile( mid, "repo/repoindex.xml" );
-    Pathname path = mediamanager.localPath(mid, "repo/repoindex.xml" );
-
-    //parse it
-    RepoInfoCollector collector;
-    parser::RepoindexFileReader reader( path,
-      bind( &RepoInfoCollector::collect, &collector, _1 ) );
-    mediamanager.close( mid );
-
-    bool ret = false;
-
-    // set base url for all collected repositories
-    for_( it, collector.repos.begin(), collector.repos.end())
-    {
-      it->setBaseUrl( url() );
-    }
-
-    //compare old and new repositories (hope not to much, if it change
-    // then construct set and use set operation on it)
-
-    std::list<RepoInfo> krepos = repomanager.knownRepositories();
-
-    //find old to remove
-    for_( it, begin(), end() )
-    {
-      bool found = false;
-
-      for_( it2, collector.repos.begin(), collector.repos.end() )
-        if ( *it == it2->alias() )
-        {
-          found = true;
-          break;
-        }
-
-      if( !found )
-      {
-        ret = true;
-        repomanager.removeRepository( repomanager.getRepositoryInfo( *it ) );
-      }
-    }
-
-    //find new to add
-    for_( it, collector.repos.begin(), collector.repos.end() )
-    {
-      bool found = false;
-
-      for_( it2, begin(), end() )
-        if( it->alias() == *it2 )
-        {
-          found = true;
-          break;
-        }
-
-      if (!found)
-      {
-        ret = true;
-        repomanager.addRepository( *it );
-      }
-    }
-
-    //update internal alias storage
-    if (ret)
-    {
-      _pimpl->repos.clear();
-      for_( it, collector.repos.begin(), collector.repos.end() )
-      {
-        _pimpl->repos.push_back(it->alias());
-      }
-      repomanager.modifyService(*this);
-    }
-  }
-
   Pathname Service::location() const
   {
     return _pimpl->loc;
   }
 
-  void Service::setLocation( const Pathname& location ) const
+  void Service::setLocation( const Pathname& location )
   {
     _pimpl->loc = location;
   }
index ced5093..a5def13 100644 (file)
@@ -29,11 +29,6 @@ namespace zypp
     class Service
     {
     public:
-        typedef std::vector<std::string> RepoContainer;
-        typedef RepoContainer::const_iterator const_iterator;
-        typedef RepoContainer::size_type size_type;
-
-    public:
         /** Default ctor creates \ref noService.*/
         Service();
 
@@ -60,54 +55,24 @@ namespace zypp
 
         Pathname location() const;
 
-        void setLocation( const Pathname& location ) const;
-
-        void setUrl( const Url& url );
-
     public:
 
-        /** Whether \ref Service contains solvables. */
-        bool empty() const;
-
-        /** Number of solvables in \ref Service. */
-        size_type size() const;
+        void setLocation( const Pathname& location );
 
-        /** Iterator to the first \ref Solvable. */
-        const_iterator begin() const;
+        void setUrl( const Url& url );
 
-        /** Iterator behind the last \ref Solvable. */
-        const_iterator end() const;
+        void setName( const std::string& name );
 
    public:
         /**
-         * Refreshes local information about service.
-         * It can addi, remove or modify repositories.
-         * it is const due to use Service in set or map and name doesn't change
-         */
-        void refresh( RepoManager& repomanager) const;
-
-        /**
          * Writes Service to stream in ".service" format
          */
         void dumpServiceOn( std::ostream & str ) const;
 
-        /**
-         * set repositories by alias.
-         * Used only during local loading, for update repository use refresh
-         */
-        template<typename InputIterator>
-        void setRepos(InputIterator begin, InputIterator end)
-        {
-          for_(it,begin,end)
-            addRepo(*it);
-        }
-
-        void addRepo(const std::string& alias);
-
         class Impl;
 
     private:
-        mutable RW_pointer<Impl> _pimpl;
+        RWCOW_pointer<Impl> _pimpl;
     };
     ///////////////////////////////////////////////////////////////////
 
index 0c4703d..d959f50 100644 (file)
@@ -74,6 +74,8 @@ namespace zypp
             info.setGpgCheck( str::strToTrue( it->second ) );
          else if ( it->first == "keeppackages" )
            info.setKeepPackages( str::strToTrue( it->second ) );
+         else if ( it->first == "service" )
+           info.setService( it->second );
           else
             ERR << "Unknown attribute " << it->second << " ignored" << endl;
         }
index d1d249f..e0972a5 100644 (file)
@@ -56,8 +56,6 @@ namespace zypp
           //MIL << (*it).first << endl;
           if (it->first == "url" )
             service.setUrl( Url (it->second) );
-          else if ( it->first == "alias" )
-            service.addRepo( it->second );
           else
             ERR << "Unknown attribute " << it->second << " ignored" << endl;
         }