Add class InstanceId: Build string to identify/retrieve a specific Solvable.
authorMichael Andres <ma@suse.de>
Wed, 22 Jul 2009 13:29:49 +0000 (15:29 +0200)
committerMichael Andres <ma@suse.de>
Wed, 22 Jul 2009 13:29:49 +0000 (15:29 +0200)
VERSION.cmake
package/libzypp.changes
tests/zypp/CMakeLists.txt
tests/zypp/InstanceId_test.cc [new file with mode: 0644]
zypp/CMakeLists.txt
zypp/InstanceId.cc [new file with mode: 0644]
zypp/InstanceId.h [new file with mode: 0644]

index 1722af7..fe672b2 100644 (file)
@@ -61,8 +61,8 @@
 SET(LIBZYPP_MAJOR "6")
 SET(LIBZYPP_COMPATMINOR "11")
 SET(LIBZYPP_MINOR "11")
-SET(LIBZYPP_PATCH "0")
+SET(LIBZYPP_PATCH "1")
 #
-# LAST RELEASED: 6.11.0 (11)
+# LAST RELEASED: 6.11.1 (11)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index e328b50..f5bbea6 100644 (file)
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Wed Jul 22 14:57:32 CEST 2009 - ma@suse.de
+
+- New class InstanceId to build strings to identify/retrieve specific 
+  Solvables.
+- version 6.11.1 (11)
+
+-------------------------------------------------------------------
 Mon Jul 20 23:57:46 CEST 2009 - ma@km13.de
 
 - Add download policies to ZYppCommitPolicy, supporting DownloadOnly
index 7d75796..ed43863 100644 (file)
@@ -15,6 +15,7 @@ ADD_TESTS(
   Edition
   Fetcher
   FileChecker
+  InstanceId
   KeyRing
   Locks
   MediaSetAccess
diff --git a/tests/zypp/InstanceId_test.cc b/tests/zypp/InstanceId_test.cc
new file mode 100644 (file)
index 0000000..248056b
--- /dev/null
@@ -0,0 +1,43 @@
+#include "TestSetup.h"
+#include "zypp/InstanceId.h"
+
+#define BOOST_TEST_MODULE InstanceId
+
+/////////////////////////////////////////////////////////////////////////////
+static TestSetup test( Arch_x86_64 );
+
+BOOST_AUTO_TEST_CASE(pool_query_init)
+{
+  // Abuse;) vbox as System repo:
+  test.loadTargetRepo( TESTS_SRC_DIR "/data/obs_virtualbox_11_1" );
+  test.loadRepo( TESTS_SRC_DIR "/data/openSUSE-11.1", "opensuse" );
+  test.loadRepo( TESTS_SRC_DIR "/data/OBS_zypp_svn-11.1", "zyppsvn" );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOST_AUTO_TEST_CASE(default_constructed)
+{
+  InstanceId instanceId;
+  BOOST_CHECK_EQUAL( instanceId.getNamespace(), std::string() );
+
+  BOOST_CHECK_EQUAL( instanceId.isSystemId( "System" ), false );
+  BOOST_CHECK_EQUAL( instanceId.isSystemId( "@System" ), true );
+
+  BOOST_CHECK_EQUAL( instanceId(""), PoolItem() );
+  BOOST_CHECK_EQUAL( instanceId(PoolItem()), "" );
+}
+
+BOOST_AUTO_TEST_CASE(convert)
+{
+  InstanceId instanceId;
+  instanceId.setNamespace( "SUSE" );
+  BOOST_CHECK_EQUAL( instanceId.getNamespace(), "SUSE" );
+
+  ResPool pool( ResPool::instance() );
+  for_( it, pool.begin(), pool.end() )
+  {
+    std::cout << instanceId(*it) << endl;
+    BOOST_CHECK_EQUAL( instanceId(instanceId(*it)), *it );
+  }
+}
index b61ef9c..07d12ef 100644 (file)
@@ -27,6 +27,7 @@ SET( zypp_SRCS
   HistoryLog.cc
   HistoryLogData.cc
   IdString.cc
+  InstanceId.cc
   KeyRing.cc
   Locks.cc
   MediaProducts.cc
@@ -108,6 +109,7 @@ SET( zypp_HEADERS
   HistoryLogData.h
   IdString.h
   IdStringType.h
+  InstanceId.h
   KeyContext.h
   KeyRing.h
   KVMap.h
diff --git a/zypp/InstanceId.cc b/zypp/InstanceId.cc
new file mode 100644 (file)
index 0000000..348b0de
--- /dev/null
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/InstanceId.cc
+ *
+*/
+//#include <iostream>
+//#include "zypp/base/LogTools.h"
+#include "zypp/base/String.h"
+
+#include "zypp/InstanceId.h"
+#include "zypp/ResPool.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+  std::string InstanceId::getIdFor( sat::Solvable slv_r ) const
+  {
+    if ( ! slv_r )
+      return std::string();
+
+    std::string ret( _namespace );
+    if ( ! ret.empty() )
+      ret += ':';
+
+    if ( slv_r.isKind<SrcPackage>() ) // satsolver uses no namespace in SrcPackage ident!
+    {
+      ret += ResKind::srcpackage.c_str();
+      ret += ':';
+    }
+
+    ret += str::form( "%s-%s-%s.%s@%s",
+                      slv_r.ident().c_str(),
+                      slv_r.edition().version().c_str(),
+                      slv_r.edition().release().c_str(),
+                      slv_r.arch().c_str(),
+                      slv_r.repository().alias().c_str() );
+    return ret;
+  }
+
+  PoolItem InstanceId::findPoolItem( const std::string str_r ) const
+  {
+    // [namespace:]<name>-<version>-<release>.<arch>@<repoalias>
+    std::string::size_type namespaceOff( _namespace.size() );
+
+    if ( namespaceOff )
+    {
+      if ( ! str::hasPrefix( str_r, _namespace ) || str_r[namespaceOff] != ':' )
+        return PoolItem();
+      ++namespaceOff; // for the ':'
+    }
+
+    // check repo
+    std::string::size_type rdelim( str_r.find( "@" ) );
+    if ( rdelim == std::string::npos )
+      return PoolItem();
+
+    Repository repo( sat::Pool::instance().reposFind( str_r.substr( rdelim+1) ) );
+    if ( ! repo )
+      return PoolItem();
+
+    // check n-v-r.a from behind
+    std::string::size_type delim = str_r.rfind( ".", rdelim );
+    if ( delim == std::string::npos )
+      return PoolItem();
+
+    Arch arch( str_r.substr( delim+1, rdelim-delim-1 ) );
+
+    // v-r starts at one but last '-'
+    rdelim = delim;
+    delim = str_r.rfind( "-", rdelim );
+    if ( delim == std::string::npos )
+      return PoolItem();
+
+    if ( delim == rdelim-1 ) // supress an empty release
+      rdelim = delim;
+
+    delim = str_r.rfind( "-", delim-1 );
+    if ( delim == std::string::npos )
+      return PoolItem();
+
+    Edition ed( str_r.substr( delim+1, rdelim-delim-1 ) );
+
+    // eveythig before is name (except the leading "<namespace>:")
+    std::string identstring( str_r.substr( namespaceOff, delim-namespaceOff ) );
+
+    // now lookup in pool..
+    sat::Solvable::SplitIdent ident( (IdString(identstring)) );
+    ResPool pool( ResPool::instance() );
+    for_( it, pool.byIdentBegin( ident.kind(), ident.name() ), pool.byIdentEnd( ident.kind(), ident.name() ) )
+    {
+      sat::Solvable solv( (*it).satSolvable() );
+      if ( solv.repository() == repo && solv.arch() == arch && solv.edition() == ed )
+      {
+        return *it;
+      }
+    }
+    return PoolItem();
+  }
+
+  bool InstanceId::isSystemId( const std::string str_r ) const
+  { return str::hasSuffix( str_r, Repository::systemRepoAlias() ); }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/InstanceId.h b/zypp/InstanceId.h
new file mode 100644 (file)
index 0000000..c7b745c
--- /dev/null
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/InstanceId.h
+ *
+*/
+#ifndef ZYPP_INSTANCEID_H
+#define ZYPP_INSTANCEID_H
+
+#include <string>
+
+#include "zypp/PoolItem.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  //
+  //   CLASS NAME : InstanceId
+  //
+  /**
+   * Build string to identify/retrieve a specific \a Solvable.
+   *
+   * <tt>"[<namespace>:]<name>-<version>-<release>.<arch>@<repoalias>"</tt>
+   *
+   * Any namespace that prepends the InstanceIds must be
+   * passed to the ctor. Conversion to/from instanceId can
+   * be done via function call \c operator().
+   *
+   * \code
+   *   InstanceId instanceId( "SUSE:" ); // using a namespace
+   *
+   *   ResPool pool( ResPool::instance() );
+   *   for_( it, pool.begin(), pool.end() )
+   *   {
+   *     std::cout << instanceId(*it) << endl;
+   *   }
+   * \endcode
+   */
+  class InstanceId
+  {
+    public:
+      /** Default ctor empty empty namespace */
+      InstanceId()
+      {}
+
+      /** Ctor taking namespace */
+      InstanceId( const std::string & namespace_r )
+      : _namespace( namespace_r )
+      {}
+
+    public:
+      /** \ref Solvable to \ref InstanceId string. */
+      std::string getIdFor( sat::Solvable slv_r ) const;
+      /** \ref PoolItem to \ref InstanceId string. */
+      std::string getIdFor( const PoolItem & pi_r ) const
+      { return getIdFor( pi_r.satSolvable() ); }
+
+      /** \ref InstanceId string to \ref Solvable. */
+      sat::Solvable findSolvable( const std::string str_r ) const
+      { return findPoolItem( str_r ).satSolvable(); }
+      /** \ref InstanceId string to \ref PoolItem. */
+      PoolItem findPoolItem( const std::string str_r ) const;
+
+    public:
+      /** \ref Solvable to \ref InstanceId string. */
+      std::string operator()( sat::Solvable slv_r ) const
+      { return getIdFor( slv_r ); }
+
+      /** \ref PoolItem to \ref InstanceId string. */
+      std::string operator()( const PoolItem & pi_r ) const
+      { return getIdFor( pi_r ); }
+
+      /** \ref InstanceId string to \ref PoolItem. */
+      PoolItem operator()( const std::string str_r ) const
+      { return findPoolItem( str_r ); }
+
+      /** Quick test whether the InstanceId string would refer
+       * to a system (installed) Solvable. */
+      bool isSystemId( const std::string str_r ) const;
+
+    public:
+      /** The namespace in use. */
+      const std::string & getNamespace() const
+      { return _namespace; }
+
+      /** Set a new namespace. */
+      void setNamespace( const std::string & namespace_r )
+      { _namespace = namespace_r; }
+
+      /** Set no (empty) namespace. */
+      void unsetNamespace()
+      { _namespace.clear(); }
+
+   private:
+      std::string _namespace;
+  };
+  /////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_INSTANCEID_H