libzypp  17.14.0
Repository.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <climits>
13 #include <iostream>
14 
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/Gettext.h"
17 #include "zypp/base/Exception.h"
18 #include "zypp/base/Xml.h"
19 
20 #include "zypp/AutoDispose.h"
21 #include "zypp/Pathname.h"
22 
24 #include "zypp/Repository.h"
25 #include "zypp/ResPool.h"
26 #include "zypp/Product.h"
27 #include "zypp/sat/Pool.h"
28 
29 using std::endl;
30 
32 namespace zypp
33 {
34 
35  const Repository Repository::noRepository;
36 
37  const std::string & Repository::systemRepoAlias()
39 
41 
43  { return myPool().getRepo( _id ); }
44 
45 #define NO_REPOSITORY_RETURN( VAL ) \
46  sat::detail::CRepo * _repo( get() ); \
47  if ( ! _repo ) return VAL
48 
49 #define NO_REPOSITORY_THROW( VAL ) \
50  sat::detail::CRepo * _repo( get() ); \
51  if ( ! _repo ) ZYPP_THROW( VAL )
52 
54  {
55  NO_REPOSITORY_RETURN( false );
56  return myPool().isSystemRepo( _repo );
57  }
58 
59  std::string Repository::alias() const
60  {
61  NO_REPOSITORY_RETURN( std::string() );
62  if ( ! _repo->name )
63  return std::string();
64  return _repo->name;
65  }
66 
67  std::string Repository::name() const
68  { return info().name(); }
69 
70  std::string Repository::label() const
71  { return info().label(); }
72 
74  {
75  NO_REPOSITORY_RETURN( INT_MIN );
76  return _repo->priority;
77  }
78 
80  {
81  NO_REPOSITORY_RETURN( INT_MIN );
82  return _repo->subpriority;
83  }
84 
86  {
89  return q.empty() ? std::string() : q.begin().asString();
90  }
91 
93  {
96  return q.empty() ? std::string() : q.begin().asString();
97  }
98 
100  {
101  NO_REPOSITORY_RETURN( false );
103  for_( it, q.begin(), q.end() )
104  if ( it.asString() == id_r )
105  return true;
106  return false;
107  }
108 
110  {
113  return( q.empty() ? 0 : q.begin().asUnsigned() );
114  }
115 
117  {
119  Date generated = generatedTimestamp();
120  if ( ! generated )
121  return 0; // do not calculate over a missing generated timestamp
122 
124  if ( q.empty() )
125  return 0;
126 
127  return generated + Date(q.begin().asUnsigned());
128  }
129 
131  {
134  }
135 
136  bool Repository::hasKeyword( const std::string & val_r ) const
137  {
138  for ( const auto & val : keywords() )
139  if ( val == val_r )
140  return true;
141  return false;
142  }
143 
145  {
146  NO_REPOSITORY_RETURN( false );
147  // system repo is not mirrored
148  if ( isSystemRepo() )
149  return false;
150 
151  Date suggested = suggestedExpirationTimestamp();
152 
153  // if no data, don't suggest
154  if ( ! suggested )
155  return false;
156 
158  }
159 
160  bool Repository::providesUpdatesFor( const CpeId & cpeid_r ) const
161  {
162  NO_REPOSITORY_RETURN( false );
163  if ( ! cpeid_r )
164  return false; // filter queries/products without CpeId, as an empty CpeId matches ANYthing.
165 
166  // check in repository metadata
168  {
169  if ( compare( cpeid_r, it.cpeId(), SetRelation::subset ) )
170  return true;
171  }
172 
173  // check whether known products refer to this as update repo
174  sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
175  if ( ! myIds.empty() )
176  {
177  const ResPool & pool( ResPool::instance() );
178  for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
179  {
180  Product::constPtr prod( (*it)->asKind<Product>() );
181  if ( compare( cpeid_r, prod->cpeId(), SetRelation::superset ) )
182  {
183  for_( myId, myIds.begin(), myIds.end() )
184  {
185  if ( prod->hasUpdateContentIdentifier( myId.asString() ) )
186  return true;
187  }
188  }
189  }
190  }
191  return false;
192  }
193 
195  {
196  NO_REPOSITORY_RETURN( false );
197 
198  // check in repository metadata
200  return true;
201 
202  // check whether known products refer to this as update repo
203  sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
204  if ( ! myIds.empty() )
205  {
206  const ResPool & pool( ResPool::instance() );
207  for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
208  {
209  for_( myId, myIds.begin(), myIds.end() )
210  {
211  if ( (*it)->asKind<Product>()->hasUpdateContentIdentifier( myId.asString() ) )
212  return true;
213  }
214  }
215  }
216  return false;
217  }
218 
220  {
221  NO_REPOSITORY_RETURN( true );
222  return !_repo->nsolvables;
223  }
224 
226  {
228  return _repo->nsolvables;
229  }
230 
232  {
233  NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
236  return make_filter_iterator( detail::ByRepository( *this ),
237  sat::detail::SolvableIterator(_repo->start),
238  sat::detail::SolvableIterator(_repo->end) );
239  }
240 
242  {
243  NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
246  return make_filter_iterator(detail::ByRepository( *this ),
247  sat::detail::SolvableIterator(_repo->end),
248  sat::detail::SolvableIterator(_repo->end) );
249  }
250 
252  {
255  }
256 
258  {
259  return ProductInfoIterator();
260  }
261 
263  {
266  }
267 
269  {
270  return ProductInfoIterator();
271  }
272 
274  {
276  return myPool().repoInfo( _repo );
277  }
278 
279  void Repository::setInfo( const RepoInfo & info_r )
280  {
281  NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
282  if ( info_r.alias() != alias() )
283  {
284  ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
285  info_r.alias().c_str(), alias().c_str() ) ) );
286  }
287  myPool().setRepoInfo( _repo, info_r );
288  MIL << *this << endl;
289  }
290 
292  {
294  myPool().setRepoInfo( _repo, RepoInfo() );
295  }
296 
298  {
300  MIL << *this << " removed from pool" << endl;
301  myPool()._deleteRepo( _repo );
303  }
304 
306  {
308  for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
309  {
310  if ( *it == *this )
311  {
312  if ( ++it != _for_end )
313  return *it;
314  break;
315  }
316  }
317  return noRepository;
318  }
319 
320  void Repository::addSolv( const Pathname & file_r )
321  {
322  NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
323 
324  AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "re" ), ::fclose );
325  if ( file == NULL )
326  {
327  file.resetDispose();
328  ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
329  }
330 
331  if ( myPool()._addSolv( _repo, file ) != 0 )
332  {
333  ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
334  }
335 
336  MIL << *this << " after adding " << file_r << endl;
337  }
338 
339  void Repository::addHelix( const Pathname & file_r )
340  {
341  NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
342 
343  std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
344  command += file_r.asString();
345 
346  AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
347  if ( file == NULL )
348  {
349  file.resetDispose();
350  ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
351  }
352 
353  if ( myPool()._addHelix( _repo, file ) != 0 )
354  {
355  ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
356  }
357 
358  MIL << *this << " after adding " << file_r << endl;
359  }
360 
362  {
363  NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
364  return myPool()._addSolvables( _repo, count_r );
365  }
366 
367  /******************************************************************
368  **
369  ** FUNCTION NAME : operator<<
370  ** FUNCTION TYPE : std::ostream &
371  */
372  std::ostream & operator<<( std::ostream & str, const Repository & obj )
373  {
374  if ( ! obj )
375  return str << "noRepository";
376 
377  return str << "sat::repo(" << obj.alias() << ")"
378  << "{"
379  << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
380  << ", size " << obj.solvablesSize()
381  << "}";
382  }
383 
384  std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj )
385  {
386  return xmlout::node( str, "repository", {
387  { "name", obj.name() },
388  { "alias", obj.alias() }
389  } );
390  }
391 
393  namespace detail
394  {
396  {
397  if ( base() )
398  {
400  do {
401  ++base_reference();
402  } while ( base() < satpool->repos+satpool->nrepos && !*base() );
403  }
404  }
405  } // namespace detail
407 
409  //
410  // Repository::ProductInfoIterator
411  //
413 
415  { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
416 
418  { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
419 
421  { return CpeId( base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(), CpeId::noThrow ); }
422 
424 } // namespace zypp