- exact/glob and case-insensitive matching for multi-attribute condition
authorJan Kupec <jkupec@suse.cz>
Mon, 7 Apr 2008 22:57:12 +0000 (22:57 +0000)
committerJan Kupec <jkupec@suse.cz>
Mon, 7 Apr 2008 22:57:12 +0000 (22:57 +0000)
tests/zypp/PoolQuery_test.cc
zypp/PoolQuery.cc

index 1071be30a71d139040c55e4c90535cc78bff3d77..e41e4e0a885175b3796aea29d43acefffab50625 100644 (file)
@@ -222,6 +222,51 @@ BOOST_AUTO_TEST_CASE(pool_query_9)
   BOOST_CHECK(q2.size() == 28);
 }
 
+// multi attr (same value) substring matching (case sensitive and insensitive)
+BOOST_AUTO_TEST_CASE(pool_query_10)
+{
+  cout << "****10****"  << endl;
+/*
+  PoolQuery q;
+  q.addString("SSH");
+  q.addAttribute(sat::SolvAttr::name);
+  q.addAttribute(sat::SolvAttr::summary);
+  q.addAttribute(sat::SolvAttr::description);
+
+  std::for_each(q.begin(), q.end(), &result_cb);
+  cout << q.size() << endl;
+//  BOOST_CHECK(q.size() == 17);
+*/
+  cout << endl;
+
+  PoolQuery q2;
+  q2.addString("SSH");
+  q2.addAttribute(sat::SolvAttr::name);
+  q2.addAttribute(sat::SolvAttr::summary);
+  q2.addAttribute(sat::SolvAttr::description);
+  q2.setCaseSensitive();
+
+  std::for_each(q2.begin(), q2.end(), &result_cb);
+  cout << q2.size() << endl;
+}
+/*
+// multi attr (same value) glob matching (case sensitive and insensitive)
+BOOST_AUTO_TEST_CASE(pool_query_11)
+{
+  cout << "****11****"  << endl;
+  PoolQuery q;
+  q.addString("pack*");
+  q.addAttribute(sat::SolvAttr::name);
+  q.addAttribute(sat::SolvAttr::summary);
+  q.setMatchGlob();
+
+  std::for_each(q.begin(), q.end(), &result_cb);
+  cout << q.asString() <<  endl;
+//  BOOST_CHECK(q.size() == 11);
+}
+*/
+
+
 // save/load query
 BOOST_AUTO_TEST_CASE(pool_query_save_restore)
 {
index deb76f5251eecf788dfd0e727019aea5c4495b94..a6f9907032e1e1b05c6527e48bcd36392b9b8cb1 100644 (file)
@@ -14,6 +14,7 @@
 #include <list>
 #include <vector>
 #include <algorithm>
+#include <fnmatch.h>
 
 #include "zypp/base/Logger.h"
 #include "zypp/base/PtrTypes.h"
@@ -436,12 +437,13 @@ attremptycheckend:
     o << "compiled: " << _compiled << endl;
 
     o << "string match flags:" << endl;
-    o << "* sat: " << (_flags & SEARCH_STRINGMASK) << endl; 
-    o << "* SEARCH_REGEX: " << ((_flags & SEARCH_STRINGMASK) == SEARCH_REGEX ? "yes" : "no") << endl;
-    o << "status filter flags:" << _status_flags << endl; 
+    o << "* string/substring/glob/regex: " << (_flags & SEARCH_STRINGMASK) << endl; 
+    o << "* SEARCH_NOCASE: " << ((_flags & SEARCH_NOCASE) ? "yes" : "no") << endl;
+    o << "* SEARCH_ALL_REPOS: " << ((_flags & SEARCH_ALL_REPOS) ? "yes" : "no") << endl;
+    o << "status filter flags:" << _status_flags << endl;
 
     // raw
-    
+
     o << "strings: ";
     for(vector<string>::const_iterator it = _strings.begin();
         it != _strings.end(); ++it)
@@ -553,21 +555,49 @@ attremptycheckend:
         if (!matches && in_repo)
         {
           SolvAttr attr(_rdit->key->name);
-
           CompiledAttrMap::const_iterator ai = _attrs.find(attr);
           if (ai != _attrs.end())
           {
-            // exact match
-            //matches = (ai->second == IdString(_rdit->kv.id).asString());
-            // substring
-            matches = (
-              IdString(_rdit->kv.id).asString().find
-                (_pqimpl->_rcstrings.empty() ? ai->second : _pqimpl->_rcstrings)
-                != string::npos);
+            const string & sstr =
+              _pqimpl->_rcstrings.empty() ? ai->second : _pqimpl->_rcstrings;
+            const IdString & value =
+              IdString(_rdit->kv.id);
+
+            //cout << "solvid: " << _sid << " attr: " << attr.asString() << " val: " << value.asString() << endl;
+
+            //string v2(::id2str(_rdit->repo->pool/*_pool.get()*/, _rdit->kv.id));
+            //if (value.asString() != v2)
+            //  cout << "ha! " << value.asString() << "!=" << v2 << endl;
+
+            switch(_pqimpl->_flags & SEARCH_STRINGMASK)
+            {
+            case SEARCH_STRING:
+              if (_pqimpl->_flags & SEARCH_NOCASE)
+                matches = ! str::compareCI(sstr.c_str(), value.c_str());
+              else
+                matches = (sstr == value.asString());
+              break;
+            case SEARCH_SUBSTRING:
+              if (_pqimpl->_flags & SEARCH_NOCASE)
+                matches = ::strcasestr(value.c_str(), sstr.c_str());
+              else
+                matches = (value.asString().find(sstr) != string::npos);
+              break;
+            case SEARCH_GLOB:
+              matches = !::fnmatch(sstr.c_str(), value.c_str(),
+                  (_pqimpl->_flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0);
+              break;
+            case SEARCH_REGEX:
+              matches = false;
+              break;
+            default:
+              matches = false;
+              ERR << "ivalid string matching type: "
+                  << (_pqimpl->_flags & SEARCH_STRINGMASK) << endl;
+            }
             if (matches)
-              INT << "value: " << IdString(_rdit->kv.id).asString() << endl
-                  << " mstr: " <<  (_pqimpl->_rcstrings.empty() ? ai->second : _pqimpl->_rcstrings) << endl; 
-            // regex
+              INT << "value: " << value.asString() << endl
+                  << " mstr: " <<  sstr << endl; 
           }
         }
       }