#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 );
}
}
-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
/** \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
{ /////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////
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:
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();
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; }
/** Set the \ref SolvAttr to search. */
void setAttr( SolvAttr attr_r )
{ _attr = attr_r; }
-
//@}
+
public:
/** \name Where to search. */
//@{
_repo = Repository::noRepository;
_solv = solv_r;
}
-
//@}
+
private:
SolvAttr _attr;
Repository _repo;
/** 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. */