repository keys work
[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
21 #include "zypp/sat/detail/PoolImpl.h"
22 #include "zypp/Repository.h"
23 #include "zypp/sat/Pool.h"
24
25 using std::endl;
26
27 ///////////////////////////////////////////////////////////////////
28 namespace zypp
29 { /////////////////////////////////////////////////////////////////
30   ///////////////////////////////////////////////////////////////////
31
32     const Repository Repository::noRepository;
33
34     /////////////////////////////////////////////////////////////////
35
36     ::_Repo * Repository::get() const
37     { return myPool().getRepo( _id ); }
38
39 #define NO_REPOSITORY_RETURN( VAL ) \
40     ::_Repo * _repo( get() ); \
41     if ( ! _repo ) return VAL
42
43 #define NO_REPOSITORY_THROW( VAL ) \
44     ::_Repo * _repo( get() ); \
45     if ( ! _repo ) ZYPP_THROW( VAL )
46
47     bool Repository::isSystemRepo() const
48     {
49         NO_REPOSITORY_RETURN( false );
50         return( sat::Pool::systemRepoAlias() == _repo->name );
51     }
52
53     std::string Repository::alias() const
54     {
55         NO_REPOSITORY_RETURN( std::string() );
56         if ( ! _repo->name )
57             return std::string();
58         return _repo->name;
59     }
60
61     zypp::Date Repository::generatedTimestamp() const
62     {
63         ::Dataiterator di;
64         ::dataiterator_init(&di, get(), -1, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
65         if (::dataiterator_step(&di))
66         {
67             do
68             {
69                 switch (di.key->name)
70                 {
71                     case REPOSITORY_TIMESTAMP:
72                     {
73                         return di.kv.num;
74                         break;
75                     }
76                 }
77             }
78             while (::dataiterator_step(&di));
79       }
80       else
81       {    
82           if ( isSystemRepo() )
83             return 0;
84           ERR << "the attribute generated timestamp does not exist in the repo" << endl;
85       }
86         
87       return Date();        
88     }
89     
90
91     zypp::Date Repository::suggestedExpirationTimestamp() const
92     {
93         ::Dataiterator di;
94         ::dataiterator_init(&di, get(), -1, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
95         Date generated = generatedTimestamp();
96         // do not calculate over a missing generated
97         // timestamp
98         if ( generated == Date() )
99             return Date();
100         
101         if (::dataiterator_step(&di))
102         {
103             do
104             {
105                 switch (di.key->name)
106                 {
107                     case REPOSITORY_EXPIRE:
108                     {
109                         return generated + di.kv.num;
110                         break;
111                     }
112                 }
113             }
114             while (::dataiterator_step(&di));
115       }
116       else
117       {     
118         if ( isSystemRepo() )
119             return 0;
120         ERR << "the attribute suggested expiration timestamp does not exist in the repo" << endl;
121       }
122         
123       return Date();
124     }
125
126     bool Repository::maybeOutdated() const
127     {
128         // system repo is not mirrored
129         if ( isSystemRepo() )
130             return false;
131         
132         Date suggested = suggestedExpirationTimestamp();
133         
134         // if no data, don't suggest
135         if ( suggested == Date() ) 
136             return false;
137
138         return suggestedExpirationTimestamp() < Date::now();
139     }
140
141     Repository::UpdateKeys Repository::updateKeys() const
142     { return UpdateKeys( sat::SolvAttr::repositoryUpdates, *this ); }
143     
144     bool Repository::providesUpdatesForKey( const std::string &key ) const
145     {
146         UpdateKeys keys(updateKeys());
147         return ( keys.find(key) != keys.end() );
148     }
149     
150     bool Repository::isUpdateRepo() const
151     {
152         return ( ! updateKeys().empty() );
153     }
154
155     bool Repository::solvablesEmpty() const
156     {
157         NO_REPOSITORY_RETURN( true );
158         return !_repo->nsolvables;
159     }
160
161     Repository::size_type Repository::solvablesSize() const
162     {
163         NO_REPOSITORY_RETURN( 0 );
164         return _repo->nsolvables;
165     }
166
167     Repository::SolvableIterator Repository::solvablesBegin() const
168     {
169         NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
170                                               sat::detail::SolvableIterator(),
171                                               sat::detail::SolvableIterator() ) );
172         return make_filter_iterator( detail::ByRepository( *this ),
173                                      sat::detail::SolvableIterator(_repo->start),
174                                      sat::detail::SolvableIterator(_repo->end) );
175     }
176
177     Repository::SolvableIterator Repository::solvablesEnd() const
178     {
179         NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
180                                               sat::detail::SolvableIterator(),
181                                               sat::detail::SolvableIterator() ) );
182         return make_filter_iterator(detail::ByRepository( *this ),
183                                     sat::detail::SolvableIterator(_repo->end),
184                                     sat::detail::SolvableIterator(_repo->end) );
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
208     void Repository::clearInfo()
209     {
210         NO_REPOSITORY_RETURN();
211         myPool().setRepoInfo( _repo, RepoInfo() );
212     }
213
214     void Repository::eraseFromPool()
215     {
216         NO_REPOSITORY_RETURN();
217         myPool()._deleteRepo( _repo );
218         _id = sat::detail::noRepoId;
219     }
220
221     Repository Repository::nextInPool() const
222     {
223       NO_REPOSITORY_RETURN( noRepository );
224       for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
225       {
226         if ( *it == *this )
227         {
228           if ( ++it != _for_end )
229             return *it;
230           break;
231         }
232       }
233       return noRepository;
234     }
235
236 #warning NEED POOL MANIP EXEPTIONS
237     void Repository::addSolv( const Pathname & file_r )
238     {
239         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
240
241         AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "r" ), ::fclose );
242         if ( file == NULL )
243         {
244             file.resetDispose();
245             ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ));
246         }
247
248         if ( myPool()._addSolv( _repo, file, isSystemRepo() ) != 0 )
249         {
250             ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ));
251         }
252     }
253
254     sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
255     {
256         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
257         return myPool()._addSolvables( _repo, count_r );
258     }
259
260     /******************************************************************
261      **
262      ** FUNCTION NAME : operator<<
263      ** FUNCTION TYPE : std::ostream &
264      */
265     std::ostream & operator<<( std::ostream & str, const Repository & obj )
266     {
267         if ( ! obj )
268             return str << "noRepository";
269
270         return str << "sat::repo(" << obj.alias() << ")"
271                    << "{"
272                    << "prio " << obj.get()->priority
273                    << ", size " << obj.solvablesSize()
274                    <<"}";
275     }
276
277
278     /////////////////////////////////////////////////////////////////
279 } // namespace zypp
280 ///////////////////////////////////////////////////////////////////