00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <iostream>
00011 #include <map>
00012
00013 #include "zypp/base/Gettext.h"
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Measure.h"
00016 #include "zypp/capability/Capabilities.h"
00017 #include "zypp/cache/ResolvableQuery.h"
00018 #include "zypp/detail/ResImplTraits.h"
00019 #include "zypp/CapFactory.h"
00020
00021 #include "zypp/Package.h"
00022 #include "zypp/SrcPackage.h"
00023 #include "zypp/Product.h"
00024 #include "zypp/Pattern.h"
00025 #include "zypp/Patch.h"
00026 #include "zypp/Message.h"
00027 #include "zypp/Script.h"
00028 #include "zypp/Atom.h"
00029
00030 #include "zypp/repo/cached/RepoImpl.h"
00031 #include "zypp/repo/cached/PackageImpl.h"
00032 #include "zypp/repo/cached/SrcPackageImpl.h"
00033 #include "zypp/repo/cached/ProductImpl.h"
00034 #include "zypp/repo/cached/PatternImpl.h"
00035 #include "zypp/repo/cached/PatchImpl.h"
00036 #include "zypp/repo/cached/MessageImpl.h"
00037 #include "zypp/repo/cached/ScriptImpl.h"
00038 #include "zypp/repo/cached/AtomImpl.h"
00039 #include "zypp/cache/CacheAttributes.h"
00040
00041 using namespace zypp::detail;
00042 using namespace zypp::cache;
00043 using namespace std;
00044 using namespace sqlite3x;
00045
00047 namespace zypp
00048 {
00049
00050 namespace repo
00051 {
00052
00053 namespace cached
00054 {
00055
00056 RepoImpl::RepoImpl( const RepoOptions &opts )
00057 : RepositoryImpl(opts.repoinfo)
00058 , _type_cache(opts.dbdir)
00059 , _rquery(opts.dbdir)
00060 , _options(opts)
00061 {
00062 }
00063
00064 RepoImpl::~RepoImpl()
00065 {
00066 MIL << "Destroying repo '" << info().alias() << "'" << endl;
00067 }
00068
00069 void RepoImpl::createResolvables()
00070 {
00071 ProgressData ticks;
00072 ticks.sendTo(_options.readingResolvablesProgress);
00073 ticks.name(str::form(_( "Reading '%s' repository cache"), info().alias().c_str()));
00074 CombinedProgressData subprogrcv(ticks);
00075
00076 debug::Measure m("create resolvables");
00077 CapFactory capfactory;
00078 try
00079 {
00080 sqlite3_connection con((_options.dbdir + "zypp.db").asString().c_str());
00081 con.setprogresshandler(subprogrcv, 100);
00082
00083 con.executenonquery("PRAGMA cache_size=8000;");
00084 con.executenonquery("BEGIN;");
00085
00086
00087
00088
00089
00090
00091 sqlite3_command cmd( con, "select id,name,version,release,epoch,arch,kind from resolvables where repository_id=:repository_id;");
00092 cmd.bind(":repository_id", _options.repository_id);
00093 map<data::RecordId, pair<Resolvable::Kind, NVRAD> > nvras;
00094
00095 sqlite3_reader reader = cmd.executereader();
00096
00097 while(reader.read())
00098 {
00099 long long id = reader.getint64(0);
00100 Dependencies deps;
00101 Resolvable::Kind kind = _type_cache.kindFor(reader.getint(6));
00102
00103 nvras[id] = make_pair( kind, NVRAD( reader.getstring(1),
00104 Edition( reader.getstring(2), reader.getstring(3), reader.getint(4) ),
00105 _type_cache.archFor(reader.getint(5)),
00106 deps ) );
00107 }
00108
00109 MIL << "Done reading resolvables nvra" << endl;
00110
00111 ticks.tick();
00112
00113 read_capabilities( con, _options.repository_id, nvras, ticks );
00114
00115 ticks.tick();
00116
00117 for ( map<data::RecordId, pair<Resolvable::Kind, NVRAD> >::const_iterator it = nvras.begin(); it != nvras.end(); ++it )
00118 {
00119 if ( it->second.first == ResTraits<Package>::kind )
00120 {
00121 ResImplTraits<cached::PackageImpl>::Ptr impl = new cached::PackageImpl(it->first, this);
00122 Package::Ptr package = detail::makeResolvableFromImpl( it->second.second, impl );
00123 _store.insert( package );
00124 }
00125 else if ( it->second.first == ResTraits<SrcPackage>::kind )
00126 {
00127 ResImplTraits<cached::SrcPackageImpl>::Ptr impl = new cached::SrcPackageImpl(it->first, this);
00128 SrcPackage::Ptr srcpackage = detail::makeResolvableFromImpl( it->second.second, impl );
00129 _store.insert( srcpackage );
00130 }
00131 else if ( it->second.first == ResTraits<Product>::kind )
00132 {
00133 ResImplTraits<cached::ProductImpl>::Ptr impl = new cached::ProductImpl(it->first, this);
00134 Product::Ptr product = detail::makeResolvableFromImpl( it->second.second, impl );
00135 _store.insert( product );
00136 }
00137 else if ( it->second.first == ResTraits<Pattern>::kind )
00138 {
00139 ResImplTraits<cached::PatternImpl>::Ptr impl = new cached::PatternImpl(it->first, this);
00140 Pattern::Ptr pattern = detail::makeResolvableFromImpl( it->second.second, impl );
00141 _store.insert( pattern );
00142 }
00143 else if ( it->second.first == ResTraits<Patch>::kind )
00144 {
00145 ResImplTraits<cached::PatchImpl>::Ptr impl = new cached::PatchImpl(it->first, this);
00146 Patch::Ptr patch = detail::makeResolvableFromImpl( it->second.second, impl );
00147 _store.insert( patch );
00148 }
00149 else if ( it->second.first == ResTraits<Message>::kind )
00150 {
00151 ResImplTraits<cached::MessageImpl>::Ptr impl = new cached::MessageImpl(it->first, this);
00152 Message::Ptr message = detail::makeResolvableFromImpl( it->second.second, impl );
00153 _store.insert( message );
00154 }
00155 else if ( it->second.first == ResTraits<Script>::kind )
00156 {
00157 ResImplTraits<cached::ScriptImpl>::Ptr impl = new cached::ScriptImpl(it->first, this);
00158 Script::Ptr script = detail::makeResolvableFromImpl( it->second.second, impl );
00159 _store.insert( script );
00160 }
00161 else if ( it->second.first == ResTraits<Atom>::kind )
00162 {
00163 ResImplTraits<cached::AtomImpl>::Ptr impl = new cached::AtomImpl(it->first, this);
00164 Atom::Ptr atom = detail::makeResolvableFromImpl( it->second.second, impl );
00165 _store.insert( atom );
00166 }
00167 }
00168 con.executenonquery("COMMIT;");
00169 con.resetprogresshandler();
00170 }
00171 catch(exception &ex) {
00172 cerr << "Exception Occured: " << ex.what() << endl;
00173 }
00174
00175 }
00176
00177 void RepoImpl::createPatchAndDeltas()
00178 {
00179 ProgressData ticks;
00180 ticks.sendTo(_options.readingPatchDeltasProgress );
00181 ticks.name(str::form(_( "Reading patch and delta rpms from '%s' repository cache"), info().alias().c_str()));
00182 CombinedProgressData subprogrcv(ticks);
00183 try
00184 {
00185 sqlite3_connection con((_options.dbdir + "zypp.db").asString().c_str());
00186 con.setprogresshandler(subprogrcv);
00187 con.executenonquery("PRAGMA cache_size=8000;");
00188 con.executenonquery("BEGIN;");
00189
00190
00191
00192 enum pp_query_val { pp_id, pp_name, pp_version, pp_release, pp_epoch, pp_arch, pp_media_nr, pp_location, pp_checksum, pp_checksum_type, pp_download_size, pp_build_time };
00193 string pp_query = "SELECT id, name, version, release, epoch, arch, media_nr, location, checksum, checksum_type, download_size, build_time "
00194
00195 "FROM patch_packages WHERE repository_id=:repository_id;";
00196
00197 enum pp_bv_query_val { pp_bv_version, pp_bv_release, pp_bv_epoch };
00198 string pp_bv_query = "SELECT version, release, epoch "
00199
00200 "FROM patch_packages_baseversions WHERE patch_package_id = :patch_package_id";
00201
00202 enum dp_query_val { dp_id, dp_name, dp_version, dp_release, dp_epoch, dp_arch, dp_media_nr, dp_location, dp_checksum, dp_checksum_type, dp_download_size, dp_build_time, dp_baseversion_version, dp_baseversion_release, dp_baseversion_epoch, dp_baseversion_checksum, dp_baseversion_checksum_type, dp_baseversion_build_time, dp_baseversion_sequence_info };
00203 string dp_query = "SELECT id, name, version, release, epoch, arch, media_nr, location, checksum, checksum_type, download_size, build_time, baseversion_version, baseversion_release, baseversion_epoch, baseversion_checksum, baseversion_checksum_type, baseversion_build_time, baseversion_sequence_info "
00204
00205 "FROM delta_packages WHERE repository_id=:repository_id;";
00206
00207 {
00208
00209 sqlite3_command deltas_cmd( con, dp_query);
00210 deltas_cmd.bind(":repository_id", _options.repository_id);
00211 sqlite3_reader reader = deltas_cmd.executereader();
00212 while ( reader.read() )
00213 {
00214 zypp::OnMediaLocation on_media( reader.getstring(dp_location), reader.getint(dp_media_nr) );
00215
00216 CheckSum checksum(reader.getstring(dp_checksum_type), reader.getstring(dp_checksum));
00217 if ( checksum.empty() )
00218 {
00219 ERR << "Wrong checksum for delta, skipping..." << endl;
00220 continue;
00221 }
00222 on_media.setChecksum(checksum);
00223 on_media.setDownloadSize(reader.getint(dp_download_size));
00224
00225 packagedelta::DeltaRpm::BaseVersion baseversion;
00226 baseversion.setEdition( Edition(reader.getstring(dp_baseversion_version), reader.getstring(dp_baseversion_release), reader.getstring(dp_baseversion_epoch) ) );
00227
00228 checksum = CheckSum(reader.getstring(dp_baseversion_checksum_type), reader.getstring(dp_baseversion_checksum));
00229 if ( checksum.empty() )
00230 {
00231 ERR << "Wrong checksum for delta, skipping..." << endl;
00232 continue;
00233 }
00234 baseversion.setChecksum(checksum);
00235 baseversion.setBuildtime(reader.getint(dp_baseversion_build_time));
00236 baseversion.setSequenceinfo(reader.getstring(dp_baseversion_sequence_info));
00237
00238 zypp::packagedelta::DeltaRpm delta;
00239 delta.setName ( reader.getstring(dp_name) );
00240 delta.setEdition( Edition( reader.getstring(dp_version), reader.getstring(dp_release), reader.getint(dp_epoch) ) );
00241 delta.setArch ( _type_cache.archFor( reader.getint(dp_arch) ) );
00242 delta.setLocation( on_media );
00243 delta.setBaseversion( baseversion );
00244 delta.setBuildtime(reader.getint(dp_build_time));
00245
00246 _deltaRpms.push_back(delta);
00247 }
00248 reader.close();
00249 }
00250 {
00251
00252
00253
00254 sqlite3_command pp_cmd( con, pp_query);
00255 sqlite3_command pp_bv_cmd( con, pp_bv_query);
00256 pp_cmd.bind(":repository_id", _options.repository_id);
00257 sqlite3_reader reader = pp_cmd.executereader();
00258
00259 while ( reader.read() )
00260 {
00261
00262 long long patch_package_id = reader.getint64(pp_id);
00263
00264 zypp::OnMediaLocation on_media( reader.getstring(pp_location), reader.getint(pp_media_nr) );
00265
00266 CheckSum checksum(reader.getstring(pp_checksum_type), reader.getstring(pp_checksum));
00267 if ( checksum.empty() )
00268 {
00269 ERR << "Wrong checksum for delta, skipping..." << endl;
00270 continue;
00271 }
00272 on_media.setChecksum(checksum);
00273 on_media.setDownloadSize(reader.getint(pp_download_size));
00274
00275 zypp::packagedelta::PatchRpm patch;
00276 patch.setName ( reader.getstring(pp_name) );
00277 patch.setEdition( Edition( reader.getstring(pp_version), reader.getstring(pp_release), reader.getint(pp_epoch) ) );
00278 patch.setArch ( _type_cache.archFor( reader.getint(pp_arch) ) );
00279 patch.setLocation( on_media );
00280 patch.setBuildtime(reader.getint(pp_build_time));
00281
00282 pp_bv_cmd.bind( ":patch_package_id", patch_package_id );
00283
00284 sqlite3_reader bv_reader = pp_bv_cmd.executereader();
00285 while (bv_reader.read())
00286 {
00287
00288 packagedelta::PatchRpm::BaseVersion baseversion = packagedelta::PatchRpm::BaseVersion( bv_reader.getstring(pp_bv_version) ,
00289 bv_reader.getstring(pp_bv_release),
00290 bv_reader.getint(pp_bv_epoch) );
00291 patch.addBaseversion(baseversion);
00292 }
00293
00294 bv_reader.close();
00295
00296 _patchRpms.push_back(patch);
00297 }
00298 reader.close();
00299 MIL << _patchRpms.size() << " patch rpms read." << endl;
00300 }
00301
00302 con.close();
00303 }
00304 catch(exception &ex) {
00305 cerr << "Exception Occured: " << ex.what() << endl;
00306 }
00307 }
00308
00309 ResolvableQuery RepoImpl::resolvableQuery()
00310 {
00311 return _rquery;
00312 }
00313
00314 void RepoImpl::read_capabilities( sqlite3_connection &con,
00315 data::RecordId repo_id,
00316 map<data::RecordId, pair<Resolvable::Kind, NVRAD> > &nvras,
00317 ProgressData &ticks )
00318 {
00319 CapFactory capfactory;
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 sqlite3_command select_named_cmd( con, "select v.refers_kind, n.name, v.version, v.release, v.epoch, v.relation, v.dependency_type, v.resolvable_id from named_capabilities v, names n, resolvables res where v.name_id=n.id and v.resolvable_id=res.id and res.repository_id=:repo_id;");
00337
00338 sqlite3_command select_file_cmd( con, "select fc.refers_kind, dn.name, fn.name, fc.dependency_type, fc.resolvable_id from file_capabilities fc, files f, dir_names dn, file_names fn, resolvables res where f.id=fc.file_id and f.dir_name_id=dn.id and f.file_name_id=fn.id and fc.resolvable_id=res.id and res.repository_id=:repo_id;");
00339
00340 sqlite3_command select_hal_cmd( con, "select hc.refers_kind, hc.name, hc.value, hc.relation, hc.dependency_type, hc.resolvable_id from hal_capabilities hc, resolvables res where hc.resolvable_id=res.id and res.repository_id=:repo_id;");
00341
00342 sqlite3_command select_modalias_cmd( con, "select mc.refers_kind, mc.name, mc.pkgname, mc.value, mc.relation, mc.dependency_type, mc.resolvable_id from modalias_capabilities mc, resolvables res where mc.resolvable_id=res.id and res.repository_id=:repo_id;");
00343
00344 sqlite3_command select_filesystem_cmd( con, "select v.refers_kind, n.name, v.dependency_type, v.resolvable_id from filesystem_capabilities v, names n, resolvables res where v.name_id=n.id and v.resolvable_id=res.id and res.repository_id=:repo_id;");
00345
00346 sqlite3_command select_split_cmd( con, "select v.refers_kind, n.name, dn.name, fn.name, v.dependency_type, v.resolvable_id from split_capabilities v, names n, resolvables res, files f, dir_names dn, file_names fn where v.name_id=n.id and v.resolvable_id=res.id and f.id=v.file_id and f.dir_name_id=dn.id and f.file_name_id=fn.id and res.repository_id=:repo_id;");
00347
00348 sqlite3_command select_other_cmd( con, "select oc.refers_kind, oc.value, oc.dependency_type, oc.resolvable_id from other_capabilities oc, resolvables res where oc.resolvable_id=res.id and res.repository_id=:repo_id;");
00349
00350
00351 {
00352 debug::Measure mnc("read named capabilities");
00353 select_named_cmd.bind(":repo_id", repo_id);
00354 sqlite3_reader reader = select_named_cmd.executereader();
00355
00356
00357 Date start(Date::now());
00358 while ( reader.read() )
00359 {
00360 ticks.tick();
00361
00362 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00363 Rel rel = _type_cache.relationFor(reader.getint(5));
00364
00365 data::RecordId rid = reader.getint64(7);
00366
00367 if ( rel == zypp::Rel::NONE )
00368 {
00369 capability::NamedCap *ncap = new capability::NamedCap( refer, reader.getstring(1) );
00370 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(6));
00371 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(ncap) ) );
00372 }
00373 else
00374 {
00375 capability::VersionedCap *vcap = new capability::VersionedCap( refer, reader.getstring(1), rel, Edition( reader.getstring(2), reader.getstring(3), reader.getint(4) ) );
00376 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(6));
00377 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(vcap) ) );
00378 }
00379 }
00380 }
00381
00382 {
00383 debug::Measure mnf("read file capabilities");
00384 select_file_cmd.bind(":repo_id", repo_id);
00385 sqlite3_reader reader = select_file_cmd.executereader();
00386 while ( reader.read() )
00387 {
00388 ticks.tick();
00389 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00390 capability::FileCap *fcap = new capability::FileCap( refer, reader.getstring(1) + "/" + reader.getstring(2) );
00391 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(3));
00392 data::RecordId rid = reader.getint64(4);
00393 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(fcap) ) );
00394 }
00395 }
00396
00397 {
00398 debug::Measure mnf("read hal capabilities");
00399 select_hal_cmd.bind(":repo_id", repo_id);
00400 sqlite3_reader reader = select_hal_cmd.executereader();
00401 while ( reader.read() )
00402 {
00403 ticks.tick();
00404
00405
00406 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00407
00408 Rel rel = _type_cache.relationFor(reader.getint(3));
00409 capability::HalCap *hcap = new capability::HalCap( refer, reader.getstring(1), rel, reader.getstring(2) );
00410 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(4));
00411 data::RecordId rid = reader.getint64(5);
00412 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(hcap) ) );
00413 }
00414 }
00415
00416 {
00417 debug::Measure mnf("read modalias capabilities");
00418 select_modalias_cmd.bind(":repo_id", repo_id);
00419 sqlite3_reader reader = select_modalias_cmd.executereader();
00420 while ( reader.read() )
00421 {
00422 ticks.tick();
00423 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00424
00425 Rel rel = _type_cache.relationFor(reader.getint(4));
00426 capability::ModaliasCap *mcap = new capability::ModaliasCap( refer, reader.getstring(1), rel, reader.getstring(3) );
00427 mcap->setPkgname(reader.getstring(2));
00428 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(5));
00429 data::RecordId rid = reader.getint64(6);
00430 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(mcap) ) );
00431 }
00432 }
00433
00434 {
00435 debug::Measure mnf("read filesystem capabilities");
00436 select_filesystem_cmd.bind(":repo_id", repo_id);
00437 sqlite3_reader reader = select_filesystem_cmd.executereader();
00438 while ( reader.read() )
00439 {
00440 ticks.tick();
00441 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00442
00443 capability::FilesystemCap *fscap = new capability::FilesystemCap( refer, reader.getstring(1) );
00444 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(2));
00445 data::RecordId rid = reader.getint64(3);
00446 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(fscap) ) );
00447 }
00448 }
00449
00450 {
00451 debug::Measure mnf("read split capabilities");
00452 select_split_cmd.bind(":repo_id", repo_id);
00453 sqlite3_reader reader = select_split_cmd.executereader();
00454 while ( reader.read() )
00455 {
00456 ticks.tick();
00457 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00458
00459 capability::SplitCap *scap = new capability::SplitCap( refer, reader.getstring(1),
00460 reader.getstring(2) + "/" + reader.getstring(3) );
00461 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(4));
00462 data::RecordId rid = reader.getint64(5);
00463 nvras[rid].second[deptype].insert( capfactory.fromImpl( capability::CapabilityImpl::Ptr(scap) ) );
00464 }
00465 }
00466
00467 {
00468 debug::Measure mnf("read other capabilities");
00469 select_other_cmd.bind(":repo_id", repo_id);
00470 sqlite3_reader reader = select_other_cmd.executereader();
00471 while ( reader.read() )
00472 {
00473 ticks.tick();
00474
00475
00476 Resolvable::Kind refer = _type_cache.kindFor(reader.getint(0));
00477 capability::CapabilityImpl::Ptr cap = capability::parse( refer, reader.getstring(1));
00478
00479 if ( !cap )
00480 {
00481 ERR << "Invalid capability " << reader.getstring(1) << endl;
00482 }
00483
00484 zypp::Dep deptype = _type_cache.deptypeFor(reader.getint(2));
00485 data::RecordId rid = reader.getint64(3);
00486 nvras[rid].second[deptype].insert( capfactory.fromImpl(cap) );
00487 }
00488 }
00489
00490 MIL << nvras.size() << " capabilities" << endl;
00491 }
00492
00493
00495 }
00498 }
00501 }
00503