Remove obsolete ResStatus bits.
[platform/upstream/libzypp.git] / zypp / Repository.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Repository.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/Gettext.h"
16 #include "zypp/base/Exception.h"
17
18 #include "zypp/AutoDispose.h"
19 #include "zypp/Pathname.h"
20 #include "zypp/media/MediaPriority.h"
21
22 #include "zypp/sat/detail/PoolImpl.h"
23 #include "zypp/Repository.h"
24 #include "zypp/sat/Pool.h"
25
26 using std::endl;
27
28 ///////////////////////////////////////////////////////////////////
29 namespace zypp
30 { /////////////////////////////////////////////////////////////////
31
32     const Repository Repository::noRepository;
33
34     const std::string & Repository::systemRepoAlias()
35     { return sat::detail::PoolImpl::systemRepoAlias(); }
36
37     /////////////////////////////////////////////////////////////////
38
39     ::_Repo * Repository::get() const
40     { return myPool().getRepo( _id ); }
41
42 #define NO_REPOSITORY_RETURN( VAL ) \
43     ::_Repo * _repo( get() ); \
44     if ( ! _repo ) return VAL
45
46 #define NO_REPOSITORY_THROW( VAL ) \
47     ::_Repo * _repo( get() ); \
48     if ( ! _repo ) ZYPP_THROW( VAL )
49
50     bool Repository::isSystemRepo() const
51     {
52         NO_REPOSITORY_RETURN( false );
53         return myPool().isSystemRepo( _repo );
54     }
55
56     std::string Repository::alias() const
57     {
58       NO_REPOSITORY_RETURN( std::string() );
59       if ( ! _repo->name )
60         return std::string();
61       return _repo->name;
62     }
63
64     std::string Repository::name() const
65     { return info().name(); }
66
67     zypp::Date Repository::generatedTimestamp() const
68     {
69       NO_REPOSITORY_RETURN( 0 );
70       sat::LookupRepoAttr q( sat::SolvAttr::repositoryTimestamp, *this );
71       return( q.empty() ? 0 : q.begin().asUnsigned() );
72     }
73
74     zypp::Date Repository::suggestedExpirationTimestamp() const
75     {
76       NO_REPOSITORY_RETURN( 0 );
77       Date generated = generatedTimestamp();
78       if ( ! generated )
79         return 0; // do not calculate over a missing generated timestamp
80
81       sat::LookupRepoAttr q( sat::SolvAttr::repositoryExpire, *this );
82       if ( q.empty() )
83         return 0;
84
85       return generated + q.begin().asUnsigned();
86     }
87
88     Repository::Keywords Repository::keywords() const
89     {
90       NO_REPOSITORY_RETURN( Keywords() );
91       return Keywords( sat::SolvAttr::repositoryKeywords, *this, sat::LookupAttr::REPO_ATTR );
92     }
93
94     bool Repository::maybeOutdated() const
95     {
96       NO_REPOSITORY_RETURN( false );
97       // system repo is not mirrored
98       if ( isSystemRepo() )
99         return false;
100
101       Date suggested = suggestedExpirationTimestamp();
102
103       // if no data, don't suggest
104       if ( ! suggested )
105         return false;
106
107       return suggestedExpirationTimestamp() < Date::now();
108     }
109
110     bool Repository::providesUpdatesFor( const std::string &key ) const
111     {
112       NO_REPOSITORY_RETURN( false );
113
114       for_( it,
115             updatesProductBegin(),
116             updatesProductEnd() )
117       {
118         // FIXME implement real CPE matching here
119         // someday
120         if ( key == it.cpeId() )
121           return true;
122       }
123
124       return false;
125     }
126
127     bool Repository::isUpdateRepo() const
128     {
129       NO_REPOSITORY_RETURN( false );
130       return ( updatesProductBegin() != updatesProductEnd() );
131     }
132
133     bool Repository::solvablesEmpty() const
134     {
135       NO_REPOSITORY_RETURN( true );
136       return !_repo->nsolvables;
137     }
138
139     Repository::size_type Repository::solvablesSize() const
140     {
141       NO_REPOSITORY_RETURN( 0 );
142       return _repo->nsolvables;
143     }
144
145     Repository::SolvableIterator Repository::solvablesBegin() const
146     {
147       NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
148                             sat::detail::SolvableIterator(),
149                             sat::detail::SolvableIterator() ) );
150       return make_filter_iterator( detail::ByRepository( *this ),
151                                    sat::detail::SolvableIterator(_repo->start),
152                                    sat::detail::SolvableIterator(_repo->end) );
153     }
154
155     Repository::SolvableIterator Repository::solvablesEnd() const
156     {
157       NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
158                             sat::detail::SolvableIterator(),
159                             sat::detail::SolvableIterator() ) );
160       return make_filter_iterator(detail::ByRepository( *this ),
161                                   sat::detail::SolvableIterator(_repo->end),
162                                   sat::detail::SolvableIterator(_repo->end) );
163     }
164
165     Repository::ProductInfoIterator Repository::compatibleWithProductBegin() const
166     {
167       NO_REPOSITORY_RETURN( ProductInfoIterator() );
168       return ProductInfoIterator( sat::SolvAttr::repositoryDistros, *this );
169     }
170
171     Repository::ProductInfoIterator Repository::compatibleWithProductEnd() const
172     {
173       return ProductInfoIterator();
174     }
175
176     Repository::ProductInfoIterator Repository::updatesProductBegin() const
177     {
178       NO_REPOSITORY_RETURN( ProductInfoIterator() );
179       return ProductInfoIterator( sat::SolvAttr::repositoryUpdates, *this );
180     }
181
182     Repository::ProductInfoIterator Repository::updatesProductEnd() const
183     {
184       return ProductInfoIterator();
185     }
186
187     RepoInfo Repository::info() const
188     {
189       NO_REPOSITORY_RETURN( RepoInfo() );
190       return myPool().repoInfo( _repo );
191     }
192
193     void Repository::setInfo( const RepoInfo & info_r )
194     {
195         NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
196         if ( info_r.alias() != alias() )
197         {
198             ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
199                                               info_r.alias().c_str(), alias().c_str() ) ) );
200         }
201         myPool().setRepoInfo( _repo, info_r );
202
203         // satsolver priority is based on '<', while yum's repoinfo
204         // uses 1(highest)->99(lowest). Thus we use -info_r.priority.
205         _repo->priority = -info_r.priority();
206
207         // subpriority is used to e.g. prefer http over dvd iff
208         // both have same priority.
209         _repo->subpriority = media::MediaPriority( info_r.url() );
210
211         MIL << *this << endl;
212     }
213
214     void Repository::clearInfo()
215     {
216         NO_REPOSITORY_RETURN();
217         myPool().setRepoInfo( _repo, RepoInfo() );
218     }
219
220     void Repository::eraseFromPool()
221     {
222         NO_REPOSITORY_RETURN();
223         MIL << *this << " removed from pool" << endl;
224         myPool()._deleteRepo( _repo );
225         _id = sat::detail::noRepoId;
226     }
227
228     Repository Repository::nextInPool() const
229     {
230       NO_REPOSITORY_RETURN( noRepository );
231       for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
232       {
233         if ( *it == *this )
234         {
235           if ( ++it != _for_end )
236             return *it;
237           break;
238         }
239       }
240       return noRepository;
241     }
242
243     void Repository::addSolv( const Pathname & file_r )
244     {
245       NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
246
247       AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "r" ), ::fclose );
248       if ( file == NULL )
249       {
250         file.resetDispose();
251         ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
252       }
253
254       if ( myPool()._addSolv( _repo, file ) != 0 )
255       {
256         ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
257       }
258
259       MIL << *this << " after adding " << file_r << endl;
260     }
261
262     void Repository::addHelix( const Pathname & file_r )
263     {
264       NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
265
266       std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
267       command += file_r.asString();
268
269       AutoDispose<FILE*> file( ::popen( command.c_str(), "r" ), ::pclose );
270       if ( file == NULL )
271       {
272         file.resetDispose();
273         ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
274       }
275
276       if ( myPool()._addHelix( _repo, file ) != 0 )
277       {
278         ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
279       }
280
281       MIL << *this << " after adding " << file_r << endl;
282     }
283
284     sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
285     {
286         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
287         return myPool()._addSolvables( _repo, count_r );
288     }
289
290     /******************************************************************
291      **
292      ** FUNCTION NAME : operator<<
293      ** FUNCTION TYPE : std::ostream &
294      */
295     std::ostream & operator<<( std::ostream & str, const Repository & obj )
296     {
297         if ( ! obj )
298             return str << "noRepository";
299
300         return str << "sat::repo(" << obj.alias() << ")"
301                    << "{"
302                    << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
303                    << ", size " << obj.solvablesSize()
304                    << "}";
305     }
306
307     ///////////////////////////////////////////////////////////////////
308     //
309     // Repository::ProductInfoIterator
310     //
311     ///////////////////////////////////////////////////////////////////
312
313     Repository::ProductInfoIterator::ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r )
314     { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
315
316     std::string Repository::ProductInfoIterator::label() const
317     { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
318
319     std::string Repository::ProductInfoIterator::cpeId() const
320     { return base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(); }
321
322     /////////////////////////////////////////////////////////////////
323 } // namespace zypp
324 ///////////////////////////////////////////////////////////////////