- Adapt to satsolver changes.
[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 #warning FIX to iterator
62     zypp::Date Repository::generatedTimestamp() const
63     {
64         ::Dataiterator di;
65         ::dataiterator_init(&di, get(), SOLVID_META, REPOSITORY_TIMESTAMP, 0, 0);
66         if (::dataiterator_step(&di))
67         {
68             do
69             {
70                 switch (di.key->name)
71                 {
72                     case REPOSITORY_TIMESTAMP:
73                     {
74                         return di.kv.num;
75                         break;
76                     }
77                 }
78             }
79             while (::dataiterator_step(&di));
80       }
81       else
82       {
83           if ( isSystemRepo() )
84             return 0;
85           ERR << "the attribute generated timestamp does not exist in the repo" << endl;
86       }
87
88       return Date();
89     }
90
91
92     zypp::Date Repository::suggestedExpirationTimestamp() const
93     {
94         ::Dataiterator di;
95         ::dataiterator_init(&di, get(), SOLVID_META, REPOSITORY_EXPIRE, 0, 0);
96         Date generated = generatedTimestamp();
97         // do not calculate over a missing generated
98         // timestamp
99         if ( generated == Date() )
100             return Date();
101
102         if (::dataiterator_step(&di))
103         {
104             do
105             {
106                 switch (di.key->name)
107                 {
108                     case REPOSITORY_EXPIRE:
109                     {
110                         return generated + di.kv.num;
111                         break;
112                     }
113                 }
114             }
115             while (::dataiterator_step(&di));
116       }
117       else
118       {
119         if ( isSystemRepo() )
120             return 0;
121         ERR << "the attribute suggested expiration timestamp does not exist in the repo" << endl;
122       }
123
124       return Date();
125     }
126
127     Repository::Keywords Repository::keywords() const
128     { return Keywords(sat::SolvAttr::repositoryKeywords); }
129
130     Repository::Products Repository::products() const
131     { return Products(sat::SolvAttr::repositoryProducts); }
132
133     bool Repository::maybeOutdated() const
134     {
135         // system repo is not mirrored
136         if ( isSystemRepo() )
137             return false;
138
139         Date suggested = suggestedExpirationTimestamp();
140
141         // if no data, don't suggest
142         if ( suggested == Date() )
143             return false;
144
145         return suggestedExpirationTimestamp() < Date::now();
146     }
147
148     bool Repository::providesUpdatesFor( const std::string &key ) const
149     {
150         return false;
151     }
152
153     bool Repository::isUpdateRepo() const
154     {
155         return false;
156     }
157
158     bool Repository::solvablesEmpty() const
159     {
160         NO_REPOSITORY_RETURN( true );
161         return !_repo->nsolvables;
162     }
163
164     Repository::size_type Repository::solvablesSize() const
165     {
166         NO_REPOSITORY_RETURN( 0 );
167         return _repo->nsolvables;
168     }
169
170     Repository::SolvableIterator Repository::solvablesBegin() const
171     {
172         NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
173                                               sat::detail::SolvableIterator(),
174                                               sat::detail::SolvableIterator() ) );
175         return make_filter_iterator( detail::ByRepository( *this ),
176                                      sat::detail::SolvableIterator(_repo->start),
177                                      sat::detail::SolvableIterator(_repo->end) );
178     }
179
180     Repository::SolvableIterator Repository::solvablesEnd() const
181     {
182         NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
183                                               sat::detail::SolvableIterator(),
184                                               sat::detail::SolvableIterator() ) );
185         return make_filter_iterator(detail::ByRepository( *this ),
186                                     sat::detail::SolvableIterator(_repo->end),
187                                     sat::detail::SolvableIterator(_repo->end) );
188     }
189
190     RepoInfo Repository::info() const
191     {
192         NO_REPOSITORY_RETURN( RepoInfo() );
193         return myPool().repoInfo( _repo );
194     }
195
196     void Repository::setInfo( const RepoInfo & info_r )
197     {
198         NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
199         if ( info_r.alias() != alias() )
200         {
201             ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
202                                               info_r.alias().c_str(), alias().c_str() ) ) );
203         }
204         myPool().setRepoInfo( _repo, info_r );
205
206         // satsolver priority is based on '<', while yum's repoinfo
207         // uses 1(highest)->99(lowest). Thus we use -info_r.priority.
208         _repo->priority = -info_r.priority();
209     }
210
211     void Repository::clearInfo()
212     {
213         NO_REPOSITORY_RETURN();
214         myPool().setRepoInfo( _repo, RepoInfo() );
215     }
216
217     void Repository::eraseFromPool()
218     {
219         NO_REPOSITORY_RETURN();
220         myPool()._deleteRepo( _repo );
221         _id = sat::detail::noRepoId;
222     }
223
224     Repository Repository::nextInPool() const
225     {
226       NO_REPOSITORY_RETURN( noRepository );
227       for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
228       {
229         if ( *it == *this )
230         {
231           if ( ++it != _for_end )
232             return *it;
233           break;
234         }
235       }
236       return noRepository;
237     }
238
239 #warning NEED POOL MANIP EXEPTIONS
240     void Repository::addSolv( const Pathname & file_r )
241     {
242         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
243
244         AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "r" ), ::fclose );
245         if ( file == NULL )
246         {
247             file.resetDispose();
248             ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ));
249         }
250
251         if ( myPool()._addSolv( _repo, file, isSystemRepo() ) != 0 )
252         {
253             ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ));
254         }
255     }
256
257     sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
258     {
259         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
260         return myPool()._addSolvables( _repo, count_r );
261     }
262
263     /******************************************************************
264      **
265      ** FUNCTION NAME : operator<<
266      ** FUNCTION TYPE : std::ostream &
267      */
268     std::ostream & operator<<( std::ostream & str, const Repository & obj )
269     {
270         if ( ! obj )
271             return str << "noRepository";
272
273         return str << "sat::repo(" << obj.alias() << ")"
274                    << "{"
275                    << "prio " << obj.get()->priority
276                    << ", size " << obj.solvablesSize()
277                    <<"}";
278     }
279
280
281     /////////////////////////////////////////////////////////////////
282 } // namespace zypp
283 ///////////////////////////////////////////////////////////////////