cd80ffcc1c5681f5f8cef410e4e66890af1c9d6f
[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 tests/zypp/PoolQuery_test.cc for more examples
81    * \see sat::SolvIterMixin
82    */
83   class PoolQuery : public sat::SolvIterMixin<PoolQuery, detail::PoolQueryIterator>
84   {
85   public:
86     typedef std::set<std::string>                           StrContainer;
87     typedef std::set<ResKind>                               Kinds;
88     typedef std::map<sat::SolvAttr, StrContainer>           AttrRawStrMap;
89     typedef std::map<sat::SolvAttr, std::string>            AttrCompiledStrMap;
90     typedef std::map<sat::SolvAttr, str::regex>             AttrRegexMap;
91
92     typedef detail::PoolQueryIterator                       const_iterator;
93     typedef unsigned int                                    size_type;
94
95   public:
96     typedef function<bool( const sat::Solvable & )> ProcessResolvable;
97
98     PoolQuery();
99     ~PoolQuery();
100
101     /** Query result accessers. */
102     //@{
103     /**
104      * Compile the query and return an iterator to the result.
105      *
106      * \return An iterator (\ref detail::PoolQueryIterator) returning
107      *         sat::Solvable objects pointing at the beginning of the query result.
108      * \throws sat::MatchInvalidRegexException if the query was about to use a regex which
109      *         failed to compile.
110      *
111      * \note Note that PoolQuery is derived from \ref sat::SolvIterMixin which
112      *       makes PoolItem and Selectable iterators automatically available.
113      * \see \ref sat::SolvIterMixin
114      */
115     const_iterator begin() const;
116
117     /** An iterator pointing to the end of the query result. */
118     const_iterator end() const;
119
120     /** Whether the result is empty. */
121     bool empty() const;
122
123     /** Number of solvables in the query result. */
124     size_type size() const;
125     //@}
126
127     /**
128      * Executes the query with the current settings.
129      * Results are yielded via the \a fnc callback.
130      */
131     void execute(ProcessResolvable fnc);
132
133     /**
134      * Filter by selectable kind.
135      *
136      * By default, all kinds will be returned. If addKind() is used,
137      * only the specified kinds will be returned (multiple kinds will be ORed).
138      *
139      * Pass ResKind constants to this method, (e.g. ResKind::package).
140      */
141     void addKind(const ResKind & kind);
142
143     /**
144      * Filter by repo.
145      *
146      * By default, all repos will be returned. If addRepo() is used,
147      * only the specified repo will be returned (multiple repos will be ORed).
148      */
149     void addRepo(const std::string &repoalias);
150
151     /** Installed status filter setters. */
152     //@{
153
154     /**
155      * Filter by status (installed uninstalled)
156      */
157     enum StatusFilter {
158       ALL = 0, // both install filter and uninstall filter bits are 0
159       INSTALLED_ONLY = 1,
160       UNINSTALLED_ONLY = 2
161     };
162
163     /** Return only @System repo packages */
164     void setInstalledOnly();
165     /** Return only packages from repos other than @System. */
166     void setUninstalledOnly();
167     /** Set status filter directly \see StatusFilter */
168     void setStatusFilterFlags( StatusFilter flags );
169
170     //@}
171
172     /**
173      * Add a global query string. The string added via this method is applied
174      * to all query attributes as if addAttribute(..., \value) was called
175      * for all of them.
176      *
177      * This method can be used multiple times in which case the query strings
178      * will be combined (together with strings added via addAttribute()) into
179      * a regex. Searched attribute value will match this regex if <b>any</b>
180      * of these strings will match the value. This can be changed by
181      * (not yet implemented) \ref setRequireAll() method.
182      */
183     void addString(const std::string & value);
184
185     /**
186      * Filter by the \a value of the specified \a attr attribute. This can
187      * be any of the available solvable attributes.
188      *
189      * This method can be used multiple times with the same \a attr in which
190      * case the query strings will be combined (together with strings added
191      * via addString()) into a regex. Searched attribute value will match
192      * this regex if <b>any</b> of these strings will match the value.
193      * This can be changed by (not yet implemented) \ref setRequireAll()
194      * method.
195      *
196      * \note Though it is possible to use dependency attributes like
197      * \ref Solv::Attr::provides here, note that the query string is
198      * matched against a dependencies \c "name" part only. Any
199      * <tt>"op edition"</tt> part of a \ref Capability is \b not
200      * considered at all. \see \ref addDependency on how to query for
201      * capabilities including edition ranges.
202      *
203      * \note Solvables of a kind not supporting the specified attribute will
204      * <b>not</b> be returned.
205      * \todo check the above
206      *
207      * \param attr Attribute identfier. Use sat::Solvattr::* constants
208      * \param value What to search for.
209      *
210      * \see sat::SolvAttr
211      */
212     void addAttribute( const sat::SolvAttr & attr, const std::string & value = "" );
213
214     /** \name Filter by dependencies matching a broken down capability <tt>name [op edition]</tt>.
215      *
216      * The capabilities \c name part may be defined as query string
217      * like with \ref addAttribute. Globing and regex are supported.
218      * Global query strings defined by \ref addString are considered.
219      *
220      * So without any <tt>op edition</tt> addDependency behaves the
221      * same as \ref addAttribute. If an edition range is given, matches
222      * are restricted accordingly. Thete are various overloads, so pick
223      * the one you like best.
224      *
225      * \code
226      * {
227      *   setMatchGlob();
228      *   setCaseSensitive( false );
229      *   addDependency( sat::SolvAttr::provides, "kde*", Rel::EQ, Edition("2.0") );
230      *   addDependency( sat::SolvAttr::provides, "kde*", Edition("2.0") ); // same as above
231      * }
232      * {
233      *   setMatchGlob();
234      *   setCaseSensitive( false );
235      *   addString( "kde*" );
236      *   addDependency( sat::SolvAttr::provides, Rel::EQ, Edition("2.0") );// same as above
237      *   addDependency( sat::SolvAttr::provides, Edition("2.0") );         // same as above
238      * }
239      * \endcode
240      *
241      * \note Thre's also a version of \ref addDependency provided, that takes a
242      * complete \ref Capability as argument. This always requires an exact match
243      * of the name part (as the resolver would do it).
244      *
245      * This is the list of valid dependency attributes:
246      * \code
247      *   SolvAttr::provides
248      *   SolvAttr::obsoletes
249      *   SolvAttr::conflicts
250      *   SolvAttr::requires
251      *   SolvAttr::recommends
252      *   SolvAttr::suggests
253      *   SolvAttr::supplements
254      *   SolvAttr::enhances
255      * \endcode
256      *
257      * \note <b>What happens if a non dependency attribute is passed?<\b>
258      * If an edition range is given, it is matched against the matching
259      * solvables edition instead. Without edition range it behaves the
260      * same as \ref addAttribute.
261      *
262      * \code
263      *   // Find all packages providing "kernel > 2.0"
264      *   addDependency( sat::SolvAttr::provides, "kernel", Rel::GT, Edition("2.0") );
265      *
266      *   // // Find all packages named "kernel" and with edition "> 2.0"
267      *   addDependency( sat::SolvAttr::name, "kernel", Rel::GT, Edition("2.0") );
268      * \endcode
269      */
270     //@{
271     /** Query <tt>"name|global op edition"</tt>. */
272     void addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition );
273
274     /** \overload Query <tt>"name|global == edition"</tt>. */
275     void addDependency( const sat::SolvAttr & attr, const std::string & name, const Edition & edition )
276     { addDependency( attr, name, Rel::EQ, edition ); }
277
278     /** \overload Query <tt>"name|global"</tt>. */
279     void addDependency( const sat::SolvAttr & attr, const std::string & name )
280     { addDependency( attr, name, Rel::ANY, Edition() ); }
281
282     /** \overload Query <tt>"global op edition"</tt>.*/
283     void addDependency( const sat::SolvAttr & attr, const Rel & op, const Edition & edition )
284     { addDependency( attr, std::string(), op, edition ); }
285
286     /** \overload Query <tt>"global == edition"</tt>. */
287     void addDependency( const sat::SolvAttr & attr, const Edition & edition )
288     { addDependency( attr, std::string(), Rel::EQ, edition ); }
289
290     /** \overload Query <tt>"global"</tt>. */
291     void addDependency( const sat::SolvAttr & attr )
292     { addDependency( attr, std::string(), Rel::ANY, Edition() ); }
293
294     /** \overload Query taking a \ref Capability (always exact name match).
295      * \note If a non dependency attribute is passed, the \ref Capability
296      * will always be matched against the Solvables \c name and \c edition.
297     */
298     void addDependency( const sat::SolvAttr & attr, Capability cap_r );
299     //@}
300
301     /**
302      * Set version condition. This will filter out solvables not matching
303      * <tt>solvableEdition \a op \a edition</tt>.
304      *
305      * \param edition Edition to look for.
306      * \param op      Found-wanted relation operator.
307      */
308     void setEdition(const Edition & edition, const Rel & op = Rel::EQ);
309
310     /** \name Text Matching Options
311      * \note The implementation treats an empty search string as
312      * <it>"match always"</it>. So if you want to actually match
313      * an empty value, try <tt>( "^$", setMatchRegex )</tt>.
314      */
315     //@{
316     /**
317      * Turn case sentitivity on or off (unsets or sets \ref SEARCH_NOCASE flag).
318      * PoolQuery defaults to case insensitive search unless this method
319      * is used.
320      *
321      * \param value Whether to turn the case sensitivity on (default) or off.
322      */
323     void setCaseSensitive( bool value = true );
324
325     /**
326      * If set (default), look at the full path when searching in filelists.
327      * Otherwise just match the the basenames.
328      * \see \ref Match::FILES
329      */
330     void setFilesMatchFullPath( bool value = true );
331     /** \overload */
332     void setFilesMatchBasename( bool value = true )
333     { setFilesMatchFullPath( !value ); }
334
335     /** Set to match exact string instead of substring.*/
336     void setMatchExact();
337     /** Set to substring (the default). */
338     void setMatchSubstring();
339     /** Set to match globs. */
340     void setMatchGlob();
341     /** Set to use the query strings as regexes */
342     void setMatchRegex();
343     /** Set to match words (uses regex) */
344     void setMatchWord();
345     //void setLocale(const Locale & locale);
346     //@}
347
348     /**
349      * Require that all of the values set by addString or addAttribute
350      * match the values of respective attributes.
351      *
352      * \todo doesn't work yet, don't use this function
353      */
354     void setRequireAll( bool require_all = true );
355
356
357     /** \name getters */
358     //@{
359
360     /** Search strings added via addString() */
361     const StrContainer & strings() const;
362     /**
363      * Map (map<SolvAttr, StrContainer>) of attribute values added via
364      * addAttribute(), addDep in string form */
365     const AttrRawStrMap & attributes() const;
366
367     const StrContainer & attribute(const sat::SolvAttr & attr) const;
368
369     const Kinds & kinds() const;
370
371     const StrContainer & repos() const;
372
373     const Edition edition() const;
374     const Rel editionRel() const;
375
376     /**
377      * returns true if search is case sensitive
378      */
379     bool caseSensitive() const;
380
381     /** Whether searching in filelists looks at the full path or just at the basenames. */
382     bool filesMatchFullPath() const;
383     /** \overload */
384     bool filesMatchBasename() const
385     { return !filesMatchFullPath(); }
386
387     bool matchExact() const;
388     bool matchSubstring() const;
389     bool matchGlob() const;
390     bool matchRegex() const;
391     bool matchWord() const;
392
393     /** Returns string matching mode as enum.
394      * \see \ref Match::Mode
395      */
396     Match::Mode matchMode() const
397     { return flags().mode(); }
398
399     /**
400      * Whether all values added via addString() or addAttribute() are required
401      * to match the values of the respective attributes.
402      */
403     bool requireAll() const;
404
405     StatusFilter statusFilterFlags() const;
406     //@}
407
408     /**
409      * Reads from stream query. Attributes is sepated by delim. Query is
410      * separated by two delim.
411      *
412      * \param str input stream which contains query
413      * \param delim delimeter for attributes
414      * \return true if non-empty query is recovered
415      *
416      * \see readPoolQueriesFromFile
417      */
418     bool recover( std::istream &str, char delim = '\n' );
419
420     /**
421      * Writes a machine-readable string representation of the query to stream.
422      * Use \a delim as attribute delimiter.
423      *
424      * \param str output stream to write to
425      * \param delim delimiter for attributes
426      *
427      * \see writePoolQueriesToFile
428      */
429     void serialize( std::ostream &str, char delim = '\n' ) const;
430
431     /** Return a human-readable description of the query */
432     std::string asString() const;
433
434     bool operator==(const PoolQuery& b) const;
435     bool operator!=(const PoolQuery& b) const { return !(*this == b ); }
436
437     // low level API
438
439     /**
440      * Free function to get the satsolver repo search
441      * flags.
442      *
443      * \see \ref Match
444      */
445     Match flags() const;
446
447     /**
448      * Free function to set the satsolver repo search
449      * flags.
450      *
451      * \see \ref Match
452      */
453     void setFlags( const Match & flags );
454
455   public:
456     class Impl;
457
458     /** \deprecated unused, buggy and useless. */
459     ZYPP_DEPRECATED void setMatchFiles() {}
460     /** \deprecated unused, buggy and useless. */
461     ZYPP_DEPRECATED bool matchFiles() const { return false; }
462     /** \deprecated There should be no need for this internal value. To
463      * switch across all match mode types, use the enum values returned
464      * by \ref matchMode().  \see \ref Match::Mode.
465      *
466      */
467     ZYPP_DEPRECATED int  matchType() const { return flags().modeval(); }
468
469
470   private:
471     /** Pointer to implementation */
472     RW_pointer<Impl> _pimpl;
473   };
474   ///////////////////////////////////////////////////////////////////
475
476   /** \relates PoolQuery Stream output. */
477   std::ostream & operator<<( std::ostream & str, const PoolQuery & obj );
478
479
480   ///////////////////////////////////////////////////////////////////
481   namespace detail
482   { /////////////////////////////////////////////////////////////////
483
484   class PoolQueryMatcher;
485
486   ///////////////////////////////////////////////////////////////////
487   //
488   //  CLASS NAME : PoolQuery::PoolQueryIterator
489   //
490   /** \ref PoolQuery iterator as returned by \ref PoolQuery::begin.
491   */
492   class PoolQueryIterator : public boost::iterator_adaptor<
493     PoolQueryIterator                  // Derived
494     , sat::LookupAttr::iterator        // Base
495     , const sat::Solvable              // Value
496     , boost::forward_traversal_tag     // CategoryOrTraversal
497     , const sat::Solvable              // Reference
498   >
499   {
500     public:
501       /** Default ctor is also \c end.*/
502       PoolQueryIterator()
503       {}
504
505       /** \Ref PoolQuery ctor. */
506       PoolQueryIterator( const shared_ptr<PoolQueryMatcher> & matcher_r )
507       : _matcher( matcher_r )
508       { increment(); }
509
510     private:
511       friend class boost::iterator_core_access;
512
513       sat::Solvable dereference() const
514       { return base_reference().inSolvable(); }
515
516       void increment();
517
518    private:
519       shared_ptr<PoolQueryMatcher> _matcher;
520   };
521   ///////////////////////////////////////////////////////////////////
522
523   /** \relates PoolQueryIterator Stream output. */
524   inline std::ostream & operator<<( std::ostream & str, const PoolQueryIterator & obj )
525   { return str << obj.base(); }
526
527   ///////////////////////////////////////////////////////////////////
528   } //namespace detail
529   ///////////////////////////////////////////////////////////////////
530
531   inline detail::PoolQueryIterator PoolQuery::end() const
532   { return detail::PoolQueryIterator(); }
533
534   /////////////////////////////////////////////////////////////////
535 } // namespace zypp
536 ///////////////////////////////////////////////////////////////////
537
538 #endif // ZYPP_POOLQUERY_H