Remove obsolete ResStatus bits.
[platform/upstream/libzypp.git] / zypp / PoolQuery.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/PoolQuery.h
10  *
11 */
12 #ifndef ZYPP_POOLQUERY_H
13 #define ZYPP_POOLQUERY_H
14
15 #include <iosfwd>
16 #include <set>
17 #include <map>
18
19 #include "zypp/base/Regex.h"
20 #include "zypp/base/PtrTypes.h"
21 #include "zypp/base/Function.h"
22
23 #include "zypp/sat/SolvIterMixin.h"
24 #include "zypp/sat/LookupAttr.h"
25 #include "zypp/sat/AttrMatcher.h"
26 #include "zypp/sat/Pool.h"
27
28 ///////////////////////////////////////////////////////////////////
29 namespace zypp
30 { /////////////////////////////////////////////////////////////////
31
32   namespace detail
33   {
34     class PoolQueryIterator;
35   }
36
37   ///////////////////////////////////////////////////////////////////
38   //
39   //  CLASS NAME : PoolQuery
40   //
41   /**
42    * Meta-data query API. Returns solvables of specified kinds from specified
43    * repositories with attributes matching the specified search strings.
44    *
45    * The search strings can be specified via \ref addString() and
46    * \ref addAttribute() methods. String matching type can be set using the
47    * setMatch*() methods. Multiple search strings for a particular attribute
48    * will be combined into a regex (see \ref addString() and
49    * \ref addAttribute() for more details).
50    *
51    * The begin() and end() methods return a PoolQueryIterator returning
52    * \ref sat::Solvable objects which can easily be turned into \ref Resolvable
53    * objects. Additionally, thanx to the \ref sat::SolvIterMixin, a Selectable
54    * and PoolItem iterators are automatically available.
55    *
56    * <code>
57    * PoolQuery q;
58    * q.addAttribute(sat::SolvAttr::name, "zypp*");
59    * q.addKind(ResKind::package);
60    * q.setMatchGlob();
61    *
62    * for (PoolQuery::Selectable_iterator it = q.selectableBegin();
63    *     it != q.selectableEnd(); ++it)
64    * {
65    *   ui::Selectable::constPtr s = *it;
66    *   // ...
67    * }
68    * </code>
69    *
70    * Performance considerations
71    *
72    * Results of simple queries like those using one string and/or one attribute
73    * and/or one repository are filtered by sat-solver's Dataiterator directly,
74    * and thus it is fast.
75    *
76    * Queries with multiple strings are implemented using regexes. Queries based
77    * on kinds, multiple repos, and multiple attributes are filtered inside
78    * the PoolQuery, so these tend to be slower.
79    *
80    * \see detail::PoolQueryIterator on how to inspect matches in detail.
81    * \see tests/zypp/PoolQuery_test.cc for more examples
82    * \see sat::SolvIterMixin
83    */
84   class PoolQuery : public sat::SolvIterMixin<PoolQuery, detail::PoolQueryIterator>
85   {
86   public:
87     typedef std::set<ResKind>                               Kinds;
88     typedef std::set<std::string>                           StrContainer;
89     typedef std::map<sat::SolvAttr, StrContainer>           AttrRawStrMap;
90
91     typedef detail::PoolQueryIterator                       const_iterator;
92     typedef unsigned int                                    size_type;
93
94   public:
95     typedef function<bool( const sat::Solvable & )> ProcessResolvable;
96
97     PoolQuery();
98     ~PoolQuery();
99
100     /** Query result accessers. */
101     //@{
102     /**
103      * Compile the query and return an iterator to the result.
104      *
105      * \return An iterator (\ref detail::PoolQueryIterator) returning
106      *         sat::Solvable objects pointing at the beginning of the query result.
107      * \throws sat::MatchInvalidRegexException if the query was about to use a regex which
108      *         failed to compile.
109      *
110      * \note Note that PoolQuery is derived from \ref sat::SolvIterMixin which
111      *       makes PoolItem and Selectable iterators automatically available.
112      * \see \ref sat::SolvIterMixin
113      */
114     const_iterator begin() const;
115
116     /** An iterator pointing to the end of the query result. */
117     const_iterator end() const;
118
119     /** Whether the result is empty. */
120     bool empty() const;
121
122     /** Number of solvables in the query result. */
123     size_type size() const;
124     //@}
125
126     /**
127      * Executes the query with the current settings.
128      * Results are yielded via the \a fnc callback.
129      */
130     void execute(ProcessResolvable fnc);
131
132     /**
133      * Filter by selectable kind.
134      *
135      * By default, all kinds will be returned. If addKind() is used,
136      * only the specified kinds will be returned (multiple kinds will be ORed).
137      *
138      * Pass ResKind constants to this method, (e.g. ResKind::package).
139      */
140     void addKind(const ResKind & kind);
141
142     /**
143      * Filter by repo.
144      *
145      * By default, all repos will be returned. If addRepo() is used,
146      * only the specified repo will be returned (multiple repos will be ORed).
147      */
148     void addRepo(const std::string &repoalias);
149
150     /** Installed status filter setters. */
151     //@{
152
153     /**
154      * Filter by status (installed uninstalled)
155      */
156     enum StatusFilter {
157       ALL = 0, // both install filter and uninstall filter bits are 0
158       INSTALLED_ONLY = 1,
159       UNINSTALLED_ONLY = 2
160     };
161
162     /** Return only @System repo packages */
163     void setInstalledOnly();
164     /** Return only packages from repos other than @System. */
165     void setUninstalledOnly();
166     /** Set status filter directly \see StatusFilter */
167     void setStatusFilterFlags( StatusFilter flags );
168
169     //@}
170
171     /**
172      * Add a global query string. The string added via this method is applied
173      * to all query attributes as if addAttribute(..., \value) was called
174      * for all of them.
175      *
176      * This method can be used multiple times in which case the query strings
177      * will be combined (together with strings added via addAttribute()) into
178      * a regex. Searched attribute value will match this regex if <b>any</b>
179      * of these strings will match the value. This can be changed by
180      * (not yet implemented) \ref setRequireAll() method.
181      */
182     void addString(const std::string & value);
183
184     /**
185      * Filter by the \a value of the specified \a attr attribute. This can
186      * be any of the available solvable attributes.
187      *
188      * This method can be used multiple times with the same \a attr in which
189      * case the query strings will be combined (together with strings added
190      * via addString()) into a regex. Searched attribute value will match
191      * this regex if <b>any</b> of these strings will match the value.
192      * This can be changed by (not yet implemented) \ref setRequireAll()
193      * method.
194      *
195      * \note Though it is possible to use dependency attributes like
196      * \ref Solv::Attr::provides here, note that the query string is
197      * matched against a dependencies \c "name" part only. Any
198      * <tt>"op edition"</tt> part of a \ref Capability is \b not
199      * considered at all. \see \ref addDependency on how to query for
200      * capabilities including edition ranges.
201      *
202      * \note Solvables of a kind not supporting the specified attribute will
203      * <b>not</b> be returned.
204      * \todo check the above
205      *
206      * \param attr Attribute identfier. Use sat::Solvattr::* constants
207      * \param value What to search for.
208      *
209      * \see sat::SolvAttr
210      */
211     void addAttribute( const sat::SolvAttr & attr, const std::string & value = "" );
212
213     /** \name Filter by dependencies matching a broken down capability <tt>name [op edition]</tt>.
214      *
215      * The capabilities \c name part may be defined as query string
216      * like with \ref addAttribute. Globing and regex are supported.
217      * Global query strings defined by \ref addString are considered.
218      *
219      * So without any <tt>op edition</tt> addDependency behaves the
220      * same as \ref addAttribute. If an edition range is given, matches
221      * are restricted accordingly. Thete are various overloads, so pick
222      * the one you like best.
223      *
224      * \code
225      * {
226      *   setMatchGlob();
227      *   setCaseSensitive( false );
228      *   addDependency( sat::SolvAttr::provides, "kde*", Rel::EQ, Edition("2.0") );
229      *   addDependency( sat::SolvAttr::provides, "kde*", Edition("2.0") ); // same as above
230      * }
231      * {
232      *   setMatchGlob();
233      *   setCaseSensitive( false );
234      *   addString( "kde*" );
235      *   addDependency( sat::SolvAttr::provides, Rel::EQ, Edition("2.0") );// same as above
236      *   addDependency( sat::SolvAttr::provides, Edition("2.0") );         // same as above
237      * }
238      * \endcode
239      *
240      * \note Thre's also a version of \ref addDependency provided, that takes a
241      * complete \ref Capability as argument. This always requires an exact match
242      * of the name part (as the resolver would do it).
243      *
244      * This is the list of valid dependency attributes:
245      * \code
246      *   SolvAttr::provides
247      *   SolvAttr::obsoletes
248      *   SolvAttr::conflicts
249      *   SolvAttr::requires
250      *   SolvAttr::recommends
251      *   SolvAttr::suggests
252      *   SolvAttr::supplements
253      *   SolvAttr::enhances
254      * \endcode
255      *
256      * \note <b>What happens if a non dependency attribute is passed?<\b>
257      * If an edition range is given, it is matched against the matching
258      * solvables edition instead. Without edition range it behaves the
259      * same as \ref addAttribute.
260      *
261      * \code
262      *   // Find all packages providing "kernel > 2.0"
263      *   addDependency( sat::SolvAttr::provides, "kernel", Rel::GT, Edition("2.0") );
264      *
265      *   // // Find all packages named "kernel" and with edition "> 2.0"
266      *   addDependency( sat::SolvAttr::name, "kernel", Rel::GT, Edition("2.0") );
267      * \endcode
268      */
269     //@{
270     /** Query <tt>"name|global op edition"</tt>. */
271     void addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition );
272
273     /** \overload Query <tt>"name|global == edition"</tt>. */
274     void addDependency( const sat::SolvAttr & attr, const std::string & name, const Edition & edition )
275     { addDependency( attr, name, Rel::EQ, edition ); }
276
277     /** \overload Query <tt>"name|global"</tt>. */
278     void addDependency( const sat::SolvAttr & attr, const std::string & name )
279     { addDependency( attr, name, Rel::ANY, Edition() ); }
280
281     /** \overload Query <tt>"global op edition"</tt>.*/
282     void addDependency( const sat::SolvAttr & attr, const Rel & op, const Edition & edition )
283     { addDependency( attr, std::string(), op, edition ); }
284
285     /** \overload Query <tt>"global == edition"</tt>. */
286     void addDependency( const sat::SolvAttr & attr, const Edition & edition )
287     { addDependency( attr, std::string(), Rel::EQ, edition ); }
288
289     /** \overload Query <tt>"global"</tt>. */
290     void addDependency( const sat::SolvAttr & attr )
291     { addDependency( attr, std::string(), Rel::ANY, Edition() ); }
292
293     /** \overload Query taking a \ref Capability (always exact name match).
294      * \note If a non dependency attribute is passed, the \ref Capability
295      * will always be matched against the Solvables \c name and \c edition.
296     */
297     void addDependency( const sat::SolvAttr & attr, Capability cap_r );
298     //@}
299
300     /**
301      * Set version condition. This will filter out solvables not matching
302      * <tt>solvableEdition \a op \a edition</tt>.
303      *
304      * \param edition Edition to look for.
305      * \param op      Found-wanted relation operator.
306      */
307     void setEdition(const Edition & edition, const Rel & op = Rel::EQ);
308
309     /** \name Text Matching Options
310      * \note The implementation treats an empty search string as
311      * <it>"match always"</it>. So if you want to actually match
312      * an empty value, try <tt>( "^$", setMatchRegex )</tt>.
313      */
314     //@{
315     /**
316      * Turn case sentitivity on or off (unsets or sets \ref SEARCH_NOCASE flag).
317      * PoolQuery defaults to case insensitive search unless this method
318      * is used.
319      *
320      * \param value Whether to turn the case sensitivity on (default) or off.
321      */
322     void setCaseSensitive( bool value = true );
323
324     /**
325      * If set (default), look at the full path when searching in filelists.
326      * Otherwise just match the the basenames.
327      * \see \ref Match::FILES
328      */
329     void setFilesMatchFullPath( bool value = true );
330     /** \overload */
331     void setFilesMatchBasename( bool value = true )
332     { setFilesMatchFullPath( !value ); }
333
334     /** Set to match exact string instead of substring.*/
335     void setMatchExact();
336     /** Set to substring (the default). */
337     void setMatchSubstring();
338     /** Set to match globs. */
339     void setMatchGlob();
340     /** Set to use the query strings as regexes */
341     void setMatchRegex();
342     /** Set to match words (uses regex) */
343     void setMatchWord();
344     //void setLocale(const Locale & locale);
345     //@}
346
347     /**
348      * Require that all of the values set by addString or addAttribute
349      * match the values of respective attributes.
350      *
351      * \todo doesn't work yet, don't use this function
352      */
353     void setRequireAll( bool require_all = true );
354
355
356     /** \name getters */
357     //@{
358
359     /** Search strings added via addString() */
360     const StrContainer & strings() const;
361     /**
362      * Map (map<SolvAttr, StrContainer>) of attribute values added via
363      * addAttribute(), addDep in string form */
364     const AttrRawStrMap & attributes() const;
365
366     const StrContainer & attribute(const sat::SolvAttr & attr) const;
367
368     const Kinds & kinds() const;
369
370     const StrContainer & repos() const;
371
372     const Edition edition() const;
373     const Rel editionRel() const;
374
375     /**
376      * returns true if search is case sensitive
377      */
378     bool caseSensitive() const;
379
380     /** Whether searching in filelists looks at the full path or just at the basenames. */
381     bool filesMatchFullPath() const;
382     /** \overload */
383     bool filesMatchBasename() const
384     { return !filesMatchFullPath(); }
385
386     bool matchExact() const;
387     bool matchSubstring() const;
388     bool matchGlob() const;
389     bool matchRegex() const;
390     bool matchWord() const;
391
392     /** Returns string matching mode as enum.
393      * \see \ref Match::Mode
394      */
395     Match::Mode matchMode() const
396     { return flags().mode(); }
397
398     /**
399      * Whether all values added via addString() or addAttribute() are required
400      * to match the values of the respective attributes.
401      */
402     bool requireAll() const;
403
404     StatusFilter statusFilterFlags() const;
405     //@}
406
407     /**
408      * Reads from stream query. Attributes is sepated by delim. Query is
409      * separated by two delim.
410      *
411      * \param str input stream which contains query
412      * \param delim delimeter for attributes
413      * \return true if non-empty query is recovered
414      *
415      * \see readPoolQueriesFromFile
416      */
417     bool recover( std::istream &str, char delim = '\n' );
418
419     /**
420      * Writes a machine-readable string representation of the query to stream.
421      * Use \a delim as attribute delimiter.
422      *
423      * \param str output stream to write to
424      * \param delim delimiter for attributes
425      *
426      * \see writePoolQueriesToFile
427      */
428     void serialize( std::ostream &str, char delim = '\n' ) const;
429
430     /** Return a human-readable description of the query */
431     std::string asString() const;
432
433     bool operator==(const PoolQuery& b) const;
434     bool operator!=(const PoolQuery& b) const { return !(*this == b ); }
435
436     // low level API
437
438     /**
439      * Free function to get the satsolver repo search
440      * flags.
441      *
442      * \see \ref Match
443      */
444     Match flags() const;
445
446     /**
447      * Free function to set the satsolver repo search
448      * flags.
449      *
450      * \see \ref Match
451      */
452     void setFlags( const Match & flags );
453
454   public:
455     class Impl;
456   private:
457     /** Pointer to implementation */
458     RW_pointer<Impl> _pimpl;
459   };
460   ///////////////////////////////////////////////////////////////////
461
462   /** \relates PoolQuery Stream output. */
463   std::ostream & operator<<( std::ostream & str, const PoolQuery & obj );
464
465   ///////////////////////////////////////////////////////////////////
466   namespace detail
467   { /////////////////////////////////////////////////////////////////
468
469   class PoolQueryMatcher;
470
471   ///////////////////////////////////////////////////////////////////
472   //
473   //  CLASS NAME : PoolQuery::PoolQueryIterator
474   //
475   /** \ref PoolQuery iterator as returned by \ref PoolQuery::begin.
476    *
477    * The \ref PoolQueryIterator visits sat::Solavables that do contain matches.
478    *
479    * But it also provides an iterator by itself, to allow a detailed inspection of
480    * the individual attribute matches within the current Solvable.
481    */
482   class PoolQueryIterator : public boost::iterator_adaptor<
483     PoolQueryIterator                  // Derived
484     , sat::LookupAttr::iterator        // Base
485     , const sat::Solvable              // Value
486     , boost::forward_traversal_tag     // CategoryOrTraversal
487     , const sat::Solvable              // Reference
488   >
489   {
490       typedef std::vector<sat::LookupAttr::iterator> Matches;
491     public:
492       typedef Matches::size_type size_type;
493       typedef Matches::const_iterator matches_iterator;
494     public:
495       /** Default ctor is also \c end.*/
496       PoolQueryIterator()
497       {}
498
499       /** \Ref PoolQuery ctor. */
500       PoolQueryIterator( const shared_ptr<PoolQueryMatcher> & matcher_r )
501       : _matcher( matcher_r )
502       { increment(); }
503
504       /** \name Detailed inspection of attribute matches within the current Solvable.
505        *
506        * The \ref matches_iterator visits all attribute matches within the current Solvable,
507        * providing a \ref sat::LookupAttr::iterator pointing to attribute. While a
508        * \ref matches_iterator itself becomes invalid if the PoolQueryIterator is advanced,
509        * the \ref sat::LookupAttr::iterator it pointed to stays valid, even after the query
510        * ended.
511        *
512        * \code
513        * // Setup query for "libzypp"  in name or requires:
514        * PoolQuery q;
515        * q.addString( "libzypp" );
516        * q.setMatchSubstring();
517        * q.setCaseSensitive( false );
518        * q.addAttribute( sat::SolvAttr::name );
519        * q.addDependency( sat::SolvAttr::requires );
520        *
521        * // Iterate the result:
522        * for_( solvIter, q.begin(), q.end() )
523        * {
524        *   sat::Solvable solvable( *solvIter );
525        *   cout << "Found matches in " << solvable << endl;
526        *   if ( verbose )
527        *     for_( attrIter, solvIter.matchesBegin(), solvIter.matchesEnd() )
528        *     {
529        *       sat::LookupAttr::iterator attr( *attrIter );
530        *       cout << "    " << attr.inSolvAttr() << "\t\"" << attr.asString() << "\"" << endl;
531        *     }
532        * }
533        *
534        *
535        * Found matches in PackageKit-0.3.11-1.12.i586(@System)
536        *    solvable:requires        "libzypp.so.523"
537        * Found matches in libqdialogsolver1-1.2.6-1.1.2.i586(@System)
538        *    solvable:requires        "libzypp.so.523"
539        *    solvable:requires        "libzypp >= 5.25.3-0.1.2"
540        * Found matches in libzypp-5.30.3-0.1.1.i586(@System)
541        *    solvable:name            "libzypp"
542        * Found matches in libzypp-testsuite-tools-4.2.6-8.1.i586(@System)
543        *    solvable:name            "libzypp-testsuite-tools"
544        *    solvable:requires        "libzypp.so.523"
545        * ...
546        * \endcode
547        */
548       //@{
549       /** \c False unless this is the \c end iterator. */
550       bool matchesEmpty() const                 { return ! _matcher; }
551       /** Number of attribute matches. */
552       size_type matchesSize() const             { return matches().size(); }
553       /** Begin of matches. */
554       matches_iterator matchesBegin() const     { return matches().begin(); }
555       /** End of matches. */
556       matches_iterator matchesEnd() const       { return matches().end(); }
557       //@}
558
559     private:
560       friend class boost::iterator_core_access;
561
562       sat::Solvable dereference() const
563       { return base_reference().inSolvable(); }
564
565       void increment();
566
567     private:
568       const Matches & matches() const;
569
570     private:
571       shared_ptr<PoolQueryMatcher> _matcher;
572       mutable shared_ptr<Matches>  _matches;
573   };
574   ///////////////////////////////////////////////////////////////////
575
576   /** \relates PoolQueryIterator Stream output. */
577   inline std::ostream & operator<<( std::ostream & str, const PoolQueryIterator & obj )
578   { return str << obj.base(); }
579
580   /** \relates PoolQueryIterator Detailed stream output. */
581   std::ostream & dumpOn( std::ostream & str, const PoolQueryIterator & obj );
582
583   ///////////////////////////////////////////////////////////////////
584   } //namespace detail
585   ///////////////////////////////////////////////////////////////////
586
587   inline detail::PoolQueryIterator PoolQuery::end() const
588   { return detail::PoolQueryIterator(); }
589
590   /////////////////////////////////////////////////////////////////
591 } // namespace zypp
592 ///////////////////////////////////////////////////////////////////
593
594 #endif // ZYPP_POOLQUERY_H