28 #undef ZYPP_BASE_LOGGER_LOGGROUP
29 #define ZYPP_BASE_LOGGER_LOGGROUP "PoolQuery"
32 using namespace zypp::sat;
46 bool isDependencyAttribute( sat::SolvAttr attr_r )
48 static sat::SolvAttr deps[] = {
55 SolvAttr::supplements,
68 struct EditionRangePredicate
70 EditionRangePredicate(
const Rel & op,
const Edition & edition )
74 EditionRangePredicate(
const Rel & op,
const Edition & edition,
const Arch & arch )
79 bool operator()( sat::LookupAttr::iterator iter_r )
81 if ( !
_arch.empty() && iter_r.inSolvable().arch() !=
_arch )
84 CapDetail cap( iter_r.id() );
85 if ( ! cap.isSimple() )
89 return overlaps( Edition::MatchRange( cap.op(), cap.ed() ),
_range );
92 std::string serialize()
const
94 std::string ret(
"EditionRange" );
106 struct SolvableRangePredicate
108 SolvableRangePredicate(
const Rel & op,
const Edition & edition )
113 SolvableRangePredicate(
const Rel & op,
const Edition & edition,
const Arch & arch )
118 bool operator()( sat::LookupAttr::iterator iter_r )
120 if ( !
_arch.empty() && iter_r.inSolvable().arch() !=
_arch )
122 return overlaps( Edition::MatchRange( Rel::EQ, iter_r.inSolvable().edition() ),
_range );
125 std::string serialize()
const
127 std::string ret(
"SolvableRange" );
134 Edition::MatchRange
_range;
142 struct CapabilityMatchPredicate
144 CapabilityMatchPredicate( Capability cap_r )
148 bool operator()( sat::LookupAttr::iterator iter_r )
const
150 return _cap.matches( iter_r.asType<Capability>() ) == CapMatch::yes;
153 std::string serialize()
const
155 std::string ret(
"CapabilityMatch" );
193 typedef function<bool(sat::LookupAttr::iterator)> Predicate;
195 static bool always( sat::LookupAttr::iterator ) {
return true; }
196 static bool never( sat::LookupAttr::iterator ) {
return false; }
201 AttrMatchData( sat::SolvAttr attr_r )
205 AttrMatchData( sat::SolvAttr attr_r,
const StrMatcher & strMatcher_r )
210 AttrMatchData( sat::SolvAttr attr_r,
const StrMatcher & strMatcher_r,
211 const Predicate & predicate_r,
const std::string & predicateStr_r )
223 template<
class TPredicate>
224 void addPredicate(
const TPredicate & predicate_r )
235 std::string serialize()
const
237 std::string ret(
"AttrMatchData" );
248 static AttrMatchData
deserialize(
const std::string & str_r )
250 std::vector<std::string> words;
252 if ( words.empty() || words[0] !=
"AttrMatchData" )
253 ZYPP_THROW( Exception( str::Str() <<
"Expecting AttrMatchData: " << str_r ) );
254 if ( words.size() != 5 )
255 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
258 ret.attr = sat::SolvAttr( words[1] );
259 ret.strMatcher = StrMatcher( words[2] );
260 if ( Match::Mode mode = deserializeMode( words[3] ) )
261 ret.strMatcher.setFlags( mode );
262 ret.predicateStr = words[4];
267 if ( ! words.empty() )
269 if ( words[0] ==
"EditionRange" )
271 switch( words.size() )
274 ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]) );
277 ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
280 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
284 else if ( words[0] ==
"SolvableRange" )
286 switch( words.size() )
289 ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]) );
292 ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
295 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
299 else if ( words[0] ==
"CapabilityMatch" )
301 if ( words.size() != 2 )
302 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
303 ret.predicate = CapabilityMatchPredicate( Capability(words[1]) );
306 ZYPP_THROW( Exception( str::Str() <<
"Unknown predicate: " << str_r ) );
319 static std::string serializeMode( Match::Mode mode_r )
326 #define OUTS(M,S) case Match::M: return #S; break
331 OUTS( STRINGSTART, S );
332 OUTS( STRINGEND, E );
333 OUTS( SUBSTRING, B );
345 static Match::Mode deserializeMode(
const std::string & str_r )
349 #define OUTS(M,C) case *#C: return Match::M; break
354 OUTS( STRINGSTART, S );
355 OUTS( STRINGEND, E );
356 OUTS( SUBSTRING, B );
364 return Match::NOTHING;
369 inline std::ostream &
operator<<( std::ostream & str,
const AttrMatchData & obj )
371 str << obj.attr <<
": " << obj.strMatcher;
372 if ( obj.kindPredicate )
373 str <<
" +(" << obj.kindPredicate <<
")";
375 str <<
" +(" << obj.predicateStr <<
")";
380 inline bool operator==(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
382 return ( lhs.attr == rhs.attr
383 && lhs.strMatcher == rhs.strMatcher
384 && lhs.predicateStr == rhs.predicateStr );
388 inline bool operator!=(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
389 {
return !( lhs == rhs ); }
392 inline bool operator<(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
394 if ( lhs.attr != rhs.attr )
395 return ( lhs.attr < rhs.attr );
396 if ( lhs.strMatcher != rhs.strMatcher )
397 return ( lhs.strMatcher < rhs.strMatcher );
398 if ( lhs.predicateStr != rhs.predicateStr )
399 return ( lhs.predicateStr < rhs.predicateStr );
403 typedef std::list<AttrMatchData> AttrMatchList;
463 #define OUTS(A) if ( A != rhs.A ) return A < rhs.A;
466 OUTS( _uncompiledPredicated );
467 OUTS( _flags.get() );
469 OUTS( _status_flags );
471 OUTS( _op.inSwitch() );
489 && _attrs.size() == 1
490 && _attrs.begin()->first == sat::SolvAttr::name ) )
500 && _kinds == rhs.
_kinds );
513 void compile()
const;
525 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
528 {
return new Impl( *
this ); }
537 bool operator()(
const string & str)
549 bool operator()(
const string & str)
555 void PoolQuery::Impl::compile()
const
557 _attrMatchList.clear();
559 if ( _flags.mode() == Match::OTHER )
580 else if (_attrs.size() == 1)
586 _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first, joinedStrMatcher( joined, _flags ) ) );
593 bool attrvals_empty =
true;
594 for_( ai, _attrs.begin(), _attrs.end() )
596 if ( ai->second.empty() )
598 for_( it, ai->second.begin(), ai->second.end() )
602 attrvals_empty =
false;
606 if ( ! attrvals_empty )
611 bool attrvals_thesame =
true;
612 AttrRawStrMap::const_iterator ai = _attrs.begin();
615 for (; ai != _attrs.end(); ++ai)
619 set1.begin(), set1.end(),
620 ai->second.begin(), ai->second.end(),
621 inserter(result, result.begin()));
624 attrvals_thesame =
false;
633 if (attrvals_empty || attrvals_thesame)
647 StrMatcher matcher( joinedStrMatcher( joined, _flags ) );
648 for_( ai, _attrs.begin(), _attrs.end() )
650 _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
660 for_(ai, _attrs.begin(), _attrs.end())
666 _attrMatchList.push_back( AttrMatchData( ai->first, joinedStrMatcher( joined, _flags ) ) );
672 if ( ! _uncompiledPredicated.empty() )
676 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
678 if ( it->strMatcher.flags().mode() == Match::OTHER )
682 const std::string & mstr( it->strMatcher.searchstring() );
683 if ( ! mstr.empty() )
684 joined.insert( mstr );
687 AttrMatchData nattr( *it );
688 nattr.strMatcher = joinedStrMatcher( joined, _flags );
689 _attrMatchList.push_back( std::move(nattr) );
694 _attrMatchList.push_back( *it );
700 if ( _attrMatchList.empty() )
702 _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr, joinedStrMatcher( _strings, _flags ) ) );
706 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
708 it->strMatcher.compile();
720 std::string rxEscape( std::string str_r,
const Match & flags_r )
735 if ( container_r.empty() )
738 if ( container_r.size() == 1 && !_match_word )
739 return StrMatcher( *container_r.begin(), flags_r );
744 Match retflags( flags_r );
750 else if ( _match_word )
755 for ( const::std::string & s : container_r )
757 ret << sep << rxEscape( s, flags_r );
765 else if ( _match_word )
776 if ( _kinds.empty() )
780 for(Kinds::const_iterator it = _kinds.begin();
781 it != _kinds.end(); ++it)
787 if ( _repos.empty() )
791 for(StrContainer::const_iterator it = _repos.begin();
792 it != _repos.end(); ++it)
797 o <<
"version: "<< _op <<
" " << _edition.asString() << endl;
798 o <<
"status: " << ( _status_flags ? ( _status_flags == INSTALLED_ONLY ?
"INSTALLED_ONLY" :
"UNINSTALLED_ONLY" )
801 o <<
"string match flags: " <<
Match(_flags) << endl;
805 for(StrContainer::const_iterator it = _strings.begin();
806 it != _strings.end(); ++it)
810 o <<
"attributes: " << endl;
811 for(AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
813 o <<
"* " << ai->first <<
": ";
814 for(StrContainer::const_iterator vi = ai->second.begin();
815 vi != ai->second.end(); ++vi)
820 o <<
"predicated: " << endl;
821 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
823 o <<
"* " << *it << endl;
827 o <<
"last attribute matcher compiled: " << endl;
828 if ( _attrMatchList.empty() )
830 o <<
"not yet compiled" << endl;
834 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
836 o <<
"* " << *it << endl;
850 PoolQuery::PoolQuery()
859 if (repoalias.empty())
861 WAR <<
"ignoring an empty repository alias" << endl;
910 AttrMatchData attrMatchData( attr );
912 attrMatchData.strMatcher =
StrMatcher( name, mode );
916 attrMatchData.strMatcher =
StrMatcher( strchr( name.c_str(),
':')+1, mode );
917 attrMatchData.kindPredicate = explicitKind;
920 if ( isDependencyAttribute( attr ) )
921 attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
923 attrMatchData.addPredicate( SolvableRangePredicate( op, edition, arch ) );
937 if ( isDependencyAttribute( attr ) )
938 attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
940 attrMatchData.addPredicate( SolvableRangePredicate( cap.
op(), cap.
ed() ) );
983 AttrRawStrMap::const_iterator it =
_pimpl->
_attrs.find(attr);
984 return it !=
_pimpl->
_attrs.end() ? it->second : nocontainer;
1137 bool finded_something =
false;
1145 if ((!s.empty()) && s[0]==
'#')
1151 if (s.empty() || pos == s.npos)
1153 if (finded_something)
1163 finded_something =
true;
1165 string attrName(
str::trim(
string(s,0,pos)));
1166 string attrValue(
str::trim(
string(s,pos+1,s.npos)));
1180 || attribute==
"global_string")
1185 || attribute==
"string_type" )
1210 WAR <<
"unknown string type " << attrValue << endl;
1214 WAR <<
"forget recover some attribute defined as String type attribute: " << attrValue << endl;
1234 WAR <<
"unknown boolean value " << attrValue << endl;
1239 if( attrValue ==
"all" )
1243 else if( attrValue ==
"installed" )
1247 else if( attrValue ==
"not-installed" )
1253 WAR <<
"Unknown value for install status " << attrValue << endl;
1260 if (attrValue.find_first_of(
"=<>!") == 0)
1262 pos = attrValue.find_last_of(
"=<>");
1263 rel =
Rel(attrValue.substr(0, pos+1));
1264 attrValue =
str::trim(attrValue.substr(pos+1, attrValue.npos));
1283 WAR <<
"empty attribute name" << endl;
1287 string s = attrName;
1290 if ( a == SolvAttr::name || isDependencyAttribute( a ) )
1324 if ( attrmatch.attr == SolvAttr::name && attrmatch.strMatcher.flags().mode() ==
Match::OTHER )
1329 std::vector<std::string> words;
1331 if ( words.size() < 4 || words[3].empty() )
1343 if ( attrmatch.kindPredicate )
1346 addKind( attrmatch.kindPredicate );
1350 addAttribute( SolvAttr::name, attrmatch.strMatcher.searchstring() );
1353 std::vector<std::string> words;
1355 if ( ! words.empty() )
1357 if ( words[0] ==
"EditionRange" || words[0] ==
"SolvableRange" )
1369 return finded_something;
1381 str <<
"repo: " << *it << delim ;
1387 << it->idStr() << delim ;
1402 <<
": substring" << delim;
1417 str <<
"case_sensitive: ";
1420 str <<
"on" << delim;
1424 str <<
"off" << delim;
1433 str <<
"install_status: all" << delim;
1436 str <<
"install_status: installed" << delim;
1439 str <<
"install_status: not-installed" << delim;
1451 string s = it->first.asString();
1453 for_( it2,it->second.begin(),it->second.end() )
1455 str << s <<
": "<< *it2 << delim;
1461 str <<
"complex: "<< it->serialize() << delim;
1521 if ( base_r ==
end() )
1529 while ( base_r !=
end() )
1544 if ( base_r ==
end() )
1556 return_r.push_back( base );
1559 for ( ++base; base.
inSolvable() == inSolvable; ++base )
1562 return_r.push_back( base );
1570 const AttrMatchData & matchData( *mi );
1572 if ( matchData.strMatcher )
1578 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1582 return_r.push_back( it );
1600 for_( it, query_r->_repos.begin(), query_r->_repos.end() )
1614 _kinds = query_r->_kinds;
1637 if (
_repos.size() == 1 )
1646 if ( matchData.strMatcher )
1698 bool globalKindOk =(
_kinds.empty() || inSolvable.isKind(
_kinds.begin(),
_kinds.end() ) );
1709 if ( matchData.kindPredicate )
1711 if ( matchData.kindPredicate != inSolvable.kind() )
1717 else if ( !globalKindOk )
1720 if ( !matchData.predicate || matchData.predicate( base_r ) )
1729 const AttrMatchData & matchData( *mi );
1731 if ( matchData.kindPredicate )
1733 if ( matchData.kindPredicate != inSolvable.kind() )
1736 else if ( !globalKindOk )
1740 if ( matchData.strMatcher )
1746 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1788 if ( !
_matcher->advance( base_reference() ) )
1812 if ( ! obj.matchesEmpty() )
1814 for_( it, obj.matchesBegin(), obj.matchesEnd() )
1816 str << endl <<
" " << it->inSolvAttr() <<
"\t" << it->asString();