package_database.hh

Go to the documentation of this file.
00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh
00005  *
00006  * This file is part of the Paludis package manager. Paludis is free software;
00007  * you can redistribute it and/or modify it under the terms of the GNU General
00008  * Public License version 2, as published by the Free Software Foundation.
00009  *
00010  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
00011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013  * details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifndef PALUDIS_GUARD_PALUDIS_PACKAGE_DATABASE_HH
00021 #define PALUDIS_GUARD_PALUDIS_PACKAGE_DATABASE_HH 1
00022 
00023 #include <paludis/package_database-fwd.hh>
00024 #include <paludis/dep_spec.hh>
00025 #include <paludis/name.hh>
00026 #include <paludis/repository.hh>
00027 #include <paludis/selection-fwd.hh>
00028 #include <paludis/filter-fwd.hh>
00029 #include <paludis/util/exception.hh>
00030 #include <paludis/util/join.hh>
00031 #include <paludis/util/pimp.hh>
00032 #include <paludis/util/stringify.hh>
00033 #include <paludis/util/wrapped_forward_iterator.hh>
00034 #include <paludis/version_spec.hh>
00035 #include <paludis/contents.hh>
00036 
00037 #include <iosfwd>
00038 
00039 /** \file
00040  * Declarations for PackageDatabase.
00041  *
00042  * \ingroup g_package_database
00043  *
00044  * \section Examples
00045  *
00046  * - \ref example_package_database.cc "example_package_database.cc"
00047  */
00048 
00049 namespace paludis
00050 {
00051     /**
00052      * A PackageDatabaseError is an error that occurs when performing some
00053      * operation upon a PackageDatabase.
00054      *
00055      * \ingroup g_exceptions
00056      * \ingroup g_package_database
00057      */
00058     class PALUDIS_VISIBLE PackageDatabaseError :
00059         public Exception
00060     {
00061         protected:
00062             /**
00063              * Constructor.
00064              */
00065             PackageDatabaseError(const std::string & message) throw ();
00066     };
00067 
00068     /**
00069      * A PackageDatabaseLookupError descendent is thrown if an error occurs
00070      * when looking for something in a PackageDatabase.
00071      *
00072      * \ingroup g_exceptions
00073      * \ingroup g_package_database
00074      */
00075     class PALUDIS_VISIBLE PackageDatabaseLookupError :
00076         public PackageDatabaseError
00077     {
00078         protected:
00079             /**
00080              * Constructor.
00081              */
00082             PackageDatabaseLookupError(const std::string & message) throw ();
00083     };
00084 
00085     /**
00086      * Thrown if a PackageDatabase query results in more than one matching
00087      * Package.
00088      *
00089      * \ingroup g_exceptions
00090      * \ingroup g_package_database
00091      * \nosubgrouping
00092      */
00093     class PALUDIS_VISIBLE AmbiguousPackageNameError :
00094         public PackageDatabaseLookupError
00095     {
00096         private:
00097             struct NameData;
00098             NameData * const _name_data;
00099 
00100             std::string _name;
00101 
00102         public:
00103             ///\name Basic operations
00104             ///\{
00105 
00106             template <typename I_>
00107             AmbiguousPackageNameError(const std::string & name,
00108                     I_ begin, const I_ end) throw ();
00109 
00110             AmbiguousPackageNameError(const AmbiguousPackageNameError &);
00111 
00112             virtual ~AmbiguousPackageNameError() throw ();
00113 
00114             ///\}
00115 
00116             /**
00117              * The name of the package.
00118              */
00119             const std::string & name() const PALUDIS_ATTRIBUTE((warn_unused_result));
00120 
00121             ///\name Iterate over possible matches
00122             ///\{
00123 
00124             struct OptionsConstIteratorTag;
00125             typedef WrappedForwardIterator<OptionsConstIteratorTag,
00126                     const std::string> OptionsConstIterator;
00127 
00128             OptionsConstIterator begin_options() const PALUDIS_ATTRIBUTE((warn_unused_result));
00129             OptionsConstIterator end_options() const PALUDIS_ATTRIBUTE((warn_unused_result));
00130 
00131             ///\}
00132     };
00133 
00134     /**
00135      * Thrown if a Repository with the same name as an existing member is added
00136      * to a PackageDatabase.
00137      *
00138      * \ingroup g_exceptions
00139      * \ingroup g_package_database
00140      * \nosubgrouping
00141      */
00142     class PALUDIS_VISIBLE DuplicateRepositoryError :
00143         public PackageDatabaseError
00144     {
00145         public:
00146             /**
00147              * Constructor.
00148              */
00149             DuplicateRepositoryError(const std::string & name) throw ();
00150     };
00151 
00152     /**
00153      * Thrown if there is no Package in a PackageDatabase with the given
00154      * name.
00155      *
00156      * \ingroup g_exceptions
00157      * \ingroup g_package_database
00158      */
00159     class PALUDIS_VISIBLE NoSuchPackageError :
00160         public PackageDatabaseLookupError
00161     {
00162         private:
00163             std::string _name;
00164 
00165         public:
00166             ///\name Basic operations
00167             ///\{
00168 
00169             NoSuchPackageError(const std::string & name) throw ();
00170 
00171             virtual ~NoSuchPackageError() throw ()
00172             {
00173             }
00174 
00175             ///\}
00176 
00177             /**
00178              * Name of the package.
00179              */
00180             const std::string & name() const
00181             {
00182                 return _name;
00183             }
00184     };
00185 
00186     /**
00187      * Thrown if there is no Repository in a RepositoryDatabase with the given
00188      * name.
00189      *
00190      * \ingroup g_exceptions
00191      * \ingroup g_package_database
00192      */
00193     class PALUDIS_VISIBLE NoSuchRepositoryError : public PackageDatabaseLookupError
00194     {
00195         private:
00196             const RepositoryName _name;
00197 
00198         public:
00199             ///\name Basic operations
00200             ///\{
00201 
00202             NoSuchRepositoryError(const RepositoryName &) throw ();
00203 
00204             ~NoSuchRepositoryError() throw ();
00205 
00206             ///\}
00207 
00208             /**
00209              * The name of our repository.
00210              */
00211             RepositoryName name() const;
00212     };
00213 
00214     /**
00215      * A PackageDatabase, which is owned by an Environment, contains a number of
00216      * Repository instances and supports various querying methods.
00217      *
00218      * \ingroup g_package_database
00219      */
00220     class PALUDIS_VISIBLE PackageDatabase :
00221         private Pimp<PackageDatabase>
00222     {
00223         private:
00224             static const Filter & all_filter() PALUDIS_ATTRIBUTE((warn_unused_result));
00225 
00226         public:
00227             ///\name Basic operations
00228             ///\{
00229 
00230             explicit PackageDatabase(const Environment * const);
00231 
00232             ~PackageDatabase();
00233 
00234             PackageDatabase(const PackageDatabase &) = delete;
00235             PackageDatabase & operator= (const PackageDatabase &) = delete;
00236 
00237             ///\}
00238 
00239             /**
00240              * Add a repository.
00241              *
00242              * \exception DuplicateRepositoryError if a Repository with the
00243              * same name as the new Repository already exists in our
00244              * collection.
00245              */
00246             void add_repository(int importance, const std::shared_ptr<Repository>);
00247 
00248             /**
00249              * Fetch a named repository.
00250              */
00251             std::shared_ptr<const Repository> fetch_repository(const RepositoryName &) const
00252                 PALUDIS_ATTRIBUTE((warn_unused_result));
00253 
00254             /**
00255              * Fetch a named repository.
00256              */
00257             std::shared_ptr<Repository> fetch_repository(const RepositoryName &)
00258                 PALUDIS_ATTRIBUTE((warn_unused_result));
00259 
00260             /**
00261              * Do we have a named repository?
00262              */
00263             bool has_repository_named(const RepositoryName &) const
00264                 PALUDIS_ATTRIBUTE((warn_unused_result));
00265 
00266             /**
00267              * Fetch the name of our 'favourite' repository (if a repository's
00268              * name matches this when doing a graphical display, the repository
00269              * name part may be omitted).
00270              *
00271              * Note that this is the repository with the <i>lowest</i> importance
00272              * that is not a virtuals or installed_virtuals repository.
00273              */
00274             RepositoryName favourite_repository() const
00275                 PALUDIS_ATTRIBUTE((warn_unused_result));
00276 
00277             /**
00278              * Disambiguate a package name.  If a filter is specified,
00279              * limit the potential results to packages that match.
00280              *
00281              * \throw AmbiguousPackageNameError if there is no unambiguous
00282              * disambiguation.
00283              */
00284             QualifiedPackageName fetch_unique_qualified_package_name(
00285                     const PackageNamePart &, const Filter & = all_filter()) const
00286                 PALUDIS_ATTRIBUTE((warn_unused_result));
00287 
00288             /**
00289              * Return true if the first repository is more important than the second.
00290              */
00291             bool more_important_than(const RepositoryName &, const RepositoryName &) const
00292                 PALUDIS_ATTRIBUTE((warn_unused_result));
00293 
00294             ///\name Iterate over our repositories
00295             ///\{
00296 
00297             struct RepositoryConstIteratorTag;
00298             typedef WrappedForwardIterator<RepositoryConstIteratorTag, const std::shared_ptr<Repository> > RepositoryConstIterator;
00299 
00300             RepositoryConstIterator begin_repositories() const
00301                 PALUDIS_ATTRIBUTE((warn_unused_result));
00302 
00303             RepositoryConstIterator end_repositories() const
00304                 PALUDIS_ATTRIBUTE((warn_unused_result));
00305 
00306             ///\}
00307     };
00308 
00309     extern template class WrappedForwardIterator<PackageDatabase::RepositoryConstIteratorTag, const std::shared_ptr<Repository> >;
00310     extern template class WrappedForwardIterator<AmbiguousPackageNameError::OptionsConstIteratorTag, const std::string>;
00311 }
00312 
00313 #endif