From e10120e3a13f6850eaaf6442d5036da538e75c0e Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Mon, 7 Apr 2008 17:37:16 +0000 Subject: [PATCH] done LookupAttr, added ArrayAttr container to retrieve list attributes. --- zypp/Package.cc | 3 +- zypp/Package.h | 2 +- zypp/Patch.cc | 6 +- zypp/Patch.h | 6 +- zypp/Pattern.h | 3 + zypp/ResObject.h | 2 + zypp/sat/LookupAttr.cc | 232 ++++++++++++++++++++++++++++++++++++++-- zypp/sat/LookupAttr.h | 284 ++++++++++++++++++++++++++++++++++++++++++++----- zypp/sat/Pool.cc | 1 + zypp/sat/Solvable.h | 10 +- 10 files changed, 504 insertions(+), 45 deletions(-) diff --git a/zypp/Package.cc b/zypp/Package.cc index c0c3f78..fc888cc 100644 --- a/zypp/Package.cc +++ b/zypp/Package.cc @@ -66,9 +66,8 @@ namespace zypp std::string Package::group() const { return lookupStrAttribute( sat::SolvAttr::group ); } -#warning DUMMY keywords Package::Keywords Package::keywords() const - { return Keywords(); } + { return Keywords( sat::SolvAttr::keywords, satSolvable() ); } /** Don't ship it as class Url, because it might be * in fact anything but a legal Url. */ diff --git a/zypp/Package.h b/zypp/Package.h index 741d7ee..1f3a8e1 100644 --- a/zypp/Package.h +++ b/zypp/Package.h @@ -37,7 +37,7 @@ namespace zypp typedef TraitsType::constPtrType constPtr; public: - typedef std::set Keywords; + typedef sat::ArrayAttr Keywords; public: diff --git a/zypp/Patch.cc b/zypp/Patch.cc index 9954773..04dd40b 100644 --- a/zypp/Patch.cc +++ b/zypp/Patch.cc @@ -55,10 +55,10 @@ namespace zypp bool Patch::affects_pkg_manager() const { return false; } - Patch::AtomList Patch::atoms() const - { #warning Implement PATCH::ATOMS #if 0 + Patch::AtomList Patch::atoms() const + { if ( ! _atomlist ) { if ( ! hasBackRef() ) @@ -96,9 +96,9 @@ namespace zypp } } return *_atomlist; -#endif return AtomList(); } +#endif bool Patch::interactive() const { diff --git a/zypp/Patch.h b/zypp/Patch.h index 89cc887..74be85e 100644 --- a/zypp/Patch.h +++ b/zypp/Patch.h @@ -50,11 +50,13 @@ namespace zypp bool reboot_needed() const; /** Does the patch affect the package manager itself? */ bool affects_pkg_manager() const; - /** The list of all atoms building the patch */ - AtomList atoms() const; /** Is the patch installation interactive? (does it need user input?) */ bool interactive() const; + /** The list of all atoms building the patch */ + ZYPP_DEPRECATED AtomList atoms() const + { return AtomList(); } + protected: friend Ptr make( const sat::Solvable & solvable_r ); /** Ctor */ diff --git a/zypp/Pattern.h b/zypp/Pattern.h index 29277c8..0d634ac 100644 --- a/zypp/Pattern.h +++ b/zypp/Pattern.h @@ -36,6 +36,9 @@ namespace zypp typedef TraitsType::constPtrType constPtr; public: + typedef sat::ArrayAttr NameList; + + public: /** */ bool isDefault() const; /** */ diff --git a/zypp/ResObject.h b/zypp/ResObject.h index 844cbae..81295ce 100644 --- a/zypp/ResObject.h +++ b/zypp/ResObject.h @@ -23,6 +23,8 @@ #include "zypp/OnMediaLocation.h" #include "zypp/Repository.h" +#include "zypp/sat/LookupAttr.h" + #include "zypp/TranslatedText.h" /////////////////////////////////////////////////////////////////// diff --git a/zypp/sat/LookupAttr.cc b/zypp/sat/LookupAttr.cc index dcfb001..6d23c8a5 100644 --- a/zypp/sat/LookupAttr.cc +++ b/zypp/sat/LookupAttr.cc @@ -11,11 +11,15 @@ */ #include #include +#include + #include "zypp/base/Logger.h" +#include "zypp/base/String.h" #include "zypp/sat/detail/PoolImpl.h" #include "zypp/sat/LookupAttr.h" +#include "zypp/CheckSum.h" using std::endl; @@ -56,6 +60,9 @@ namespace zypp return iterator(); } + bool LookupAttr::empty() const + { return begin() == end(); } + std::ostream & operator<<( std::ostream & str, const LookupAttr & obj ) { if ( obj.attr() == SolvAttr::noAttr ) @@ -89,6 +96,10 @@ namespace zypp // /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + // position and moving + /////////////////////////////////////////////////////////////////// + Repository LookupAttr::iterator::inRepo() const { return Repository( _dip->repo ); } @@ -98,9 +109,6 @@ namespace zypp SolvAttr LookupAttr::iterator::inSolvAttr() const { return SolvAttr( _dip->key->name ); } - detail::IdType LookupAttr::iterator::solvAttrType() const - { return _dip->key->type; } - void LookupAttr::iterator::nextSkipSolvAttr() { ::dataiterator_skip_attribute( _dip.get() ); } @@ -111,9 +119,216 @@ namespace zypp { ::dataiterator_skip_repo( _dip.get() ); } /////////////////////////////////////////////////////////////////// + // attr value type test + /////////////////////////////////////////////////////////////////// + + detail::IdType LookupAttr::iterator::solvAttrType() const + { return _dip->key->type; } + + bool LookupAttr::iterator::solvAttrNumeric() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_U32: + case REPOKEY_TYPE_NUM: + case REPOKEY_TYPE_CONSTANT: + return true; + break; + } + return false; + } + + bool LookupAttr::iterator::solvAttrString() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_CONSTANTID: + case REPOKEY_TYPE_STR: + case REPOKEY_TYPE_DIRSTRARRAY: + return true; + break; + } + return false; + } + + bool LookupAttr::iterator::solvAttrIdString() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_CONSTANTID: + return true; + break; + } + return false; + } + + bool LookupAttr::iterator::solvAttrCheckSum() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_MD5: + case REPOKEY_TYPE_SHA1: + case REPOKEY_TYPE_SHA256: + return true; + break; + } + return false; + } + + /////////////////////////////////////////////////////////////////// + // attr value type test + /////////////////////////////////////////////////////////////////// + + int LookupAttr::iterator::asInt() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_U32: + case REPOKEY_TYPE_NUM: + case REPOKEY_TYPE_CONSTANT: + return _dip->kv.num; + break; + } + return 0; + } + + unsigned LookupAttr::iterator::asUnsigned() const + { return asInt(); } + + bool LookupAttr::iterator::asBool() const + { return asInt(); } + + + const char * LookupAttr::iterator::c_str() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_CONSTANTID: + if ( _dip->data && _dip->data->localpool ) + return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool + else + return IdString( _dip->kv.id ).c_str(); // in global pool + break; + + case REPOKEY_TYPE_STR: + return _dip->kv.str; + break; + + case REPOKEY_TYPE_DIRSTRARRAY: + return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str ); + break; + } + return 0; + } + + std::string LookupAttr::iterator::asString() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_CONSTANTID: + case REPOKEY_TYPE_STR: + case REPOKEY_TYPE_DIRSTRARRAY: + { + const char * ret( c_str() ); + return ret ? ret : ""; + } + break; + + case REPOKEY_TYPE_U32: + case REPOKEY_TYPE_NUM: + case REPOKEY_TYPE_CONSTANT: + return str::numstring( asInt() ); + break; + + case REPOKEY_TYPE_MD5: + case REPOKEY_TYPE_SHA1: + case REPOKEY_TYPE_SHA256: + { + std::ostringstream str; + str << asCheckSum(); + return str.str(); + } + break; + } + return std::string(); + } + + IdString LookupAttr::iterator::idStr() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_ID: + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_CONSTANTID: + return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) ); + break; + } + return IdString(); + } + + CheckSum LookupAttr::iterator::asCheckSum() const + { + switch ( solvAttrType() ) + { + case REPOKEY_TYPE_MD5: + return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); + break; + + case REPOKEY_TYPE_SHA1: + return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); + break; + + case REPOKEY_TYPE_SHA256: + return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) ); + break; + } + return CheckSum(); + } + + /////////////////////////////////////////////////////////////////// // internal stuff below /////////////////////////////////////////////////////////////////// + LookupAttr::iterator::~iterator() + {} + + LookupAttr::iterator::iterator() + : iterator_adaptor_( 0 ) + {} + + LookupAttr::iterator::iterator( const iterator & rhs ) + : iterator_adaptor_( cloneFrom( rhs.base() ) ) + , _dip( base() ) + {} + + LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs ) + { + if ( &rhs != this ) + { + _dip.reset( cloneFrom( rhs.base() ) ); + base_reference() = _dip.get(); + } + return *this; + } + + LookupAttr::iterator::iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r ) + : iterator_adaptor_( dip_r.get() ) + , _chainRepos( chain_r ) + { + _dip.swap( dip_r ); // take ownership! + increment(); + } + + /////////////////////////////////////////////////////////////////// + ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs ) { if ( ! rhs ) @@ -163,10 +378,13 @@ namespace zypp if ( ! dip ) return str << "EndOfQuery" << endl; - str << obj.inSolvable() - << '<' << obj.inSolvAttr() - << "> = " << obj.solvAttrType() - << "(" << dip->kv.id << ")" << (dip->data && dip->data->localpool ? "*" : "" ); + if ( obj.inSolvable() ) + str << obj.inSolvable(); + else if ( obj.inRepo() ) + str << obj.inRepo(); + + str << '<' << obj.inSolvAttr() + << ">(" << obj.solvAttrType() << ") = " << obj.asString(); return str; } diff --git a/zypp/sat/LookupAttr.h b/zypp/sat/LookupAttr.h index 1a3f132..89f1ae7 100644 --- a/zypp/sat/LookupAttr.h +++ b/zypp/sat/LookupAttr.h @@ -20,6 +20,7 @@ struct _Dataiterator; #include "zypp/base/PtrTypes.h" #include "zypp/base/DefaultIntegral.h" + #include "zypp/sat/Pool.h" /////////////////////////////////////////////////////////////////// @@ -33,17 +34,40 @@ namespace zypp // // CLASS NAME : LookupAttr // - /** Lightweight attribute lookup. + /** Lightweight attribute value lookup. * - * Search for an attribute \ref Pool, one \ref Repository or - * one \ref Solvable. \ref LookupAttr builds the query, + * Search for an attribute in \ref Pool, one \ref Repository + * or one \ref Solvable. \ref LookupAttr builds the query, * \ref LookupAttr::iterator iterates over the result. * * Modifying the query will not affect any running * iterator. * * Use \ref SolvAttr::allAttr to search all attributes. - */ + * + * \code + * // look for all attributes of one solvable + * void ditest( sat::Solvable slv_r ) + * { + * sat::LookupAttr q( sat::SolvAttr::allAttr, slv_r ); + * MIL << q << ": " << endl; + * for_( it, q.begin(), q.end() ) + * { + * MIL << " " << it.inSolvAttr() << " = " << it.asString() << endl; + * } + * } + * \endcode + * + * \code + * // look for an attribute in the pool. + * sat::LookupAttr q( sat::SolvAttr("susetags:datadir") ); + * MIL << q << ": " << endl; + * for_( it, q.begin(), q.end() ) + * { + * MIL << " " << it << endl; + * } + * \endcode + */ class LookupAttr { public: @@ -77,7 +101,13 @@ namespace zypp /** Iterator behind the end of query results. */ iterator end() const; + /** Whether the query is empty. */ + bool empty() const; + + /** TransformIterator returning an \ref iterator vaue of type \c _ResultT. */ + template class transformIterator; //@} + public: /** \name What to search. */ //@{ @@ -192,46 +222,74 @@ namespace zypp /** The current \ref SolvAttr. */ SolvAttr inSolvAttr() const; + //@} + /** \name Test attribute value type. */ + //@{ /** The current \ref SolvAttr type. */ detail::IdType solvAttrType() const; + + /** Whether this is a numeric attribute (incl. boolean). */ + bool solvAttrNumeric() const; + + /** Whether this is a string attribute. */ + bool solvAttrString() const; + + /** *Whether this string attribute is available as \ref IdString. */ + bool solvAttrIdString() const; + + /** Whether this is a CheckSum attribute.*/ + bool solvAttrCheckSum() const; //@} /** \name Retrieving attribute values. */ //@{ + /** Conversion to numeric types. */ + int asInt() const; + /** \overload */ + unsigned asUnsigned() const; + /** \overload */ + bool asBool() const; + + /** Conversion to string types. */ + const char * c_str() const; + /** \overload + * If used with non-string types, this method tries to create + * some appropriate string representation. + */ + std::string asString() const; + + /** As \ref IdStr. + * This is only done for poolized string types. Large strings like + * summary or descriptions are not available via \ref IdStr, only + * via \ref c_str and \ref asString. + */ + IdString idStr() const; + + /** As \ref CheckSum. */ + CheckSum asCheckSum() const; + + /** Templated return type. + * Specialized for supported types. + */ + template _Tp asType() const; //@} + /////////////////////////////////////////////////////////////////// // internal stuff below /////////////////////////////////////////////////////////////////// public: - iterator() - : iterator_adaptor_( 0 ) - {} + iterator(); - iterator( const iterator & rhs ) - : iterator_adaptor_( cloneFrom( rhs.base() ) ) - , _dip( base() ) - {} + iterator( const iterator & rhs ); - iterator & operator=( const iterator & rhs ) - { - if ( &rhs != this ) - { - _dip.reset( cloneFrom( rhs.base() ) ); - base_reference() = _dip.get(); - } - return *this; - } + iterator & operator=( const iterator & rhs ); + + ~iterator(); private: friend class LookupAttr; - iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r ) - : iterator_adaptor_( dip_r.get() ) - , _chainRepos( chain_r ) - { - _dip.swap( dip_r ); // take ownership! - increment(); - } + iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r ); ::_Dataiterator * cloneFrom( const ::_Dataiterator * rhs ); @@ -264,6 +322,178 @@ namespace zypp /** \relates LookupAttr::iterator Stream output. */ std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj ); + template<> inline int LookupAttr::iterator::asType() const { return asInt(); } + template<> inline unsigned LookupAttr::iterator::asType() const { return asUnsigned(); } + template<> inline bool LookupAttr::iterator::asType() const { return asBool(); } + template<> inline const char * LookupAttr::iterator::asType() const { return c_str(); } + template<> inline std::string LookupAttr::iterator::asType() const { return asString(); } + template<> inline IdString LookupAttr::iterator::asType() const { return idStr(); } + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : LookupAttr::transformIterator + // + /** TransformIterator returning an \ref iterator value of type \c _ResultT. + * + * The underlying LookupAttr::iterators value is retrieved \ref asType<_AttrT> + * and the returned \ref ResultT is constructed fron that value. + * + * \code + * class Keywords + * { + * public: + * Keywords( sat::Solvable solv_r ) + * : _q( sat::SolvAttr::keywords, solv_r ) + * {} + * + * public: + * typedef sat::LookupAttr::transformIterator iterator; + * + * iterator begin() const { return iterator( _q.begin() ); } + * iterator end() const { return iterator( _q.end() ); } + * + * private: + * sat::LookupAttr _q; + * }; + * \endcode + * + * \see \ref ArrayAttr. + */ + template + class LookupAttr::transformIterator : public boost::iterator_adaptor< + transformIterator<_ResultT,_AttrT> // Derived + , LookupAttr::iterator // Base + , _ResultT // Value + , boost::forward_traversal_tag // CategoryOrTraversal + , _ResultT // Reference + > + { + public: + transformIterator() + {} + + explicit + transformIterator( const LookupAttr::iterator & val_r ) + { this->base_reference() = val_r; } + + public: + + /** \name Moving fast forward. */ + //@{ + /** On the next call to \ref operator++ advance to the next \ref SolvAttr. */ + void nextSkipSolvAttr() + { this->base_reference().nextSkipSolvAttr(); } + + /** On the next call to \ref operator++ advance to the next \ref Solvable. */ + void nextSkipSolvable() + { this->base_reference().nextSkipSolvable(); } + + /** On the next call to \ref operator++ advance to the next \ref Repository. */ + void nextSkipRepo() + { this->base_reference().nextSkipRepo(); } + + /** Immediately advance to the next \ref SolvAttr. */ + void skipSolvAttr() + { this->base_reference().skipSolvAttr(); } + + /** Immediately advance to the next \ref Solvable. */ + void skipSolvable() + { this->base_reference().skipSolvable(); } + + /** Immediately advance to the next \ref Repository. */ + void skipRepo() + { this->base_reference().skipRepo(); } + //@} + + /** \name Current position info. */ + //@{ + /** The current \ref Repository. */ + Repository inRepo() const + { return this->base_reference().inRepo(); } + + /** The current \ref Solvabele. */ + Solvable inSolvable() const + { return this->base_reference().inSolvable(); } + + /** The current \ref SolvAttr. */ + SolvAttr inSolvAttr() const + { return this->base_reference().inSolvAttr(); } + //@} + + private: + friend class boost::iterator_core_access; + + _ResultT dereference() const + { + const LookupAttr::iterator lit( this->base_reference() ); + return _ResultT( lit.asType<_AttrT>() ); + } + }; + /////////////////////////////////////////////////////////////////// + + template + class ArrayAttr; + + template + std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj ); + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : ArrayAttr + // + /** \ref LookupAttr::transformIterator based container to retrieve list attributes. + * + * \code + * typedef ArrayAttr Keywords; + * Keywords k( sat::SolvAttr::keywords ); + * dumpRange( MIL << "All Keywords: ", k.begin(), k.end() ) << endl; + * \endcode + * + * \todo Maybe add some way to unify the result. + */ + template + class ArrayAttr + { + friend std::ostream & operator<< <_ResultT,_AttrT>( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj ); + + public: + ArrayAttr() + {} + + ArrayAttr( SolvAttr attr_r ) + : _q( attr_r ) + {} + + ArrayAttr( SolvAttr attr_r, Repository repo_r ) + : _q( attr_r, repo_r ) + {} + + ArrayAttr( SolvAttr attr_r, Solvable solv_r ) + : _q( attr_r, solv_r ) + {} + + public: + typedef sat::LookupAttr::transformIterator<_ResultT,_AttrT> iterator; + + iterator begin() const + { return iterator( _q.begin() ); } + + iterator end() const + { return iterator( _q.end() ); } + + bool empty() const + { return _q.empty(); } + + private: + sat::LookupAttr _q; + }; + /////////////////////////////////////////////////////////////////// + + /** \relates LookupAttr::iterator Stream output. */ + template + inline std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj ) + { return dumpOn( str, obj._q); } + ///////////////////////////////////////////////////////////////// } // namespace sat /////////////////////////////////////////////////////////////////// diff --git a/zypp/sat/Pool.cc b/zypp/sat/Pool.cc index 910ea88..612e524 100644 --- a/zypp/sat/Pool.cc +++ b/zypp/sat/Pool.cc @@ -26,6 +26,7 @@ extern "C" #include "zypp/sat/detail/PoolImpl.h" #include "zypp/sat/Pool.h" +#include "zypp/sat/LookupAttr.h" /////////////////////////////////////////////////////////////////// namespace zypp diff --git a/zypp/sat/Solvable.h b/zypp/sat/Solvable.h index e3fc92e..07e39be 100644 --- a/zypp/sat/Solvable.h +++ b/zypp/sat/Solvable.h @@ -86,6 +86,11 @@ namespace zypp public: + /** \name Attribute lookup. + * \see \ref LookupAttr and \ref ArrayAttr providing a general, more + * query like interface for attribute retrieval. + */ + //@{ /** * returns the string attribute value for \ref attr * or an empty string if it does not exists. @@ -121,8 +126,6 @@ namespace zypp */ detail::IdType lookupIdAttribute( const SolvAttr & attr ) const; - - /** * returns the CheckSum attribute value for \ref attr * or an empty CheckSum if ir does not exist. @@ -135,6 +138,7 @@ namespace zypp */ OnMediaLocation lookupLocation() const; + //@} public: /** The identifier. * This is the solvables \ref name, \b except for packages and @@ -177,7 +181,7 @@ namespace zypp /** Returns true if the solvable is satisfied */ bool isSatisfied() const; /** Returns true if the solvable is satisfied */ - bool isBroken() const { return !isSatisfied(); } + bool isBroken() const { return !isSatisfied(); } public: /** \name Locale support. */ -- 2.7.4