}
/////////////////////////////////////////////////////////////////////////////
+static std::ofstream devNull;
+#define COUT devNull
+
struct PrintAndCount
{
PrintAndCount() : _count(0) {}
bool operator()( const sat::Solvable & solvable )
{
zypp::PoolItem pi( zypp::ResPool::instance().find( solvable ) );
- cout << pi.resolvable() << endl;
+ COUT << pi.resolvable() << endl;
++_count;
return true;
}
BOOST_AUTO_TEST_CASE(pool_query_equal)
{
cout << "****equal****" << endl;
- PoolQuery q;
- q.addString("zypp");
- q.addAttribute(sat::SolvAttr::name);
- q.setMatchGlob();
- PoolQuery q2;
- q2.addString("zypp");
- q2.addAttribute(sat::SolvAttr::name);
- q2.setMatchGlob();
- PoolQuery q3;
- q3.addString("zypp");
- q3.addAttribute(sat::SolvAttr::name);
- q3.setMatchGlob();
- q3.setRequireAll(true);
- PoolQuery q4;
- q4.addAttribute(sat::SolvAttr::name,"zypp");
- q4.setMatchGlob();
-
- BOOST_CHECK(q==q2);
- BOOST_CHECK(q!=q3);
- BOOST_CHECK(q==q4);
- BOOST_CHECK(q4!=q3);
+ std::vector<PoolQuery> v;
+ {
+ PoolQuery q;
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addAttribute( sat::SolvAttr::name, "zypper" );
+ q.setMatchExact();
+ q.setCaseSensitive(true);
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addAttribute( sat::SolvAttr::name, "libzypp" ); // different
+ q.setMatchExact();
+ q.setCaseSensitive(true);
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addAttribute( sat::SolvAttr::vendor, "zypper" ); // different
+ q.setMatchExact();
+ q.setCaseSensitive(true);
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addAttribute( sat::SolvAttr::name, "zypper" );
+ q.setMatchExact();
+ q.setCaseSensitive(false); // different
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addAttribute( sat::SolvAttr::name, "zypper" );
+ q.setMatchSubstring(); // different
+ q.setCaseSensitive(true);
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addDependency( sat::SolvAttr::provides, "zypper" );
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addDependency( sat::SolvAttr::provides, "zypper", Rel::GT, Edition("1.0") );
+ v.push_back( q );
+ }
+ {
+ PoolQuery q;
+ q.addDependency( sat::SolvAttr::provides, "zypper", Rel::GT, Edition("2.0") );
+ v.push_back( q );
+ }
+
+ for_( li, 0U, v.size() )
+ {
+ for_( ri, 0U, v.size() )
+ {
+ COUT << li << " <> " << ri << endl;
+ bool equal( v[li] == v[ri] );
+ bool nequal( v[li] != v[ri] );
+ BOOST_CHECK_EQUAL( equal, li==ri );
+ BOOST_CHECK_EQUAL( equal, !nequal );
+ }
+ }
}
/////////////////////////////////////////////////////////////////////////////
* As the \ref predicate takes an iterator pointing to the current
* match, it's also suitable for sub-structure (flexarray) inspection
* (\see \ref sat::LookupAttr::iterator::solvAttrSubEntry).
+ *
+ * \note: \see \ref addPredicate for further constraints.
*/
struct AttrMatchData
{
, attrMatcher( attrMatcher_r )
{}
- AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r, const Predicate & predicate_r )
+ AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r,
+ const Predicate & predicate_r, const std::string & predicateStr_r )
: attr( attr_r )
, attrMatcher( attrMatcher_r )
, predicate( predicate_r )
+ , predicateStr( predicateStr_r )
{}
+ /** A usable Predicate must provide a string representation.
+ * As there is no \c operator== for \ref Predicate, we compare it's
+ * string representation instead. Actually Predicate deserves to become
+ * a class which is also serializable, so we can store predicated queries.
+ */
+ template<class _Predicate>
+ void addPredicate( const _Predicate & predicate_r )
+ {
+ predicate = predicate_r;
+ predicateStr = predicate_r.stringRep();
+ }
+
sat::SolvAttr attr;
sat::AttrMatcher attrMatcher;
Predicate predicate;
+ std::string predicateStr;
};
- std::ostream & operator<<( std::ostream & str, const AttrMatchData & obj )
+ /** \relates AttrMatchData */
+ inline std::ostream & operator<<( std::ostream & str, const AttrMatchData & obj )
+ {
+ str << obj.attr << ": " << obj.attrMatcher;
+ if ( obj.predicate )
+ str << " +(" << obj.predicateStr << ")";
+ return str;
+ }
+
+ /** \relates AttrMatchData */
+ inline bool operator==( const AttrMatchData & lhs, const AttrMatchData & rhs )
+ {
+ return ( lhs.attr == rhs.attr
+ && lhs.attrMatcher == rhs.attrMatcher
+ && lhs.predicateStr == rhs.predicateStr );
+ }
+
+ /** \relates AttrMatchData */
+ inline bool operator!=( const AttrMatchData & lhs, const AttrMatchData & rhs )
+ { return !( lhs == rhs ); }
+
+ /** \relates AttrMatchData Arbitrary order for std::container. */
+ inline bool operator<( const AttrMatchData & lhs, const AttrMatchData & rhs )
{
- return str << obj.attr << ": " << obj.attrMatcher << ( obj.predicate ? " (+predicate)" : "" );
+ if ( lhs.attr != rhs.attr )
+ return ( lhs.attr < rhs.attr );
+ if ( lhs.attrMatcher != rhs.attrMatcher )
+ return ( lhs.attrMatcher < rhs.attrMatcher );
+ if ( lhs.predicateStr != rhs.predicateStr )
+ return ( lhs.predicateStr < rhs.predicateStr );
+ return false;
}
typedef std::list<AttrMatchData> AttrMatchList;
return overlaps( Edition::MatchRange( cap.op(), cap.ed() ), _range );
}
+ std::string stringRep() const
+ {
+ std::ostringstream str;
+ str << "EditionRange " << _range.op << " " << _range.value;
+ return str.str();
+ }
+
Edition::MatchRange _range;
};
return overlaps( Edition::MatchRange( Rel::EQ, iter_r.inSolvable().edition() ), _range );
}
+ std::string stringRep() const
+ {
+ std::ostringstream str;
+ str << "SolvableRange " << _range.op << " " << _range.value;
+ return str.str();
+ }
+
Edition::MatchRange _range;
};
return _cap.matches( iter_r.asType<Capability>() ) == CapMatch::yes;
}
+ std::string stringRep() const
+ {
+ std::ostringstream str;
+ str << "CapabilityMatch " << _cap;
+ return str.str();
+ }
+
Capability _cap;
};
/** Raw attributes */
AttrRawStrMap _attrs;
/** Uncompiled attributes with predicate. */
- AttrMatchList _uncompiledPredicated;
+ std::set<AttrMatchData> _uncompiledPredicated;
/** Sat solver search flags */
Match _flags;
//@}
public:
+
+ bool operator==( const PoolQuery::Impl & rhs ) const
+ {
+ return ( _strings == rhs._strings
+ && _attrs == rhs._attrs
+ && _uncompiledPredicated == rhs._uncompiledPredicated
+ && _flags == rhs._flags
+ && _match_word == rhs._match_word
+ && _require_all == rhs._require_all
+ && _status_flags == rhs._status_flags
+ && _edition == rhs._edition
+ && _op == rhs._op
+ && _repos == rhs._repos
+ && _kinds == rhs._kinds );
+ }
+
+ bool operator!=( const PoolQuery::Impl & rhs ) const
+ { return ! operator==( rhs ); }
+
+ public:
/** Compile the regex.
* Basically building the \ref _attrMatchList from strings.
* \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
{ return new Impl( *this ); }
};
+ ///////////////////////////////////////////////////////////////////
struct MyInserter
{
_attrMatchList.push_back( AttrMatchData( it->attr,
sat::AttrMatcher( rcstrings, cflags ),
- it->predicate ) );
+ it->predicate, it->predicateStr ) );
}
else
{
break;
}
- // Match::OTHER indicates need to compile.
- sat::AttrMatcher matcher( name, Match::OTHER );
+ // Match::OTHER indicates need to compile
+ // (merge global search strings into name).
+ AttrMatchData attrMatchData( attr, sat::AttrMatcher( name, Match::OTHER ) );
- AttrMatchData::Predicate pred;
if ( isDependencyAttribute( attr ) )
- pred = EditionRangePredicate( op, edition );
+ attrMatchData.addPredicate( EditionRangePredicate( op, edition ) );
else
- pred = SolvableRangePredicate( op, edition );
+ attrMatchData.addPredicate( SolvableRangePredicate( op, edition ) );
- _pimpl->_uncompiledPredicated.push_back( AttrMatchData( attr, matcher, pred ) );
+ _pimpl->_uncompiledPredicated.insert( attrMatchData );
}
void PoolQuery::addDependency( const sat::SolvAttr & attr, Capability cap_r )
return;
// Matches STRING per default. (won't get compiled!)
- sat::AttrMatcher matcher( cap.name().asString() );
+ AttrMatchData attrMatchData( attr, sat::AttrMatcher( cap.name().asString() ) );
- AttrMatchData::Predicate pred;
if ( isDependencyAttribute( attr ) )
- pred = CapabilityMatchPredicate( cap_r );
+ attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
else
- pred = SolvableRangePredicate( cap.op(), cap.ed() );
+ attrMatchData.addPredicate( SolvableRangePredicate( cap.op(), cap.ed() ) );
- _pimpl->_uncompiledPredicated.push_back( AttrMatchData( attr, matcher, pred ) );
+ _pimpl->_uncompiledPredicated.insert( attrMatchData );
}
void PoolQuery::setEdition(const Edition & edition, const Rel & op)
ostream & operator<<( ostream & str, const PoolQuery & obj )
{ return str << obj.asString(); }
- bool PoolQuery::operator==(const PoolQuery& a) const
- {
- if( flags() != a.flags() )
- return false;
- if( a.matchWord() != matchWord())
- return false;
- if( a.requireAll() != requireAll() )
- return false;
- if ( a.kinds() != kinds() )
- return false;
- if ( a.repos() != repos() )
- return false;
- if(a.edition() != edition())
- return false;
- if(a.editionRel() != editionRel())
- return false;
-
- return true;
- }
+ bool PoolQuery::operator==( const PoolQuery & rhs ) const
+ { return *_pimpl == *rhs._pimpl; }
///////////////////////////////////////////////////////////////////
namespace detail