Mailinglist Archive: zypp-commit (606 mails)

< Previous Next >
[zypp-commit] r9408 - in /trunk/libzypp: tests/zypp/ tests/zypp/data/PoolQuery/ zypp/
  • From: jkupec@xxxxxxxxxxxxxxxx
  • Date: Sun, 06 Apr 2008 22:17:10 -0000
  • Message-id: <20080406221710.E10B826E47@xxxxxxxxxxxxxxxx>
Author: jkupec
Date: Mon Apr 7 00:17:10 2008
New Revision: 9408

URL: http://svn.opensuse.org/viewcvs/zypp?rev=9408&view=rev
Log:
- PoolQuery backup
- some basic queries work (see the PoolQuery_test suite)
- ugly code, will beautify/optimize/correct
- TODO: kind filter, multiple repos, regexes (incl. wildcards), multiple
attribute values, <,>,== for different value types (locks need to
searc for edition > x.y.z), enable search in dependencies (easy)
- do/move some functionality to sat-solver?

Added:
trunk/libzypp/tests/zypp/data/PoolQuery/@System.solv (with props)
trunk/libzypp/tests/zypp/data/PoolQuery/factory-nonoss.solv (with props)
trunk/libzypp/tests/zypp/data/PoolQuery/factory.solv (with props)
trunk/libzypp/tests/zypp/data/PoolQuery/zypp_svn.solv (with props)
Modified:
trunk/libzypp/tests/zypp/PoolQuery_test.cc
trunk/libzypp/zypp/PoolQuery.cc
trunk/libzypp/zypp/PoolQuery.h

Modified: trunk/libzypp/tests/zypp/PoolQuery_test.cc
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/PoolQuery_test.cc?rev=9408&r1=9407&r2=9408&view=diff
==============================================================================
--- trunk/libzypp/tests/zypp/PoolQuery_test.cc (original)
+++ trunk/libzypp/tests/zypp/PoolQuery_test.cc Mon Apr 7 00:17:10 2008
@@ -17,13 +17,143 @@
using namespace zypp;
using namespace boost::unit_test;

-bool result_cb( const ResObject::Ptr &r )
+bool result_cb( const sat::Solvable & solvable )
{
- cout << r << endl;
+ zypp::PoolItem pi( zypp::ResPool::instance().find( solvable ) );
+ cout << pi.resolvable() << endl;
return true;
}

-BOOST_AUTO_TEST_CASE(pool_query)
+static void init_pool()
+{
+ Pathname dir(TESTS_SRC_DIR);
+ dir += "/zypp/data/PoolQuery";
+
+ ZYpp::Ptr z = getZYpp();
+ ZConfig::instance().setSystemArchitecture(Arch("i586"));
+
+ RepoInfo i1; i1.setAlias("factory");
+ sat::Pool::instance().addRepoSolv(dir / "factory.solv", i1);
+ RepoInfo i2; i2.setAlias("factory-nonoss");
+ sat::Pool::instance().addRepoSolv(dir / "factory-nonoss.solv", i2);
+ RepoInfo i3; i3.setAlias("zypp_svn");
+ sat::Pool::instance().addRepoSolv(dir / "zypp_svn.solv", i3);
+ sat::Pool::instance().addRepoSolv(dir / "@System.solv");
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_init)
+{
+ init_pool();
+}
+
+// no conditions, default query
+// result: all available resolvables
+BOOST_AUTO_TEST_CASE(pool_query_1)
+{
+ cout << "****1****" << endl;
+ PoolQuery q;
+ cout << q.size() << endl;
+ BOOST_CHECK(q.size() == 11449);
+}
+
+// default query + one search string
+// q.addString("foo");
+// result: all resolvables having at least one attribute matching foo
+BOOST_AUTO_TEST_CASE(pool_query_2)
+{
+ cout << "****2****" << endl;
+ PoolQuery q;
+ q.addString("zypper");
+
+ std::for_each(q.begin(), q.end(), &result_cb);
+ BOOST_CHECK(q.size() == 16);
+}
+
+// default query + one attribute + one string
+// q.addAttribute(foo, bar);
+// should be the same as
+// q.addAttribute(foo); q.addString(bar);
+// result: resolvables with foo containing bar
+BOOST_AUTO_TEST_CASE(pool_query_3)
+{
+ cout << "****3****" << endl;
+ PoolQuery q;
+ q.addString("zypper");
+ q.addAttribute(sat::SolvAttr::name);
+
+ std::for_each(q.begin(), q.end(), &result_cb);
+ BOOST_CHECK(q.size() == 6);
+
+ cout << endl;
+
+ PoolQuery q1;
+ q1.addAttribute(sat::SolvAttr::name, "zypper");
+
+ std::for_each(q1.begin(), q1.end(), &result_cb);
+ BOOST_CHECK(q1.size() == 6);
+}
+
+
+// default query + one attribute(one string) + one repo
+// q.addRepo(foorepo);
+// q.addAttribute(solvable:name, foo);
+// FAILS
+BOOST_AUTO_TEST_CASE(pool_query_4)
+{
+ cout << "****4****" << endl;
+ PoolQuery q;
+ q.addAttribute(sat::SolvAttr::name, "zypper");
+ q.addRepo("zypp_svn");
+
+ PoolQuery::ResultIterator it = q.begin();
+ std::for_each(
+ it,
+ q.end(),
+ &result_cb);
+ BOOST_CHECK(q.size() == 3);
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_5)
+{
+ cout << "****5****" << endl;
+ PoolQuery q;
+ q.addRepo("zypp_svn");
+
+ std::for_each(q.begin(), q.end(), &result_cb);
+ BOOST_CHECK(q.size() == 21);
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_6)
+{
+ cout << "****6****" << endl;
+ PoolQuery q;
+ q.addString("browser");
+ q.addAttribute(sat::SolvAttr::name);
+ q.addAttribute(sat::SolvAttr::summary);
+ q.addAttribute(sat::SolvAttr::description);
+
+ std::for_each(q.begin(), q.end(), &result_cb);
+ BOOST_CHECK(q.size() == 15);
+
+ cout << endl;
+
+ PoolQuery q1;
+ q1.addString("browser");
+ q1.addAttribute(sat::SolvAttr::name);
+
+ std::for_each(q1.begin(), q1.end(), &result_cb);
+ BOOST_CHECK(q1.size() == 5);
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_7)
+{
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_8)
+{
+}
+
+BOOST_AUTO_TEST_CASE(pool_query_save_restore)
{
#warning CAN NOT USE A FIX SOLV FILE
// must store some raw metadata and generate the solv file

Added: trunk/libzypp/tests/zypp/data/PoolQuery/@System.solv
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/data/PoolQuery/%40System.solv?rev=9408&view=auto
==============================================================================
Binary file - no diff available.

Added: trunk/libzypp/tests/zypp/data/PoolQuery/factory-nonoss.solv
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/data/PoolQuery/factory-nonoss.solv?rev=9408&view=auto
==============================================================================
Binary file - no diff available.

Added: trunk/libzypp/tests/zypp/data/PoolQuery/factory.solv
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/data/PoolQuery/factory.solv?rev=9408&view=auto
==============================================================================
Binary file - no diff available.

Added: trunk/libzypp/tests/zypp/data/PoolQuery/zypp_svn.solv
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/data/PoolQuery/zypp_svn.solv?rev=9408&view=auto
==============================================================================
Binary file - no diff available.

Modified: trunk/libzypp/zypp/PoolQuery.cc
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/PoolQuery.cc?rev=9408&r1=9407&r2=9408&view=diff
==============================================================================
--- trunk/libzypp/zypp/PoolQuery.cc (original)
+++ trunk/libzypp/zypp/PoolQuery.cc Mon Apr 7 00:17:10 2008
@@ -10,6 +10,7 @@
*
*/
#include <iostream>
+#include <sstream>
#include <list>
#include <vector>
#include <algorithm>
@@ -17,39 +18,45 @@
#include "zypp/base/Logger.h"
#include "zypp/base/PtrTypes.h"
#include "zypp/base/DefaultIntegral.h"
-#include "zypp/PoolQuery.h"
+#include "zypp/base/Regex.h"
+#include "zypp/base/Algorithm.h"
#include "zypp/base/UserRequestException.h"
+#include "zypp/repo/RepoException.h"

#include "zypp/sat/Pool.h"
#include "zypp/sat/Solvable.h"
#include "zypp/sat/SolvAttr.h"
+#include "zypp/sat/detail/PoolImpl.h"

-extern "C"
-{
-#include "satsolver/repo.h"
-}
+#include "zypp/PoolQuery.h"

using namespace std;
+using namespace zypp::sat;

///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////

- struct PoolQuery::Impl
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolQuery::Impl
+ //
+ class PoolQuery::Impl
{
-
+ public:
Impl()
- : _flags( 0 | SEARCH_NOCASE | SEARCH_SUBSTRING )
+ : _flags( SEARCH_ALL_REPOS | SEARCH_NOCASE | SEARCH_SUBSTRING )
, _status_flags(ALL)
+ , _match_word(false), _use_wildcards(false)
+ , _require_all(false)
+ , _compiled(false)
{}

~Impl()
- {
- //MIL << std::endl;
- }
+ {}

public:
-
+/*
static int repo_search_cb(void *cbdata, ::Solvable *s, ::Repodata *data,
::Repokey *key, ::KeyValue *kv)
{
PoolQuery *me = (PoolQuery*) cbdata;
@@ -74,18 +81,57 @@
}

if (me->_pimpl->_fnc)
- r = me->_pimpl->_fnc( makeResObject(solvable) );
+ r = me->_pimpl->_fnc( solvable );//makeResObject(solvable) );

if (!r)
return SEARCH_STOP;
return SEARCH_NEXT_SOLVABLE;
}
+ */
+ ResultIterator begin();
+ ResultIterator end();
+
+ string asString() const;
+
+ private:
+ void compile();
+ string createRegex(vector<string> & container);
+
+ public:
+ /** Raw search strings. */
+ vector<string> _strings;
+ /** Regex-compiled search strings. */
+ string _rcstrings;
+ /** Raw attributes */
+ AttrMap _attrs;
+ /** Regex-compiled attributes */
+ CompiledAttrMap _rcattrs;

+ /** Repos to search. */
vector<string> _repos;
- vector<string> _names;
+ /** Kinds to search */
vector<Resolvable::Kind> _kinds;
+
+ /** Sat solver search flags */
int _flags;
+ /** Backup of search flags. compile() may change the flags if needed, so
+ * in order to reuse the query, the original flags need to be stored
+ * at the start of compile() */
+ int _flags_old;
+ /** Sat solver status flags */
int _status_flags;
+
+ bool _match_word;
+ bool _use_wildcards;
+
+ bool _require_all;
+
+ /** Sat solver Dataiterator structure */
+ RepoDataIterator _rdit;
+
+ bool _compiled;
+
+ /** Function for processing found solvables. Used in execute(). */
mutable PoolQuery::ProcessResolvable _fnc;
private:
friend Impl * rwcowClone<Impl>( const Impl * rhs );
@@ -93,13 +139,445 @@
Impl * clone() const
{ return new Impl( *this ); }
};
- ///////////////////////////////////////////////////////////////////
+/*
+ template <class _OutputIterator>
+ struct CollectNonEmpty
+ {
+ CollectNonEmpty( _OutputIterator iter_r ) : _iter( iter_r ) {}
+
+ template<class _Tp>
+ bool operator()( const _Tp & value_r ) const
+ {
+ if (value_r.empty())
+ return true;
+ *_iter++ = value_r;
+ return true;
+ }
+
+ private:
+ mutable _OutputIterator _iter;
+ };
+*/
+ void PoolQuery::Impl::compile()
+ {
+ // backup the flags
+ _flags_old = _flags;
+
+ // 'different' - will have to iterate through all and match by
ourselves (slow)
+ // 'same' - will pass the compiled string to dataiterator_init
+ // 'one-attr' - will pass it to dataiterator_init
+ // 'one-non-regex-str' - will pass to dataiterator_init, set flag to
SEARCH_STRING or SEARCH_SUBSTRING
+
+ // // NO ATTRIBUTE
+ // else
+ // for all _strings
+ // create regex; store in _rcstrings; if more strings flag regex;
+ if (_attrs.empty())
+ {
+ _rcstrings = createRegex(_strings);
+ if (_strings.size() > 1)
+ _flags = (_flags & ~SEARCH_STRINGMASK) |
SEARCH_REGEX;//setMatchRegex();
+ }
+
+ // // ONE ATTRIBUTE
+ // else if _attrs is not empty but it contains just one attr
+ // for all _strings and _attr[key] strings
+ // create regex; store in _rcattrs; flag 'one-attr'; if more strings
flag regex;
+ else if (_attrs.size() == 1)
+ {
+ vector<string> joined;
+ for(vector<string>::const_iterator it = _strings.begin(); it !=
_strings.end(); ++it)
+ if (!it->empty())
+ joined.push_back(*it);
+ for(vector<string>::const_iterator it = _attrs.begin()->second.begin();
it != _attrs.begin()->second.end(); ++it)
+ if (!it->empty())
+ joined.push_back(*it);
+ _rcstrings = createRegex(joined);
+ _rcattrs.insert(pair<sat::SolvAttr, string>(_attrs.begin()->first,
string()));
+ }
+
+
+ // // MULTIPLE ATTRIBUTES
+ else
+ {
+ bool attrvals_empty = true;
+ for (AttrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end();
++ai)
+ if (!ai->second.empty())
+ for(vector<string>::const_iterator it = ai->second.begin();
+ it != ai->second.end(); it++)
+ if (!it->empty())
+ {
+ attrvals_empty = false;
+ goto attremptycheckend;
+ }
+
+attremptycheckend:
+
+ bool attrvals_thesame = true;
+ for (AttrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end();
++ai)
+ {
+
+ }
+
+ // // THE SAME STRINGS FOR DIFFERENT ATTRS
+ // else if _attrs is not empty but it does not contain strings
+ // for each key in _attrs take all _strings
+ // create regex; store in _rcattrs and _rcstrings; flag 'same'; if
more strings flag regex;
+ if (attrvals_empty || attrvals_thesame)
+ {
+ if (attrvals_empty)
+ {
+ // compile the search string
+ vector<string> joined;
+ for(vector<string>::const_iterator it = _strings.begin(); it !=
_strings.end(); ++it)
+ if (!it->empty())
+ joined.push_back(*it);
+ _rcstrings = createRegex(joined);
+
+ // copy the _attrs keys to _rcattrs
+ for (AttrMap::const_iterator ai = _attrs.begin(); ai !=
_attrs.end(); ++ai)
+ _rcattrs.insert(pair<sat::SolvAttr, string>(ai->first, string()));
+ }
+ }
+ // // DIFFERENT STRINGS FOR DIFFERENT ATTRS
+ // if _attrs is not empty and it contains non-empty vectors with
non-empty strings
+ // for each key in _attrs take all _strings + all _attrs[key] strings
+ // create regex; store in _rcattrs; flag 'different'; if more
strings flag regex;
+ else
+ {
+
+ }
+ }
+
+ // tell the Dataiterator to search only in one repo if only one specified
+ if (_repos.size() == 1)
+ _flags &= ~SEARCH_ALL_REPOS;
+
+ _compiled = true;
+
+ DBG << asString() << endl;
+ }
+
+ /**
+ * Converts '*' and '?' wildcards within str into their regex equivalents.
+ */
+ static string wildcards2regex(const string & str)
+ {
+ string regexed = str;
+
+ str::regex all("\\*"); // regex to search for '*'
+ str::regex one("\\?"); // regex to search for '?'
+ string r_all(".*"); // regex equivalent of '*'
+ string r_one("."); // regex equivalent of '?'
+ string::size_type pos;
+
+ // replace all "*" in input with ".*"
+ for (pos = 0; (pos = regexed.find("*", pos)) != std::string::npos; pos+=2)
+ regexed = regexed.replace(pos, 1, r_all);
+
+ // replace all "?" in input with "."
+ for (pos = 0; (pos = regexed.find('?', pos)) != std::string::npos; ++pos)
+ regexed = regexed.replace(pos, 1, r_one);
+
+ DBG << " -> " << regexed << endl;
+
+ return regexed;
+ }
+
+//! macro for word boundary tags for regexes
+#define WB (_match_word ? string("\\b") : string())
+
+ string PoolQuery::Impl::createRegex(vector<string> & container)
+ {
+ string rstr;
+
+ if (container.empty())
+ return rstr;
+
+ if (container.size() == 1)
+ {
+ rstr = *container.begin();
+
+ if (!_use_wildcards && ((_flags & SEARCH_STRINGMASK) != SEARCH_REGEX))
+ return rstr;
+
+ if (_use_wildcards)
+ {
+ rstr = wildcards2regex(rstr);
+
+ if (_flags & SEARCH_STRING) // match exact
+ rstr = "^" + rstr + "$";
+ }
+
+ rstr = ".*" + WB + rstr + WB + ".*";
+
+ return rstr;
+ }
+
+ // multiple strings
+
+ vector<string>::const_iterator it = container.begin();
+ string tmp;
+
+ if (_use_wildcards)
+ tmp = wildcards2regex(*it);
+
+ if (_require_all)
+ {
+ if (!(_flags & SEARCH_STRING)) // not match exact
+ tmp += ".*" + WB + tmp;
+ rstr = "(?=" + tmp + ")";
+ }
+ else
+ {
+ if (_flags & SEARCH_STRING) // match exact
+ rstr = "^";
+ else
+ rstr = ".*" + WB;
+
+ rstr += "(" + tmp;
+ }
+
+ ++it;
+
+ for (; it != container.end(); ++it)
+ {
+ if (_use_wildcards)
+ tmp = wildcards2regex(*it);
+
+ if (_require_all)
+ {
+ if (!(_flags & SEARCH_STRING)) // not match exact
+ tmp += ".*" + WB + tmp;
+ rstr += "(?=" + tmp + ")";
+ }
+ else
+ {
+ rstr += "|" + tmp;
+ }
+ }
+
+ if (_require_all)
+ {
+ if (!(_flags & SEARCH_STRING)) // not match exact
+ rstr += WB + ".*";
+ }
+ else
+ {
+ rstr += ")";
+ if (_flags & SEARCH_STRING) // match exact
+ rstr += "$";
+ else
+ rstr += WB + ".*";
+ }
+
+ return rstr;
+ }
+
+
+ PoolQuery::ResultIterator PoolQuery::Impl::begin()
+ {
+ compile();
+
+ // if only one repository has been specified, find it in the pool
+ sat::Pool pool(sat::Pool::instance());
+ sat::Pool::RepositoryIterator itr = pool.reposBegin();
+ if (!(_flags & SEARCH_ALL_REPOS) && _repos.size() == 1)
+ {
+ string theone = *_repos.begin();
+ for (; itr->info().alias() != theone && itr != pool.reposEnd(); ++itr);
+ if (itr == pool.reposEnd())
+ {
+ RepoInfo info; info.setAlias(theone);
+ ERR << "Repository not found in sat pool." << endl;
+ ZYPP_THROW(repo::RepoNotFoundException(info));
+ }
+ }
+
+ DBG << "_flags:" << _flags << endl;

- /** \relates PoolQuery::Impl Stream output */
+ if (_rcattrs.empty())
+ {
+ ::dataiterator_init(&_rdit,
+ _flags & SEARCH_ALL_REPOS ? pool.get()->repos[0] : itr->get(), //
repository \todo fix this
+ 0, // search all solvables
+ 0, // attribute id - only if 1
attr key specified
+ _rcstrings.empty() ? 0 : _rcstrings.c_str(), // compiled search string
+ _flags);
+ }
+ else if (_rcattrs.size() == 1)
+ {
+ ::dataiterator_init(&_rdit,
+ _flags & SEARCH_ALL_REPOS ? pool.get()->repos[0] : itr->get(), //
repository \todo fix this
+ 0, // search all solvables
+ _rcattrs.begin()->first.id(), // keyname - attribute id
- only if 1 attr key specified
+ _rcstrings.empty() ? 0 : _rcstrings.c_str(), // compiled search string
+ _flags);
+ }
+ else
+ {
+ ::dataiterator_init(&_rdit,
+ _flags & SEARCH_ALL_REPOS ? pool.get()->repos[0] : itr->get(), /*
repository - switch to next at the end of current one in increment() */
+ 0, /*search all resolvables */
+ 0, /*keyname - if only 1 attr key specified, pass it here, otherwise
do more magic */
+ 0, //qs.empty() ? 0 : qs.c_str(), /* create regex, pass it here */
+ _flags);
+ }
+
+ ImplPtr p(this);
+ PoolQuery::ResultIterator it(p);
+ it.increment();
+ return it;
+ }
+
+ PoolQuery::ResultIterator PoolQuery::Impl::end()
+ {
+ INT << "end" << endl;
+ return PoolQuery::ResultIterator();
+ }
+
+
+ string PoolQuery::Impl::asString() const
+ {
+ ostringstream o;
+
+ o << "compiled: " << _compiled << endl;
+
+ o << "match flags:" << endl;
+ o << "* sat: " << (_flags & SEARCH_STRINGMASK) << endl;
+ o << "* SEARCH_REGEX: " << ((_flags & SEARCH_STRINGMASK) == SEARCH_REGEX ?
"yes" : "no") << endl;
+
+ // raw
+
+ o << "strings: ";
+ for(vector<string>::const_iterator it = _strings.begin();
+ it != _strings.end(); ++it)
+ o << *it << " ";
+ o << endl;
+
+ o << "attributes: " << endl;
+ for(AttrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
+ {
+ o << "* " << ai->first << ": ";
+ for(vector<string>::const_iterator vi = ai->second.begin();
+ vi != ai->second.end(); ++vi)
+ o << *vi << " ";
+ o << endl;
+ }
+
+ // compiled
+
+ o << "regex compiled strings: " << _rcstrings << endl;
+ o << "regex compiled attributes:" << endl;
+ for (CompiledAttrMap::const_iterator ai = _rcattrs.begin(); ai !=
_rcattrs.end(); ++ai)
+ o << "* " << ai->first << ": " << ai->second << endl;
+
+ return o.str();
+ }
+
+ /** \relates PoolQuery::Impl Stream output *//*
inline std::ostream & operator<<( std::ostream & str, const PoolQuery::Impl
& obj )
{
return str << "PoolQuery::Impl";
}
+ */
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolQuery::ResultIterator
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ PoolQuery::ResultIterator::ResultIterator(ImplPtr pqimpl)
+ : PoolQuery::ResultIterator::iterator_adaptor_(0)
+ , _pqimpl(pqimpl)
+ , _has_next(true)
+ , _attrs(pqimpl->_rcattrs)
+ , _do_matching(false)
+ , _pool((sat::Pool::instance()))
+ {
+ _rdit = &_pqimpl->_rdit;
+ base_reference() = _rdit;
+ _sid = 0; /*rdit > ID_EMPTY ? rdit->solvid : 0;*/
+
+ if (_attrs.size() > 1)
+ _do_matching = true;
+ }
+
+ void PoolQuery::ResultIterator::increment()
+ {
+ if (!_rdit)
+ return;
+
+ bool got_match = false;
+ if (_has_next)
+ {
+ DBG << "last: " << _sid << endl;
+ while (_has_next && !(got_match = matchSolvable()));
+ }
+
+ if (!got_match)
+ {
+ base_reference() = 0;
+ _sid = 0;
+ }
+
+ DBG << "next: " << _sid << endl;
+ }
+
+ bool PoolQuery::ResultIterator::matchSolvable()
+ {
+ _sid = _rdit->solvid;
+
+ bool matches = !_do_matching;
+ bool in_repo;
+ do
+ {
+ //! \todo FIXME Dataiterator returning resolvables belonging to current
repo?
+ in_repo = _sid >= _rdit->repo->start;
+
+ if (_do_matching)
+ {
+ if ( !matches && in_repo /*_sid >= 2 *//*_rdit->repo->start*/)
+ {
+ 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);
+ if (matches)
+ INT << "value: " << IdString(_rdit->kv.id).asString() << endl
+ << " mstr: " << (_pqimpl->_rcstrings.empty() ? ai->second :
_pqimpl->_rcstrings) << endl;
+ // regex
+ }
+ }
+ }
+
+ if ((_has_next = ::dataiterator_step(_rdit)))
+ {
+ if (!in_repo /*_sid < 2 *//*_rdit->repo->start*/)
+ {
+ INT << "repo start: " << _rdit->repo->start << endl;
+ _sid = _rdit->solvid;
+ }
+ }
+ else
+ {
+ return matches;
+ }
+ }
+ while (_rdit->solvid == _sid || !in_repo /*_sid < 2
*//*_rdit->repo->start*/);
+
+ return matches;
+ }

///////////////////////////////////////////////////////////////////
//
@@ -111,59 +589,96 @@
: _pimpl(new Impl())
{}

+
PoolQuery::~PoolQuery()
{}

+
+ void PoolQuery::addRepo(const std::string &repoalias)
+ {
+ _pimpl->_repos.push_back(repoalias);
+ _pimpl->_flags &= ~SEARCH_ALL_REPOS;
+ }
+
+
void PoolQuery::addKind(const Resolvable::Kind &kind)
{ _pimpl->_kinds.push_back(kind); }

+
+ void PoolQuery::addString(const string & value)
+ { _pimpl->_strings.push_back(value); }
+
+
+ void PoolQuery::addAttribute(const sat::SolvAttr & attr, const std::string &
value)
+ { _pimpl->_attrs[attr].push_back(value); }
+
+
void PoolQuery::setCaseSensitive(const bool value)
{
if (value)
- _pimpl->_flags = (_pimpl->_flags & ~SEARCH_NOCASE);
+ _pimpl->_flags &= ~SEARCH_NOCASE;
else
- _pimpl->_flags = (_pimpl->_flags | SEARCH_NOCASE);
+ _pimpl->_flags |= SEARCH_NOCASE;
}

- void PoolQuery::setMatchExact(const bool value)
+
+ void PoolQuery::setMatchSubstring()
+ { _pimpl->_flags = (_pimpl->_flags & ~SEARCH_STRINGMASK) | SEARCH_SUBSTRING;
}
+ void PoolQuery::setMatchExact()
+ { _pimpl->_flags = (_pimpl->_flags & ~SEARCH_STRINGMASK) | SEARCH_STRING; }
+ void PoolQuery::setMatchRegex()
+ { _pimpl->_flags = (_pimpl->_flags & ~SEARCH_STRINGMASK) | SEARCH_REGEX; }
+ void PoolQuery::setMatchWord()
{
- if (value)
- {
- _pimpl->_flags = (_pimpl->_flags | SEARCH_STRING);
- _pimpl->_flags = (_pimpl->_flags & ~SEARCH_REGEX);
- _pimpl->_flags = (_pimpl->_flags & ~SEARCH_SUBSTRING);
- _pimpl->_flags = (_pimpl->_flags & ~SEARCH_GLOB);
- }
- else
- {
- _pimpl->_flags = (_pimpl->_flags & ~SEARCH_STRING);
- }
+ _pimpl->_match_word = true;
+ _pimpl->_flags = (_pimpl->_flags & ~SEARCH_STRINGMASK) | SEARCH_REGEX;
}

- void PoolQuery::addRepo(const std::string &repoalias)
- { _pimpl->_repos.push_back(repoalias); }

void PoolQuery::setFlags(int flags)
{ _pimpl->_flags = flags; }

- void PoolQuery::setInstalledOnly()
- {
- _pimpl->_status_flags = (_pimpl->_status_flags | INSTALLED_ONLY);
- }

+ void PoolQuery::setInstalledOnly()
+ { _pimpl->_status_flags |= INSTALLED_ONLY; }
void PoolQuery::setUninstalledOnly()
- {
- _pimpl->_status_flags = (_pimpl->_status_flags | UNINSTALLED_ONLY);
- }
-
+ { _pimpl->_status_flags |= UNINSTALLED_ONLY; }
void PoolQuery::setStatusFilterFlags( int flags )
+ { _pimpl->_status_flags |= flags; }
+
+
+ void PoolQuery::requireAll(const bool require_all)
+ { _pimpl->_require_all = require_all; }
+
+
+ PoolQuery::ResultIterator PoolQuery::begin()
+ { return _pimpl->begin(); }
+
+
+ PoolQuery::ResultIterator PoolQuery::end()
+ { return _pimpl->end(); }
+
+
+ bool PoolQuery::empty()
+ { return _pimpl->begin() == _pimpl->end(); }
+
+ //! \todo collect the result, reuse if not dirty
+ PoolQuery::size_type PoolQuery::size()
{
- _pimpl->_status_flags = (_pimpl->_status_flags | flags);
+ size_type count = 0;
+ for(ResultIterator it = _pimpl->begin(); it != _pimpl->end(); ++it,
++count);
+ return count;
}
-
- void PoolQuery::execute(const string &term, ProcessResolvable fnc) const
+
+
+ void PoolQuery::execute(ProcessResolvable fnc)
{
+ invokeOnEach(_pimpl->begin(), _pimpl->end(), fnc);
+ /*
_pimpl->_fnc = fnc;
+ string term;
+ if (!_pimpl->_strings.empty())
+ term = *_pimpl->_strings.begin();

sat::Pool pool(sat::Pool::instance());
for ( sat::Pool::RepositoryIterator itr = pool.reposBegin();
@@ -188,22 +703,16 @@
}

}
+ */
}
-
- /******************************************************************
- **
- ** FUNCTION NAME : operator<<
- ** FUNCTION TYPE : ostream &
- */
- ostream & operator<<( ostream & str, const PoolQuery & obj )
- {
- return str;
- }
-

+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolQuery::Impl
+ //
/**
- * represents all atributes in PoolQuery except SolvAtributes, which is
- * used as is (not needed extend anythink if someone add new solv attr)
+ * represents all atributes in PoolQuery except SolvAtributes, which are
+ * used as is (not needed extend anything if someone adds new solv attr)
*/
struct PoolQueryAttr : public IdStringType<PoolQueryAttr>
{
@@ -249,6 +758,9 @@
const PoolQueryAttr PoolQueryAttr::repoAttr( "repo" );
const PoolQueryAttr PoolQueryAttr::kindAttr( "kind" );

+ ///////////////////////////////////////////////////////////////////
+
+
//\TODO maybe ctor with stream can be usefull
bool PoolQuery::recover( istream &str, char delim )
{
@@ -320,7 +832,8 @@
return finded_something;
}

- void PoolQuery::serialize( ostream &str, char delim )
+
+ void PoolQuery::serialize( ostream &str, char delim ) const
{
//separating delim
str << delim;
@@ -340,7 +853,15 @@
str << delim;

}
-
+
+
+ string PoolQuery::asString() const
+ { return _pimpl->asString(); }
+
+
+ ostream & operator<<( ostream & str, const PoolQuery & obj )
+ { return str << obj.asString(); }
+

/////////////////////////////////////////////////////////////////
} // namespace zypp

Modified: trunk/libzypp/zypp/PoolQuery.h
URL:
http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/PoolQuery.h?rev=9408&r1=9407&r2=9408&view=diff
==============================================================================
--- trunk/libzypp/zypp/PoolQuery.h (original)
+++ trunk/libzypp/zypp/PoolQuery.h Mon Apr 7 00:17:10 2008
@@ -17,36 +17,110 @@

#include "zypp/base/Function.h"

+extern "C"
+{
+#include "satsolver/repo.h"
+}
+
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////

/**
- * Meta-data query API for user interfaces.
+ * Meta-data query API. Returns solvables of specified kinds from specified
+ * repositories with attributes matching the specified search strings.
*
* TODO: details, examples.
*/
class PoolQuery
{
public:
+ typedef std::map<sat::SolvAttr, std::vector<std::string> > AttrMap;
+ typedef std::map<sat::SolvAttr, std::string > CompiledAttrMap;
+ typedef unsigned int size_type;
+
+ class Impl;
+ typedef Impl * ImplPtr;

- //typedef SelectableSet::iterator ResultIterator;
- //typedef constSelectableSet::iterator constResultIterator;
+ typedef ::_Dataiterator RepoDataIterator;

- typedef function<bool( const ResObject::Ptr & )> ProcessResolvable;
+ class ResultIterator : public boost::iterator_adaptor<
+ ResultIterator // Derived
+ , RepoDataIterator * // Base
+ , sat::Solvable // Value
+ , boost::forward_traversal_tag // CategoryOrTraversal
+ , sat::Solvable // Reference
+ >
+ {
+ public:
+ ResultIterator()
+ : ResultIterator::iterator_adaptor_(0), _has_next(true),
+ _attrs(CompiledAttrMap()), _do_matching(false),
_pool((sat::Pool::instance()))
+ { _rdit = 0; _sid = 0; }
+
+ private:
+ friend class boost::iterator_core_access;
+ friend class PoolQuery;
+
+ ResultIterator(ImplPtr pqimpl);
+
+ sat::Solvable dereference() const
+ {
+ return _sid ? sat::Solvable(_sid) : sat::Solvable::noSolvable;
+ }
+
+ void increment();
+
+ bool matchSolvable();
+
+ template <class OtherDerived, class OtherIterator, class V, class C,
class R, class D>
+ bool equal( const boost::iterator_adaptor<OtherDerived, OtherIterator,
V, C, R, D> & rhs ) const
+ {
+ if (!rhs.base() && !base())
+ return true;
+ if (!rhs.base() || !base())
+ return false;
+ if (rhs.base()->solvid == base()->solvid)
+ return true;
+ return false;
+ }
+
+ private:
+ RepoDataIterator * _rdit;
+ ImplPtr _pqimpl;
+ /*SolvableId*/ int _sid;
+ bool _has_next;
+ const CompiledAttrMap & _attrs;
+ bool _do_matching;
+ sat::Pool _pool;
+ };
+
+ public:
+ typedef function<bool( const sat::Solvable & )> ProcessResolvable;

PoolQuery();
~PoolQuery();

- public:
+ /** Query result accessers. */
+ //@{
+
+ /** */
+ ResultIterator begin();
+ /** */
+ ResultIterator end();
+ /** */
+ bool empty();
+ /** */
+ size_type size();
+ //@}

/**
* executes the query with the current settings
* results are yielded on the callback passed on
* construction
*/
- void execute(const std::string &term, PoolQuery::ProcessResolvable fnc)
const;
+ void execute(ProcessResolvable fnc);

/**
* Filter by selectable kind.
@@ -59,8 +133,7 @@
*/
void addKind(const Resolvable::Kind &kind);

-
- /**
+ /**
* Filter by repo.
*
* By default, all repos will be returned. If addRepo() is used,
@@ -68,13 +141,8 @@
*/
void addRepo(const std::string &repoalias);

- /**
- * Filter by selectable name.
- *
- * \param name what to search for
- * \param isRegex is the value a regex?
- */
- //void addName(const std::string & name, bool isRegex = false);
+ /** Installed status filter setters. */
+ //@{

/**
* Filter by status (installed uninstalled)
@@ -88,20 +156,24 @@
void setUninstalledOnly();
void setStatusFilterFlags( int flags );

+ //@}
+
+ /**
+ *
+ */
+ void addString(const std::string & value);
+
/**
- * Filter by the \a value of any available attribute of selectables.
+ * Filter by the \a value of any available solvable attribute.
*
- * \note Selectables of a kind not supporting the specified attribute will
+ * \note Solvables of a kind not supporting the specified attribute will
* <b>not</b> be returned.
+ * \todo check the above
*
- * \param attrid attribute identfier (sat::SolvAttr or cache::Attribute
- * or something implementation independent)
- * \param value what to search for
- * \param isRegex is the value a regex?
- */
- //void addAttribute(const solv::SolvAttr & attrid,
- // const std::string & value,
- // bool isRegex = false);
+ * \param attr Attribute identfier. Use sat::Solvattr::* constants
+ * \param value What to search for.
+ */
+ void addAttribute(const sat::SolvAttr & attr, const std::string & value =
"");

/**
* Filter by Selectable status.
@@ -112,7 +184,6 @@
*/
//void addStatus(const Status status);

-
/**
* Add dependency filter.
*
@@ -124,54 +195,50 @@
* \todo maybe a isRegexp bool as in addName() for the name parameter would
* be handy here as well.
* \todo add more addDependecy() variants
- */
- //void addDependency(const Dep & dtype,
- // const std::string & name,
- // const Edition & edition = Edition(),
- // const Rel & rel = Rel::EQ);
+ *//*
+ void addDependency(const Dep & dtype,
+ const std::string & name,
+ const Edition & edition = Edition(),
+ const Rel & rel = Rel::EQ);
+*/
+

- /** \name Text Attributes Matching Options */
+ /** \name Text Matching Options */
//@{
/**
- * Set case sentitive on
- * ( disables \ref SEARCH_NOCASE flag )
+ * Turn case sentitivity on or off (unsets or sets \ref SEARCH_NOCASE
flag).
+ * PoolQuery defaults to case insensitive search unless this method
+ * is used.
+ *
+ * \param value Whether to turn the case sensitivity on (default) or off.
*/
void setCaseSensitive(const bool value = true);

- /**
- * Set match exact string
- */
- void setMatchExact(const bool value = true);
+ /** Set to match exact string instead of substring.*/
+ void setMatchExact();
+ /** Set to use the query strings as regexes */
+ void setMatchRegex();
+ /** Set to substring (the default). */
+ void setMatchSubstring();
+ /** Set to match words (uses regex) */
+ void setMatchWord();

/**
- * Free function to set the satsolver repo search
- flags.
+ * If true, convert * and ? to correspondent regex equivalent, otherwise
+ * shield wildcards from being interpreted like regex control chars (if
+ * SEARCH_REGEX is set)
+ */
+ void setUseWildcards(const bool value = true);

- \see SEARCH_STRINGMASK
- \see SEARCH_STRING
- \see SEARCH_SUBSTRING
- \see SEARCH_GLOB
- \see SEARCH_REGEX
- \see SEARCH_NOCASE
- \see SEARCH_NO_STORAGE_SOLVABLE
- */
- void setFlags(int flags);
//void setLocale(const Locale & locale);
//@}

- //void setRequireAll(const bool require_all = true);

- /** selectable iterator over the result */
- //ResultIterator resultBegin() const;
- //ResultIterator resultEnd() const;
-
- /** Returns the size of the query result. */
- //size_t resultSize() const;
-
- /** Low-cost empty query result checker */
- //bool resultEmpty() const;
-
- // a forEach method consuming a functor can be added here, too
+ /**
+ * Require that all of the query conditions set by
+ * addAttribute, addString, addDep are satisfied.
+ */
+ void requireAll(const bool require_all = true);

/**
* Reads from stream query. Attributes is sepated by delim. Query is
@@ -186,23 +253,45 @@
bool recover( std::istream &str, char delim = '\n' );

/**
- * Writes query to stream, As delimeter is used delim.
+ * Writes a machine-readable string representation of the query to stream.
+ * Use \a delim as attribute delimiter.
*
- * \param str output stream for query
- * \param delim delimeter for attributes
+ * \param str output stream to write to
+ * \param delim delimiter for attributes
*
* \see writePoolQueriesToFile
*/
- void serialize( std::ostream &str, char delim = '\n' );
+ void serialize( std::ostream &str, char delim = '\n' ) const;
+
+ /** Return a human-readable description of the query */
+ std::string asString() const;
+
+
+ // low level API
+
+ /**
+ * Free function to set the satsolver repo search
+ * flags.
+ *
+ * \see SEARCH_STRINGMASK
+ * \see SEARCH_STRING
+ * \see SEARCH_SUBSTRING
+ * \see SEARCH_GLOB
+ * \see SEARCH_REGEX
+ * \see SEARCH_NOCASE
+ * \see SEARCH_NO_STORAGE_SOLVABLE
+ */
+ void setFlags(int flags);

- public:
- class Impl;
private:
/** Pointer to implementation */
- RW_pointer<Impl> _pimpl;
+ ImplPtr _pimpl;
};


+ /** \relates PoolQuery Stream output. */
+ std::ostream & operator<<( std::ostream & str, const PoolQuery & obj );
+

/////////////////////////////////////////////////////////////////
} // namespace zypp

--
To unsubscribe, e-mail: zypp-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: zypp-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages