Add support for accessing/iterating sub-structures (REPOKEY_TYPE_FLEXARRAY).
authorMichael Andres <ma@suse.de>
Fri, 7 Nov 2008 20:42:52 +0000 (20:42 +0000)
committerMichael Andres <ma@suse.de>
Fri, 7 Nov 2008 20:42:52 +0000 (20:42 +0000)
tests/sat/LookupAttr_test.cc
zypp/sat/LookupAttr.cc
zypp/sat/LookupAttr.h

index 1b06423..636520d 100644 (file)
@@ -2,8 +2,6 @@
 #include <zypp/sat/LookupAttr.h>
 #include <zypp/ResObjects.h>
 
-#include <zypp/sat/detail/PoolImpl.h>
-
 #define LABELED(V) #V << ":\t" << V
 
 static TestSetup test( "/tmp/x", Arch_x86_64 );
@@ -145,71 +143,37 @@ BOOST_AUTO_TEST_CASE(LookupAttr_itetate_all_attributes)
  }
 }
 
-BOOST_AUTO_TEST_CASE(LookupAttr_solvable_attribute_types)
+BOOST_AUTO_TEST_CASE(LookupAttr_solvable_attribute_substructure)
 {
-  base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "/tmp/YLOG" ) );
-  MIL << "GO" << endl;
-
-  ResPool pool( test.pool() );
-  for_( it, pool.byKindBegin<Patch>(), pool.byKindEnd<Patch>() )
+  sat::LookupAttr q( sat::SolvAttr::updateReference );
+  BOOST_CHECK_EQUAL( q.size(), 303 );
+  for_( res, q.begin(), q.end() )
   {
-    Patch::constPtr p( (*it)->asKind<Patch>() );
-    USR << p << endl;
+    BOOST_CHECK( ! res.subEmpty() );
+    BOOST_CHECK_EQUAL( res.subSize(), 4 );
 
-    sat::LookupAttr q( sat::SolvAttr::allAttr, p->satSolvable() );
-    //sat::LookupAttr q( sat::SolvAttr("update:reference") );
-    for_( res, q.begin(), q.end() )
-    {
-      if ( //res.inSolvAttr() == sat::SolvAttr("update:reference") &&
-           res.solvAttrType() == IdString("repokey:type:flexarray").id() )
-      {
-        MIL << res << endl;
-        DBG << *res << endl;
-        ::_Dataiterator * dip = res.get();
-        INT << dip << endl;
-
-        ::dataiterator_setpos( dip );
-
-        ::Dataiterator di2;
-        ::dataiterator_init( &di2
-            , sat::Pool::instance().get()
-            , 0
-            , SOLVID_POS
-            , 0
-            , 0
-            , 0 );
-
-        while ( ::dataiterator_step( &di2 ) )
-        {
-          DBG << di2 << endl;
-        }
-      }
-    }
-    break;
-  }
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::allAttr ), res.subBegin() );
+    BOOST_CHECK_EQUAL( res.subFind( "" ),                     res.subBegin() );
 
-  {
-    sat::LookupAttr q( sat::SolvAttr("update:reference") );
-    USR << q << " " << q.size() << endl;
-  }
-  {
-    sat::LookupAttr q( sat::SolvAttr("update:reference:href") );
-    USR << q << " " << q.size() << endl;
-  }
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::updateReference ), res.subEnd() );
+    BOOST_CHECK_EQUAL( res.subFind( "noval" ),                        res.subEnd() );
 
+    BOOST_CHECK_NE( res.subFind( sat::SolvAttr::updateReferenceType ),  res.subEnd() );
+    BOOST_CHECK_NE( res.subFind( sat::SolvAttr::updateReferenceHref ),  res.subEnd() );
+    BOOST_CHECK_NE( res.subFind( sat::SolvAttr::updateReferenceId ),    res.subEnd() );
+    BOOST_CHECK_NE( res.subFind( sat::SolvAttr::updateReferenceTitle ), res.subEnd() );
 
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::updateReferenceType ),  res.subFind( "type" ) );
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::updateReferenceHref ),  res.subFind( "href" ) );
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::updateReferenceId ),    res.subFind( "id" ) );
+    BOOST_CHECK_EQUAL( res.subFind( sat::SolvAttr::updateReferenceTitle ), res.subFind( "title" ) );
+  }
 }
 
-
+#if 0
 BOOST_AUTO_TEST_CASE(LookupAttr_)
 {
   base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "/tmp/YLOG" ) );
   MIL << "GO" << endl;
 }
-
-
-
-
-
-
-
+#endif
index 54bc632..26ee22e 100644 (file)
@@ -9,7 +9,6 @@
 /** \file      zypp/sat/LookupAttr.cc
  *
 */
-#include <cstring>
 #include <iostream>
 #include <sstream>
 
 
 using std::endl;
 
-#if 0
-#  undef  XXX
-#  define XXX MIL
-#  define XXD DBG
-#  define XXM MIL
-#  define XXW WAR
-#  define XXE ERR
-#  define XXS SEC
-#  define XXI INT
-#  define XXU USR
-#  warning Remove dummy debug output defines
-#else
-#  define XXD XXX
-#  define XXM XXX
-#  define XXW XXX
-#  define XXE XXX
-#  define XXS XXX
-#  define XXI XXX
-#  define XXU XXX
-#endif
-
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -206,6 +184,71 @@ namespace zypp
       return false;
     }
 
+    bool LookupAttr::iterator::solvAttrSubEntry() const
+    {
+      return solvAttrType() == REPOKEY_TYPE_FLEXARRAY;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    // Iterate sub-structures.
+    ///////////////////////////////////////////////////////////////////
+
+    bool LookupAttr::iterator::subEmpty() const
+    { return( subBegin() == subEnd() ); }
+
+    LookupAttr::size_type LookupAttr::iterator::subSize() const
+    {
+      size_type c = 0;
+      for_( it, subBegin(), subEnd() )
+        ++c;
+      return c;
+    }
+
+    LookupAttr::iterator LookupAttr::iterator::subBegin() const
+    {
+      if ( ! solvAttrSubEntry() )
+        return subEnd();
+
+      // remember this position
+      ::dataiterator_setpos( _dip.get() );
+
+      // setup the new sub iterator
+      scoped_ptr< ::_Dataiterator> dip( new ::Dataiterator );
+      // needed while LookupAttr::iterator::dip_equal does ::memcmp:
+      ::memset( dip.get(), 0, sizeof(::_Dataiterator) );
+
+      ::dataiterator_init( dip.get(), sat::Pool::instance().get(), 0, SOLVID_POS, 0, 0, 0 );
+
+      return iterator( dip ); // iterator takes over ownership!
+    }
+
+    LookupAttr::iterator LookupAttr::iterator::subEnd() const
+    {
+      return iterator();
+    }
+
+    LookupAttr::iterator LookupAttr::iterator::subFind( SolvAttr attr_r ) const
+    {
+      iterator it = subBegin();
+      if ( attr_r != sat::SolvAttr::allAttr )
+      {
+        while ( it != subEnd() && it.inSolvAttr() != attr_r )
+          ++it;
+      }
+      return it;
+    }
+
+    LookupAttr::iterator LookupAttr::iterator::subFind( const C_Str & attrname_r ) const
+    {
+      if ( attrname_r.empty() )
+        return subBegin();
+
+      std::string subattr( inSolvAttr().asString() );
+      subattr += ":";
+      subattr += attrname_r;
+      return subFind( SolvAttr( subattr ) );
+    }
+
     ///////////////////////////////////////////////////////////////////
     // attr value retrieval
     ///////////////////////////////////////////////////////////////////
@@ -271,11 +314,11 @@ namespace zypp
           case REPOKEY_TYPE_CONSTANTID:
           case REPOKEY_TYPE_STR:
           case REPOKEY_TYPE_DIRSTRARRAY:
-          {
-            const char * ret( c_str() );
-            return ret ? ret : "";
-          }
-          break;
+            {
+              const char * ret( c_str() );
+              return ret ? ret : "";
+            }
+            break;
 
           case REPOKEY_TYPE_U32:
           case REPOKEY_TYPE_NUM:
@@ -286,12 +329,20 @@ namespace zypp
           case REPOKEY_TYPE_MD5:
           case REPOKEY_TYPE_SHA1:
           case REPOKEY_TYPE_SHA256:
-          {
-            std::ostringstream str;
-            str << asCheckSum();
-            return str.str();
-          }
-          break;
+            {
+              return asCheckSum().asString();
+            }
+            break;
+
+          case REPOKEY_TYPE_FLEXARRAY:
+            {
+              std::ostringstream str;
+              dumpRange( str,
+                         transformIterator<std::string>( subBegin() ),
+                         transformIterator<std::string>( subEnd() ) );
+              return str.str();
+            }
+            break;
         }
       }
       return std::string();
index c697639..33261b5 100644 (file)
@@ -113,13 +113,12 @@ namespace zypp
         size_type size() const;
 
         /** TransformIterator returning an \ref iterator vaue of type \c _ResultT. */
-        template<class _ResultT, class _AttrT> class transformIterator;
+        template<class _ResultT, class _AttrT = _ResultT> class transformIterator;
         //@}
 
       public:
         /** \name What to search. */
         //@{
-
         /** The \ref SolvAttr to search. */
         SolvAttr attr() const
         { return _attr; }
@@ -127,8 +126,8 @@ namespace zypp
         /** Set the \ref SolvAttr to search. */
         void setAttr( SolvAttr attr_r )
         { _attr = attr_r; }
-
         //@}
+
       public:
         /** \name Where to search. */
         //@{
@@ -164,8 +163,8 @@ namespace zypp
           _repo = Repository::noRepository;
           _solv = solv_r;
         }
-
         //@}
+
       private:
         SolvAttr   _attr;
         Repository _repo;
@@ -248,6 +247,66 @@ namespace zypp
 
         /** Whether this is a CheckSum attribute.*/
         bool solvAttrCheckSum() const;
+
+        /** Whether this is the entry to a sub-structure (flexarray).
+         * This is the entry to a sequence of attributes. To
+         * acces them use \ref subBegin and  \ref subEnd.
+        */
+        bool solvAttrSubEntry() const;
+        //@}
+
+        /** \name Iterate sub-structures.
+         *
+         * These are usable iff \ref solvAttrSubEntry is \c true.
+         *
+         * \code
+         * // Lookup all "update:reference" entries for a specific solvable
+         * sat::LookupAttr q( sat::SolvAttr::updateReference, p->satSolvable() );
+         * for_( res, q.begin(), q.end() )
+         * {
+         *   // List all sub values
+         *   for_( sub, res.subBegin(), res.subEnd() )
+         *   {
+         *     cout << sub.asString() << endl;
+         *   }
+         *
+         *   // Directly access c specific value:
+         *   sat::LookupAttr::iterator it( res.subFind( sat::SolvAttr::updateReferenceHref ) );
+         *   if ( it != res.subEnd() )
+         *     cout << it.asString() << endl;
+         * }
+         * \endcode
+         */
+        //@{
+        /** Wheter the sub-structure is empty. */
+        bool subEmpty() const;
+
+        /** Ammount of attributes in the sub-structure.
+         * \note This is not a cheap call. It runs the query.
+        */
+        size_type subSize() const;
+
+        /** Iterator to the begin of a sub-structure.
+         * \see \ref solvAttrSubEntry
+        */
+        iterator subBegin() const;
+        /** Iterator behind the end of a sub-structure.
+         * \see \ref solvAttrSubEntry
+        */
+        iterator subEnd() const;
+         /** Iterator pointing to the first occurance of \ref SolvAttr \a attr_r in sub-structure.
+          * If \ref sat::SolvAttr::allAttr is passed, \ref subBegin is returned.
+          * \see \ref solvAttrSubEntry
+         */
+        iterator subFind( SolvAttr attr_r ) const;
+        /** \overload Extending the current attribute name with by \c ":attrname_r".
+         *
+         * This assumes a sub-structur \c "update:reference" has attributes
+         * like \c "update:reference:type", \c "update:reference:href".
+         *
+         * If an empty \c attrname_r is passed, \ref subBegin is returned.
+        */
+        iterator subFind( const C_Str & attrname_r ) const;
         //@}
 
         /** \name Retrieving attribute values. */