- allow for multiple types when searching, default to '-t package'
authorKlaus Kaempf <kkaempf@suse.de>
Tue, 28 Aug 2007 13:05:30 +0000 (13:05 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Tue, 28 Aug 2007 13:05:30 +0000 (13:05 +0000)
  check architecture on search output,
    different arch is always 'uninstalled'
  (#300569#c12, partial)

package/zypper.changes
src/zypper-search.cc
src/zypper-search.h
src/zypper.cc

index 789dcb1..fe421d1 100644 (file)
@@ -1,4 +1,13 @@
 -------------------------------------------------------------------
+Tue Aug 28 15:02:00 CEST 2007 - kkaempf@suse.de
+
+- allow for multiple types when searching, default to '-t package'
+  check architecture on search output,
+    different arch is always 'uninstalled'
+  (#300569#c12, partial)
+- rev 6931
+
+-------------------------------------------------------------------
 Tue Aug 28 12:50:27 CEST 2007 - duncan@suse.de
 
 - a init target at refresh to have keys available
index 3fab189..c6a7734 100644 (file)
@@ -14,6 +14,17 @@ using namespace zypp::resfilter;
 
 extern RuntimeData gData;
 
+ZyppSearchOptions::ZyppSearchOptions()
+  : _ifilter(ALL)
+  , _match_all(true)
+  , _match_words(false)
+  , _match_exact(false)
+  , _search_descriptions(false)
+  , _case_sensitive(false)
+{
+  // _kinds stays empty
+}
+
 void ZyppSearchOptions::resolveConflicts() {
   if (matchExact()) {
     // --match-all does not make sense here
@@ -69,16 +80,17 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
   ResPool pool = _zypp->pool();
 
   // search for specific resolvable type only
-  if (_options.kind() != Resolvable::Kind())
+  if (!_options.kinds().empty())
   {
     cerr_vv << "invokeOnEachSearched(): search by type" << endl;
 
     if (_options.installedFilter() != ZyppSearchOptions::UNINSTALLED_ONLY)
     {
       // search pool on ALL or INSTALLED
-      invokeOnEach(
-        pool.byKindBegin(_options.kind()), pool.byKindEnd(_options.kind()),
-        filter_r, pool_cb);
+      std::vector<zypp::Resolvable::Kind>::const_iterator it;
+      for (it = _options.kinds().begin(); it != _options.kinds().end(); ++it) {
+        invokeOnEach( pool.byKindBegin( *it ), pool.byKindEnd( *it ), filter_r, pool_cb );
+      }
     }
 
     if (_options.installedFilter() != ZyppSearchOptions::INSTALLED_ONLY)
@@ -88,12 +100,15 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
         // search cache on ALL or UNINSTALLED by TYPE
 
        if (_qstrings.empty())
-         _query.iterateResolvablesByKind( _options.kind(), cache_cb );
+        {
+         std::vector<zypp::Resolvable::Kind>::const_iterator it;
+         for (it = _options.kinds().begin(); it != _options.kinds().end(); ++it) {
+           _query.iterateResolvablesByKind( *it, cache_cb );
+         }
+        }
        else
         {
-          std::vector<zypp::Resolvable::Kind> kinds;
-         kinds.push_back( _options.kind() );
-          _query.iterateResolvablesByKindsAndStrings( kinds, _qstrings, (_options.matchExact() ? cache::MATCH_EXACT : cache::MATCH_SUBSTRING)|cache::MATCH_NAME, cache_cb );
+          _query.iterateResolvablesByKindsAndStrings( _options.kinds(), _qstrings, (_options.matchExact() ? cache::MATCH_EXACT : cache::MATCH_SUBSTRING)|cache::MATCH_NAME, cache_cb );
         }
       }
       catch ( const Exception & excpt_r )
@@ -110,9 +125,17 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
   // doesn't contain wildcards
   else if (_options.matchExact() && _qstrings.size() == 1 &&
       _qstrings[0].find('*') == string::npos &&
-      _qstrings[0].find('?') == string::npos) {
+      _qstrings[0].find('?') == string::npos)
+  {
     cerr_vv << "invokeOnEachSearched(): exact name match" << endl;
 
+    std::vector<zypp::Resolvable::Kind> kinds = _options.kinds();
+
+    // default to packages
+    if (kinds.empty()) {
+      kinds.push_back( ResTraits<Package>::kind );
+    }
+
     if (_options.installedFilter() != ZyppSearchOptions::UNINSTALLED_ONLY)
     {
       // search pool on ALL or INSTALLED
@@ -125,10 +148,8 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
     {
       try
       {
-      // search cache on ALL or UNINSTALLED by Kind AND Name
+        // search cache on ALL or UNINSTALLED by Kind AND Name
 
-        std::vector<zypp::Resolvable::Kind> kinds;
-       kinds.push_back( ResTraits<Package>::kind );
         _query.iterateResolvablesByKindsAndStrings( kinds, _qstrings, cache::MATCH_EXACT|cache::MATCH_NAME, cache_cb );
       }
       catch ( const Exception & excpt_r )
@@ -141,9 +162,17 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
   }
 
   // search among all resolvables
-  else {
+  else
+  {
     cerr_vv << "invokeOnEachSearched(): search among all resolvables" << endl;
 
+    std::vector<zypp::Resolvable::Kind> kinds = _options.kinds();
+
+    // default to packages
+    if (kinds.empty()) {
+      kinds.push_back( ResTraits<Package>::kind );
+    }
+
     if (_options.installedFilter() != ZyppSearchOptions::UNINSTALLED_ONLY)
     {
       // search pool on ALL or INSTALLED
@@ -154,10 +183,8 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
     {
       try
       {
-      // search cache on ALL or UNINSTALLED by WILD NAME
+        // search cache on ALL or UNINSTALLED by WILD NAME
 
-        std::vector<zypp::Resolvable::Kind> kinds;
-       kinds.push_back( ResTraits<Package>::kind );
         _query.iterateResolvablesByKindsAndStrings( kinds, _qstrings, cache::MATCH_SUBSTRING|cache::MATCH_NAME, cache_cb );
       }
       catch ( const Exception & excpt_r )
@@ -178,7 +205,7 @@ ZyppSearch::invokeOnEachSearched(_Filter filter_r, _PoolCallback pool_cb, _Cache
 void ZyppSearch::cacheInstalled() {
   // don't include kind string in hash map key if search is to be restricted
   // to particular kind (to improve performance a little bit)
-  if (_options.kind() != Resolvable::Kind())
+  if (_options.kinds().size() == 1)
     _icache.setIncludeKindInKey(false);
 
   cout_v << _("Pre-caching installed resolvables matching given search criteria... ") << endl;
@@ -187,8 +214,9 @@ void ZyppSearch::cacheInstalled() {
 
   _zypp->addResolvables(tgt_resolvables, true /*installed*/);
 
-  invokeOnEachSearched(Match(_reg,_options.searchDescriptions()),
-    functorRef<bool,const zypp::PoolItem &>(_icache), functorRef<bool, const data::RecordId &, data::ResObject_Ptr>(_icache));
+  invokeOnEachSearched( Match( _reg, _options.searchDescriptions()),
+    functorRef<bool,const zypp::PoolItem &>(_icache), functorRef<bool, const data::RecordId &, data::ResObject_Ptr>(_icache)
+  );
 
   cout_v << _icache.size() << _(" out of (") <<  tgt_resolvables.size() << ")"  
     << _("cached.") << endl;
@@ -216,7 +244,7 @@ ZyppSearch::doSearch(const boost::function<bool(const PoolItem &)> & f, const zy
   
   filter = chain(filter,DuplicateFilter(_idcache));
 
-  invokeOnEachSearched(filter, f, r);
+  invokeOnEachSearched( filter, f, r );
 }
 
 //! macro for word boundary tags for regexes
index 94bdcc4..155d8d4 100644 (file)
@@ -12,6 +12,7 @@
 #define ZYPPERSEARCH_H_
 
 #include <string>
+#include <vector>
 #include <boost/regex.hpp>
 #include <boost/function.hpp>
 #include <zypp/ZYpp.h>
@@ -36,12 +37,7 @@ public:
     UNINSTALLED_ONLY
   };
 
-  ZyppSearchOptions () :
-    _ifilter(ALL),
-    _match_all(true), _match_words(false), _match_exact(false),
-    _search_descriptions(false), _case_sensitive(false),
-    _kind(zypp::Resolvable::Kind())
-    {}
+  ZyppSearchOptions();
 
   void resolveConflicts();
 
@@ -52,7 +48,7 @@ public:
   bool matchExact() const { return _match_exact; }
   bool searchDescriptions() const { return _search_descriptions; }
   bool caseSensitive() const { return _case_sensitive; }
-  zypp::Resolvable::Kind kind() const { return _kind; }
+  const std::vector<zypp::Resolvable::Kind> & kinds() const { return _kinds; }
 
   void setInstalledFilter(const InsFilter ifilter) { _ifilter =  ifilter; }
   void setMatchAll(const bool match_all = true) { _match_all = match_all; }
@@ -61,7 +57,8 @@ public:
   void setMatchExact(const bool match_exact = true) { _match_exact = match_exact; }
   void setSearchDescriptions(const bool search_descriptions = true) { _search_descriptions = search_descriptions; }
   void setCaseSensitive(const bool case_sensitive = true) { _case_sensitive = case_sensitive; }
-  void setKind(const zypp::Resolvable::Kind & kind) { _kind = kind; }
+  void clearKinds( ) { _kinds.clear(); }
+  void addKind( const zypp::Resolvable::Kind & kind ) { _kinds.push_back( kind ); }
 
 private:
   InsFilter _ifilter;
@@ -70,7 +67,7 @@ private:
   bool _match_exact;
   bool _search_descriptions;
   bool _case_sensitive;
-  zypp::Resolvable::Kind _kind;
+  std::vector <zypp::Resolvable::Kind> _kinds;
 };
 
 struct GenericStringHash {
@@ -209,6 +206,8 @@ public:
 
   zypp::cache::ResolvableQuery *getQueryInstancePtr( void ) { return &_query; }
 
+  const ZyppSearchOptions &options() const { return _options; }
+
 private:
   zypp::ZYpp::Ptr & _zypp;
   const ZyppSearchOptions & _options;
@@ -267,8 +266,11 @@ struct ByInstalledCache
  */
 struct FillTable
 {
-  FillTable(Table & table, InstalledCache & icache, zypp::cache::ResolvableQuery * query) :
-    _table(&table), _icache(&icache), _query(query)
+  FillTable( Table & table, InstalledCache & icache, zypp::cache::ResolvableQuery * query, const ZyppSearchOptions &options )
+  : _table( &table )
+  , _icache( &icache )
+  , _query( query )
+  , _options( options )
   {
     TableHeader header;
 
@@ -291,51 +293,51 @@ struct FillTable
     *_table << header;
   }
 
-  bool operator()(const zypp::PoolItem & pool_item) const {
+  // PoolItem callback, called for installed resolvables
+
+  bool operator()(const zypp::PoolItem & pool_item) const
+  {
     TableRow row;
 
-    // add status to the result table
-    zypp::PoolItem inst_item = _icache->getItem(pool_item);
-    if (inst_item) {
-      // check whether the pool item is installed...
-      if (inst_item.resolvable()->edition() == pool_item.resolvable()->edition() &&
-          inst_item.resolvable()->arch() == pool_item.resolvable()->arch())
-        row << "i";
-      // ... or there's just another version of it installed
-      else
-        row << "v";
-    }
-    // or it's not installed at all
-    else {
-      row << "";
+    std::vector<zypp::Resolvable::Kind>::const_iterator it;
+    for (it = _options.kinds().begin(); it != _options.kinds().end(); ++it)
+    {
+      if (*it == pool_item.resolvable()->kind())
+      {
+        // add other fields to the result table
+        row << "i"
+           << pool_item.resolvable()->repository().info().alias()
+            // TODO what about rug's Bundle?
+            << (gSettings.is_rug_compatible ? "" : pool_item.resolvable()->kind().asString()) 
+            << pool_item.resolvable()->name()
+            << pool_item.resolvable()->edition().asString()
+            << pool_item.resolvable()->arch().asString();
+        *_table << row;
+        break;
+      }
     }
-
-    // add other fields to the result table
-    row << pool_item.resolvable()->repository().info().alias()
-        // TODO what about rug's Bundle?
-        << (gSettings.is_rug_compatible ? "" : pool_item.resolvable()->kind().asString()) 
-        << pool_item.resolvable()->name()
-        << pool_item.resolvable()->edition().asString()
-        << pool_item.resolvable()->arch().asString();
-  
-    *_table << row;
-
     return true;
   }
 
-  bool operator()(const zypp::data::RecordId & id, const zypp::data::ResObject_Ptr res) {
+  // RecordId callback, called for uninstalled resolvables
+
+  bool operator()(const zypp::data::RecordId & id, const zypp::data::ResObject_Ptr res)
+  {
     TableRow row;
 
     // add status to the result table
     zypp::PoolItem inst_item = _icache->getItem( res );
-    if (inst_item) {
-      // check whether the pool item is installed...
-      if (inst_item.resolvable()->edition() == res->edition &&
-          inst_item.resolvable()->arch() == res->arch)
+    if (inst_item
+        && inst_item.resolvable()->arch() == res->arch)
+    {
+      if (inst_item.resolvable()->edition() == res->edition)
+      {
         row << "i";
-      // ... or there's just another version of it installed
+      }
       else
+      {
         row << "v";
+      }
     }
     // or it's not installed at all
     else {
@@ -357,13 +359,20 @@ struct FillTable
     return true;
   }
 
+  // the table used for output
   Table * _table;
 
+  // the cache of installed names (used for 'i'/'v'/' ' in first column)
   InstalledCache * _icache;
 
+  // the db query interface, used to retrieve additional data like the repository alias
   zypp::cache::ResolvableQuery * _query;
+
+  // the search options, contains i.e. the list of kinds to show
+  const ZyppSearchOptions & _options;
 };
 
+
 /**
  * Filter functor for Matching PoolItems' names (or also summaries and
  * descriptions) with a regex created according to search criteria.
index 6edc54c..3880aca 100644 (file)
@@ -1150,18 +1150,21 @@ int one_command(int argc, char **argv)
     if (copts.count("search-descriptions")) options.setSearchDescriptions();
     if (copts.count("case-sensitive")) options.setCaseSensitive();
 
-    if (copts.count("type")) {
-      string skind = copts["type"].front();
-      kind = string_to_kind (skind);
-      if (kind == ResObject::Kind ()) {
-        cerr << _("Unknown resolvable type ") << skind << endl;
-        return ZYPPER_EXIT_ERR_INVALID_ARGS;
+    if (copts.count("type") > 0) {
+      options.clearKinds();
+      std::list<std::string>::const_iterator it;
+      for (it = copts["type"].begin(); it != copts["type"].end(); ++it) {
+       kind = string_to_kind( *it );
+        if (kind == ResObject::Kind()) {
+          cerr << _("Unknown resolvable type ") << *it << endl;
+          return ZYPPER_EXIT_ERR_INVALID_ARGS;
+        }
+        options.addKind( kind );
       }
-      options.setKind(kind);
     }
     else if (gSettings.is_rug_compatible) {
-      kind = ResTraits<Package>::kind;
-      options.setKind(kind);
+      options.clearKinds();
+      options.addKind( ResTraits<Package>::kind );
     }
 
     options.resolveConflicts();
@@ -1177,7 +1180,7 @@ int one_command(int argc, char **argv)
     t.style(Ascii);
 
     ZyppSearch search( God, options, arguments );
-    FillTable callback( t, search.installedCache(), search.getQueryInstancePtr() );
+    FillTable callback( t, search.installedCache(), search.getQueryInstancePtr(), search.options() );
 
     search.doSearch( callback, callback );