Imported Upstream version 15.19.0
[platform/upstream/libzypp.git] / zypp / PoolQuery.cc
index c2caef6..5fe838e 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/Solvable.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
 
 #include "zypp/PoolQuery.h"
 
@@ -165,13 +165,13 @@ namespace zypp
     /////////////////////////////////////////////////////////////////
     /** Match data per attribtue.
      *
-     * This includes the attribute itself, an optional \ref sat::AttrMatcher
+     * This includes the attribute itself, an optional \ref StrMatcher
      * to restrict the query to certain string values, and an optional
      * boolean \ref Predicate that may apply further restrictions that can
-     * not be expressed by the \ref attrMatcher.
+     * not be expressed by the \ref strMatcher.
      *
      * Example for such a \ref predicate would be an additional edition range
-     * check whan looking for dependencies. The \ref attrMatcher would
+     * check whan looking for dependencies. The \ref strMatcher would
      * find potential matches by looking at the dependencies name, the
      * predicate will then check the edition ranges.
      *
@@ -191,15 +191,15 @@ namespace zypp
       AttrMatchData()
       {}
 
-      AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r )
+      AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r )
         : attr( attr_r )
-        , attrMatcher( attrMatcher_r )
+        , strMatcher( strMatcher_r )
       {}
 
-      AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r,
+      AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r,
                      const Predicate & predicate_r, const std::string & predicateStr_r )
         : attr( attr_r )
-        , attrMatcher( attrMatcher_r )
+        , strMatcher( strMatcher_r )
         , predicate( predicate_r )
         , predicateStr( predicateStr_r )
       {}
@@ -209,8 +209,8 @@ namespace zypp
        * string representation instead. If you add new predicated, check the
        * deserialization code in \ref deserialize.
        */
-      template<class _Predicate>
-      void addPredicate( const _Predicate & predicate_r )
+      template<class TPredicate>
+      void addPredicate( const TPredicate & predicate_r )
       {
         predicate    = predicate_r;
         predicateStr = predicate_r.serialize();
@@ -225,11 +225,11 @@ namespace zypp
       {
         std::string ret( "AttrMatchData" );
         str::appendEscaped( ret, attr.asString() );
-        str::appendEscaped( ret, attrMatcher.searchstring() );
+        str::appendEscaped( ret, strMatcher.searchstring() );
         // TODO: Actually the flag should be serialized too, but for PoolQuery
         // it's by now sufficient to differ between mode OTHER and others,
         // i.e. whether to compile or not compile.
-        str::appendEscaped( ret, attrMatcher.flags().mode() == Match::OTHER ? "C" : "X" );
+        str::appendEscaped( ret, strMatcher.flags().mode() == Match::OTHER ? "C" : "X" );
         str::appendEscaped( ret, predicateStr );
         return ret;
       }
@@ -248,9 +248,9 @@ namespace zypp
 
         AttrMatchData ret;
         ret.attr = sat::SolvAttr( words[1] );
-        ret.attrMatcher = sat::AttrMatcher( words[2] );
+        ret.strMatcher = StrMatcher( words[2] );
         if ( words[3] == "C" )
-          ret.attrMatcher.setFlags( Match::OTHER );
+          ret.strMatcher.setFlags( Match::OTHER );
         ret.predicateStr = words[4];
 
         // now the predicate
@@ -301,7 +301,7 @@ namespace zypp
      }
 
       sat::SolvAttr    attr;
-      sat::AttrMatcher attrMatcher;
+      StrMatcher strMatcher;
       Predicate        predicate;
       std::string      predicateStr;
     };
@@ -309,7 +309,7 @@ namespace zypp
     /** \relates AttrMatchData */
     inline std::ostream & operator<<( std::ostream & str, const AttrMatchData & obj )
     {
-      str << obj.attr << ": " << obj.attrMatcher;
+      str << obj.attr << ": " << obj.strMatcher;
       if ( obj.predicate )
         str << " +(" << obj.predicateStr << ")";
       return str;
@@ -319,7 +319,7 @@ namespace zypp
     inline bool operator==( const AttrMatchData & lhs, const AttrMatchData & rhs )
     {
       return ( lhs.attr == rhs.attr
-               && lhs.attrMatcher == rhs.attrMatcher
+               && lhs.strMatcher == rhs.strMatcher
                && lhs.predicateStr == rhs.predicateStr );
     }
 
@@ -332,8 +332,8 @@ namespace zypp
     {
       if ( lhs.attr != rhs.attr )
         return (  lhs.attr < rhs.attr );
-      if ( lhs.attrMatcher != rhs.attrMatcher )
-        return (  lhs.attrMatcher < rhs.attrMatcher );
+      if ( lhs.strMatcher != rhs.strMatcher )
+        return (  lhs.strMatcher < rhs.strMatcher );
       if ( lhs.predicateStr != rhs.predicateStr )
         return (  lhs.predicateStr < rhs.predicateStr );
       return false;
@@ -401,17 +401,30 @@ namespace zypp
 
     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 );
+      if ( _flags == rhs._flags
+       // bnc#792901: while libzypp uses exact match mode for a single
+       // package name lock, zypper always uses glob. :(
+       // We unify those two forms to enable zypper to remove zypp locks
+       // without need to actually evaluate the query (which would require
+       // repos to be loaded).
+       || ( ( ( _flags.isModeString() && rhs._flags.isModeGlob() )
+           || ( _flags.isModeGlob() && rhs._flags.isModeString() ) )
+         && _strings.empty()
+         && _attrs.size() == 1
+         && _attrs.begin()->first == sat::SolvAttr::name ) )
+      {
+       return ( _strings == rhs._strings
+             && _attrs == rhs._attrs
+             && _uncompiledPredicated == rhs._uncompiledPredicated
+             && _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 );
+      }
+      return false;
     }
 
     bool operator!=( const PoolQuery::Impl & rhs ) const
@@ -420,11 +433,11 @@ namespace zypp
   public:
     /** Compile the regex.
      * Basically building the \ref _attrMatchList from strings.
-     * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
+     * \throws MatchException Any of the exceptions thrown by \ref StrMatcher::compile.
      */
     void compile() const;
 
-    /** AttrMatcher per attribtue. */
+    /** StrMatcher per attribtue. */
     mutable AttrMatchList _attrMatchList;
 
   private:
@@ -501,7 +514,7 @@ namespace zypp
       if (joined.size() > 1) // switch to regex for multiple strings
         cflags.setModeRegex();
       _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first,
-                                sat::AttrMatcher( rcstrings, cflags ) ) );
+                                StrMatcher( rcstrings, cflags ) ) );
     }
 
     // // MULTIPLE ATTRIBUTES
@@ -559,8 +572,8 @@ attremptycheckend:
         }
         if (joined.size() > 1) // switch to regex for multiple strings
           cflags.setModeRegex();
-        // May use the same AttrMatcher for all
-        sat::AttrMatcher matcher( rcstrings, cflags );
+        // May use the same StrMatcher for all
+        StrMatcher matcher( rcstrings, cflags );
         for_( ai, _attrs.begin(), _attrs.end() )
         {
           _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
@@ -582,7 +595,7 @@ attremptycheckend:
           if (joined.size() > 1) // switch to regex for multiple strings
             cflags.setModeRegex();
           _attrMatchList.push_back( AttrMatchData( ai->first,
-                                    sat::AttrMatcher( s, cflags ) ) );
+                                    StrMatcher( s, cflags ) ) );
         }
       }
     }
@@ -594,11 +607,11 @@ attremptycheckend:
       invokeOnEach( _strings.begin(), _strings.end(), EmptyFilter(), MyInserter(global) );
       for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
       {
-        if ( it->attrMatcher.flags().mode() == Match::OTHER )
+        if ( it->strMatcher.flags().mode() == Match::OTHER )
         {
           // need to compile:
           StrContainer joined( global );
-          const std::string & mstr( it->attrMatcher.searchstring() );
+          const std::string & mstr( it->strMatcher.searchstring() );
           if ( ! mstr.empty() )
             joined.insert( mstr );
 
@@ -608,7 +621,7 @@ attremptycheckend:
             cflags.setModeRegex();
 
           _attrMatchList.push_back( AttrMatchData( it->attr,
-                                    sat::AttrMatcher( rcstrings, cflags ),
+                                    StrMatcher( rcstrings, cflags ),
                                                       it->predicate, it->predicateStr ) );
         }
         else
@@ -627,13 +640,13 @@ attremptycheckend:
       if ( _strings.size() > 1 ) // switch to regex for multiple strings
         cflags.setModeRegex();
       _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr,
-                                sat::AttrMatcher( rcstrings, cflags ) ) );
+                                StrMatcher( rcstrings, cflags ) ) );
     }
 
     // Finally check here, whether all involved regex compile.
     for_( it, _attrMatchList.begin(), _attrMatchList.end() )
     {
-      it->attrMatcher.compile(); // throws on error
+      it->strMatcher.compile(); // throws on error
     }
     //DBG << asString() << endl;
   }
@@ -865,7 +878,7 @@ attremptycheckend:
 
     // Match::OTHER indicates need to compile
     // (merge global search strings into name).
-    AttrMatchData attrMatchData( attr, sat::AttrMatcher( name, Match::OTHER ) );
+    AttrMatchData attrMatchData( attr, StrMatcher( name, Match::OTHER ) );
 
     if ( isDependencyAttribute( attr ) )
       attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
@@ -882,7 +895,7 @@ attremptycheckend:
       return;
 
     // Matches STRING per default. (won't get compiled!)
-    AttrMatchData attrMatchData( attr, sat::AttrMatcher( cap.name().asString() ) );
+    AttrMatchData attrMatchData( attr, StrMatcher( cap.name().asString() ) );
 
     if ( isDependencyAttribute( attr ) )
       attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
@@ -1127,8 +1140,6 @@ attremptycheckend:
 
       PoolQueryAttr attribute( attrName );
 
-      MIL << "attribute name: " << attrName << endl;
-
       if ( attribute==PoolQueryAttr::repoAttr )
       {
         addRepo( attrValue );
@@ -1487,8 +1498,8 @@ attremptycheckend:
             {
               const AttrMatchData & matchData( *mi );
               sat::LookupAttr q( matchData.attr, inSolvable );
-              if ( matchData.attrMatcher ) // an empty searchstring matches always
-                q.setAttrMatcher( matchData.attrMatcher );
+              if ( matchData.strMatcher ) // an empty searchstring matches always
+                q.setStrMatcher( matchData.strMatcher );
 
               if ( ! q.empty() ) // there are matches.
               {
@@ -1514,12 +1525,20 @@ attremptycheckend:
 
          // Repo restriction:
          sat::Pool satpool( sat::Pool::instance() );
+
          for_( it, query_r->_repos.begin(), query_r->_repos.end() )
          {
            Repository r( satpool.reposFind( *it ) );
            if ( r )
              _repos.insert( r );
+           else
+             _neverMatchRepo = true;
          }
+         // _neverMatchRepo: we just need to catch the case that no repo
+         // matched, so we'd interpret the empty list as 'take from all'
+         if ( _neverMatchRepo && ! _repos.empty() )
+           _neverMatchRepo = false;
+
          // Kind restriction:
          _kinds = query_r->_kinds;
          // Edition restriction:
@@ -1527,7 +1546,7 @@ attremptycheckend:
          _edition = query_r->_edition;
          // Status restriction:
          _status_flags = query_r->_status_flags;
-          // AttrMatcher
+          // StrMatcher
           _attrMatchList = query_r->_attrMatchList;
        }
 
@@ -1540,6 +1559,9 @@ attremptycheckend:
        {
          sat::LookupAttr q;
 
+         if ( _neverMatchRepo )
+           return q.end();
+
          // Repo restriction:
          if ( _repos.size() == 1 )
            q.setRepo( *_repos.begin() );
@@ -1550,8 +1572,8 @@ attremptycheckend:
          {
             const AttrMatchData & matchData( _attrMatchList.front() );
            q.setAttr( matchData.attr );
-            if ( matchData.attrMatcher ) // empty searchstring matches always
-              q.setAttrMatcher( matchData.attrMatcher );
+            if ( matchData.strMatcher ) // empty searchstring matches always
+              q.setStrMatcher( matchData.strMatcher );
          }
           else // more than 1 attr (but not all)
           {
@@ -1624,8 +1646,8 @@ attremptycheckend:
           {
             const AttrMatchData & matchData( *mi );
             sat::LookupAttr q( matchData.attr, inSolvable );
-            if ( matchData.attrMatcher ) // an empty searchstring matches always
-              q.setAttrMatcher( matchData.attrMatcher );
+            if ( matchData.strMatcher ) // an empty searchstring matches always
+              q.setStrMatcher( matchData.strMatcher );
 
             if ( ! q.empty() ) // there are matches.
             {
@@ -1650,6 +1672,7 @@ attremptycheckend:
       private:
         /** Repositories include in the search. */
         std::set<Repository> _repos;
+       DefaultIntegral<bool,false> _neverMatchRepo;
         /** Resolvable kinds to include. */
         std::set<ResKind> _kinds;
         /** Edition filter. */
@@ -1657,7 +1680,7 @@ attremptycheckend:
         Edition _edition;
         /** Installed status filter flags. \see PoolQuery::StatusFilter */
         int _status_flags;
-        /** AttrMatcher per attribtue. */
+        /** StrMatcher per attribtue. */
         AttrMatchList _attrMatchList;
     };
     ///////////////////////////////////////////////////////////////////