CacheStore.cc

Go to the documentation of this file.
00001 #include <sqlite3.h>
00002 #include <map>
00003 #include "zypp/cache/sqlite3x/sqlite3x.hpp"
00004 
00005 #include "zypp/base/Easy.h"
00006 #include "zypp/base/LogTools.h"
00007 #include "zypp/base/Measure.h"
00008 #include "zypp/ZYppFactory.h"
00009 #include "zypp/ZYpp.h"
00010 #include "zypp/Package.h"
00011 #include "zypp/cache/CacheInitializer.h"
00012 #include "zypp/cache/CacheStore.h"
00013 #include "zypp/cache/CacheException.h"
00014 #include "zypp/cache/CacheAttributes.h"
00015 
00016 using namespace std;
00017 using namespace zypp;
00018 using namespace zypp::capability;
00019 using namespace zypp::cache;
00020 using zypp::data::RecordId;
00021 using namespace sqlite3x;
00022 
00023 using zypp::debug::Measure;
00024 
00032 #define appendOnMediaLocation(ID,OMLATTRPREFIX,OML)                                              \
00033 do {                                                                                             \
00034   appendNumericAttribute( ID, OMLATTRPREFIX##MediaNr(),          OML.medianr() );                \
00035   appendStringAttribute ( ID, OMLATTRPREFIX##Filename(),         OML.filename().asString() );    \
00036   appendNumericAttribute( ID, OMLATTRPREFIX##DownloadSize(),     OML.downloadSize() );           \
00037   appendStringAttribute ( ID, OMLATTRPREFIX##ChecksumType(),     OML.checksum().type() );        \
00038   appendStringAttribute ( ID, OMLATTRPREFIX##Checksum(),         OML.checksum().checksum() );    \
00039   appendNumericAttribute( ID, OMLATTRPREFIX##OpenSize(),         OML.openSize() );               \
00040   appendStringAttribute ( ID, OMLATTRPREFIX##OpenChecksumType(), OML.openChecksum().type() );    \
00041   appendStringAttribute ( ID, OMLATTRPREFIX##OpenChecksum(),     OML.openChecksum().checksum() );\
00042 } while(false)
00043 
00045 namespace zypp
00046 { 
00047 
00048 namespace cache
00049 { 
00050 
00051 typedef shared_ptr<sqlite3_command> sqlite3_command_ptr;
00052 
00053 struct CacheStore::Impl
00054 {
00055   Impl( const Pathname &dbdir )
00056   : name_cache_hits(0)
00057   , dir_cache_hits(0)
00058   {
00059     // let the initializer go out of scope after it executes
00060     {
00061       cache::CacheInitializer initializer(dbdir, "zypp.db");
00062       if ( initializer.justInitialized() )
00063       {
00064         MIL << "database " << (dbdir + "zypp.db") << " was just created" << endl;
00065       }
00066     }
00067 
00068     try
00069     {
00070       con.open( (dbdir + "zypp.db").asString().c_str());
00071     }
00072     catch(exception &ex)
00073     {
00074       //ZYPP_CAUGHT(ex);
00075       ZYPP_THROW(Exception(ex.what()));
00076     }
00077 
00078 
00079     // initialize all pre-compiled statements
00080 
00081     insert_resolvable_in_repository_cmd.reset( new sqlite3_command( con, "insert into resolvables_repositories (resolvable_id, repository_id) values (:resolvable_id, :repository_id);" ));
00082 
00083     select_repository_cmd.reset( new sqlite3_command( con, "select id from repositories where alias=:alias;" ));
00084     insert_repository_cmd.reset( new sqlite3_command( con, "insert into repositories (alias,timestamp) values (:alias, :timestamp);" ));
00085 
00086     select_name_cmd.reset( new sqlite3_command( con, "select id from names where name=:name;" ));
00087     insert_name_cmd.reset( new sqlite3_command( con, "insert into names (name) values (:name);" ));
00088 
00089     select_dirname_cmd.reset( new sqlite3_command( con, "select id from dir_names where name=:name;" ));
00090     insert_dirname_cmd.reset( new sqlite3_command( con, "insert into dir_names (name) values (:name);" ));
00091 
00092     select_filename_cmd.reset( new sqlite3_command( con, "select id from file_names where name=:name;" ));
00093     insert_filename_cmd.reset( new sqlite3_command( con, "insert into file_names (name) values (:name);" ));
00094 
00095     select_file_cmd.reset( new sqlite3_command( con, "select id from files where dir_name_id=:dir_name_id and file_name_id=:file_name_id;" ));
00096     insert_file_cmd.reset( new sqlite3_command( con, "insert into files (dir_name_id,file_name_id) values (:dir_name_id,:file_name_id);" ));
00097 
00098     select_type_cmd.reset( new sqlite3_command( con, "select id from types where class=:class and name=:name;" ));
00099     insert_type_cmd.reset( new sqlite3_command( con, "insert into types (class,name) values (:class,:name);" ));
00100 
00101     set_shared_flag_cmd.reset( new sqlite3_command( con, "update resolvables set shared_id=:shared_id where id=:resolvable_id;" ));
00102 
00103     append_text_attribute_cmd.reset( new sqlite3_command( con, "insert into text_attributes ( weak_resolvable_id, lang_id, attr_id, text ) values ( :rid, :lang_id, :attr_id, :text );" ));
00104     append_num_attribute_cmd.reset( new sqlite3_command( con, "insert into numeric_attributes ( weak_resolvable_id, attr_id, value ) values ( :rid, :attr_id, :value );" ));
00105 
00106     //insert_dependency_entry_cmd.reset( new sqlite3_command( con, "insert into capabilities ( resolvable_id, dependency_type, refers_kind ) values ( :resolvable_id, :dependency_type, :refers_kind );" ));
00107     append_file_dependency_cmd.reset( new sqlite3_command( con, "insert into file_capabilities ( resolvable_id, dependency_type, refers_kind, file_id ) values ( :resolvable_id, :dependency_type, :refers_kind, :file_id );" ));
00108     append_named_dependency_cmd.reset( new sqlite3_command( con, "insert into named_capabilities ( resolvable_id, dependency_type, refers_kind, name_id, version, release, epoch, relation ) values ( :resolvable_id, :dependency_type, :refers_kind, :name_id, :version, :release, :epoch, :relation );" ));
00109 
00110     append_modalias_dependency_cmd.reset( new sqlite3_command( con, "insert into modalias_capabilities ( resolvable_id, dependency_type, refers_kind, name, pkgname, value, relation ) values ( :resolvable_id, :dependency_type, :refers_kind, :name, :pkgname, :value, :relation );" ));
00111 
00112     append_hal_dependency_cmd.reset( new sqlite3_command( con, "insert into hal_capabilities ( resolvable_id, dependency_type, refers_kind, name, value, relation ) values ( :resolvable_id, :dependency_type, :refers_kind, :name, :value, :relation );" ));
00113 
00114     append_filesystem_dependency_cmd.reset( new sqlite3_command( con, "insert into filesystem_capabilities ( resolvable_id, dependency_type, refers_kind, name_id ) values ( :resolvable_id, :dependency_type, :refers_kind, :name_id );" ));
00115 
00116     append_split_dependency_cmd.reset( new sqlite3_command( con, "insert into split_capabilities ( resolvable_id, dependency_type, refers_kind, name_id, file_id ) values ( :resolvable_id, :dependency_type, :refers_kind, :name_id, :file_id );" ));
00117 
00118     append_other_dependency_cmd.reset( new sqlite3_command( con, "insert into other_capabilities ( resolvable_id, dependency_type, refers_kind, value ) values ( :resolvable_id, :dependency_type, :refers_kind, :value );" ));
00119 
00120     append_resolvable_cmd.reset( new sqlite3_command( con, "insert into resolvables ( name, version, release, epoch, arch, kind, shared_id, repository_id ) values ( :name, :version, :release, :epoch, :arch, :kind, :shared_id, :repository_id );" ));
00121 
00122     count_shared_cmd.reset( new sqlite3_command( con, "select count(id) from resolvables where shared_id=:rid;" ));
00123 
00124     insert_patchrpm_cmd.reset( new sqlite3_command (con,
00125       "insert into patch_packages (repository_id, name, version, release, epoch, arch, media_nr, location, checksum, checksum_type, download_size, build_time) "
00126       "values (:repository_id, :name, :version, :release, :epoch, :arch, :media_nr, :location, :checksum, :checksum_type, :download_size, :build_time);" ));
00127     insert_deltarpm_cmd.reset( new sqlite3_command (con,
00128       "insert into delta_packages (repository_id, name, version, release, epoch, arch, media_nr, location, checksum, checksum_type, download_size, build_time, "
00129         "baseversion_version, baseversion_release, baseversion_epoch, baseversion_checksum, "
00130         "baseversion_build_time, baseversion_sequence_info) "
00131       "values (:repository_id, :name, :version, :release, :epoch, :arch, :media_nr, :location, :checksum, :checksum_type, :download_size, :build_time, "
00132         ":baseversion_version, :baseversion_release, :baseversion_epoch, :baseversion_checksum, "
00133         ":baseversion_build_time, :baseversion_sequence_info);" ));
00134     append_patch_baseversion_cmd.reset( new sqlite3_command (con,
00135       "insert into patch_packages_baseversions (patch_package_id, version, release, epoch) "
00136       "values (:patch_package_id, :version, :release, :epoch)" ));
00137 
00138     update_disk_usage_cmd.reset( new sqlite3_command (con,
00139       "insert or replace into resolvable_disk_usage (resolvable_id, dir_name_id, files, size) "
00140       "values (:resolvable_id, :dir_name_id, :files, :size)" ));
00141 
00142 
00143     // disable autocommit
00144     con.executenonquery("PRAGMA synchronous = 0;");
00145     con.executenonquery("BEGIN;");
00146   }
00147 
00148   Impl()
00149   {
00150     Impl( getZYpp()->homePath() );
00151   }
00152 
00153   ~Impl()
00154   {
00155     MIL << "name cache hits: " << name_cache_hits << " | cache size: " << name_cache.size() << endl;
00156   }
00157 
00162   sqlite3_connection con;
00163 
00164   sqlite3_command_ptr insert_resolvable_in_repository_cmd;
00165 
00166   sqlite3_command_ptr select_name_cmd;
00167   sqlite3_command_ptr insert_name_cmd;
00168 
00169   sqlite3_command_ptr select_dirname_cmd;
00170   sqlite3_command_ptr insert_dirname_cmd;
00171 
00172   sqlite3_command_ptr select_filename_cmd;
00173   sqlite3_command_ptr insert_filename_cmd;
00174 
00175   sqlite3_command_ptr select_repository_cmd;
00176   sqlite3_command_ptr insert_repository_cmd;
00177 
00178   sqlite3_command_ptr select_file_cmd;
00179   sqlite3_command_ptr insert_file_cmd;
00180 
00181   sqlite3_command_ptr select_type_cmd;
00182   sqlite3_command_ptr insert_type_cmd;
00183 
00184   //sqlite3_command_ptr insert_dependency_entry_cmd;
00185 
00186   sqlite3_command_ptr append_file_dependency_cmd;
00187   sqlite3_command_ptr append_named_dependency_cmd;
00188   sqlite3_command_ptr append_modalias_dependency_cmd;
00189   sqlite3_command_ptr append_hal_dependency_cmd;
00190   sqlite3_command_ptr append_filesystem_dependency_cmd;
00191   sqlite3_command_ptr append_split_dependency_cmd;
00192   sqlite3_command_ptr append_other_dependency_cmd;
00193 
00194   sqlite3_command_ptr append_resolvable_cmd;
00195 
00196   sqlite3_command_ptr append_text_attribute_cmd;
00197   sqlite3_command_ptr append_num_attribute_cmd;
00198 
00199   sqlite3_command_ptr set_shared_flag_cmd;
00200 
00201   sqlite3_command_ptr count_shared_cmd;
00202 
00203   sqlite3_command_ptr insert_patchrpm_cmd;
00204   sqlite3_command_ptr insert_deltarpm_cmd;
00205   sqlite3_command_ptr append_patch_baseversion_cmd;
00206 
00207   sqlite3_command_ptr update_disk_usage_cmd;
00208 
00209   map<string, RecordId> name_cache;
00210   map< pair<string,string>, RecordId> type_cache;
00211   map<string, RecordId> dir_cache;
00212   int name_cache_hits;
00213   int dir_cache_hits;
00214 };
00215 
00216 
00217 CacheStore::CacheStore( const Pathname &dbdir )
00218   : _pimpl( new Impl(dbdir) )
00219 {
00220 
00221 }
00222 
00223 CacheStore::CacheStore()
00224     : _pimpl( new Impl() )
00225 {
00226 
00227 }
00228 
00229 CacheStore::~CacheStore()
00230 {
00231 
00232 }
00233 
00234 void CacheStore::commit()
00235 {
00236   _pimpl->con.executenonquery("COMMIT;");
00237 }
00238 
00239 void CacheStore::appendResObjectAttributes( const data::RecordId &rid,
00240                                             const data::ResObject_Ptr & res )
00241 {
00242   appendTranslatedStringAttribute( rid, attrResObjectDescription(), res->description );
00243   appendTranslatedStringAttribute( rid, attrResObjectSummary(), res->summary );
00244   appendNumericAttribute( rid, attrResObjectInstalledSize(), res->installedSize );
00245   appendNumericAttribute( rid, attrResObjectBuildTime(), res->buildTime );
00246   appendBooleanAttribute( rid, attrResObjectInstallOnly(), res->installOnly );
00247   appendStringAttribute( rid, attrResObjectVendor(), res->vendor );
00248   appendTranslatedStringAttribute( rid, attrResObjectLicenseToConfirm(), res->licenseToConfirm );
00249   appendTranslatedStringAttribute( rid, attrResObjectInsnotify(), res->insnotify );
00250   appendTranslatedStringAttribute( rid, attrResObjectDelnotify(), res->delnotify );
00251 }
00252 
00253 
00254 void CacheStore::appendPackageBaseAttributes( const RecordId & pkgid,
00255                                               const data::Packagebase_Ptr & package )
00256 {
00257   appendStringAttribute( pkgid, attrPackageBuildhost(), package->buildhost );
00258   appendStringAttribute( pkgid, attrPackageDistribution(), package->distribution );
00259   appendStringAttribute( pkgid, attrPackageLicense(), package->license );
00260   appendStringAttribute( pkgid, attrPackageGroup(), package->group );
00261   appendStringAttribute( pkgid, attrPackagePackager(), package->packager );
00262   appendStringAttribute( pkgid, attrPackageUrl(), package->url );
00263   appendStringAttribute( pkgid, attrPackageOperatingSystem(), package->operatingSystem );
00264   appendStringAttribute( pkgid, attrPackagePrein(), package->prein );
00265   appendStringAttribute( pkgid, attrPackagePostin(), package->postin );
00266   appendStringAttribute( pkgid, attrPackagePreun(), package->preun );
00267   appendStringAttribute( pkgid, attrPackagePostun(), package->postun );
00268   appendStringContainerAttribute( pkgid, attrPackageKeywords(), package->keywords.begin(), package->keywords.end() );
00269   appendStringContainerAttribute( pkgid, attrPackageAuthors(), package->authors.begin(), package->authors.end() );
00270 
00271   appendOnMediaLocation( pkgid, attrPackageLocation, package->repositoryLocation );
00272 }
00273 
00274 RecordId CacheStore::consumePackage( const RecordId & repository_id,
00275                                      const data::Package_Ptr & package )
00276 {
00277   RecordId id = appendResolvable( repository_id, ResTraits<Package>::kind,
00278       NVRA( package->name, package->edition, package->arch ), package->deps, package->shareDataWith );
00279   appendResObjectAttributes( id, package );
00280   appendPackageBaseAttributes( id, package );
00281 
00282   if ( ! package->srcPackageIdent.name.empty() )
00283   {
00284     appendStringAttribute( id, attrPackageSourcePkgName(),    package->srcPackageIdent.name );
00285     appendStringAttribute( id, attrPackageSourcePkgEdition(), package->srcPackageIdent.edition.asString() );
00286   }
00287 
00288   return id;
00289 }
00290 
00291 RecordId CacheStore::consumeSourcePackage( const data::RecordId & repository_id,
00292                                        const data::SrcPackage_Ptr & package )
00293 {
00294   RecordId id = appendResolvable( repository_id, ResTraits<SrcPackage>::kind,
00295       NVRA( package->name, package->edition, package->arch ), package->deps, package->shareDataWith );
00296   appendResObjectAttributes( id, package );
00297 
00298   appendOnMediaLocation( id, attrSrcPackageLocation, package->repositoryLocation );
00299   return id;
00300 }
00301 
00302 RecordId CacheStore::consumePatch( const data::RecordId & repository_id,
00303                                const data::Patch_Ptr & patch)
00304 {
00305   RecordId id = appendResolvable(
00306       repository_id, ResTraits<Patch>::kind,
00307       NVRA( patch->name, patch->edition, patch->arch ), patch->deps );
00308 
00309   appendResObjectAttributes( id, patch );
00310 
00311   // patch attributes
00312   appendNumericAttribute( id, attrPatchTimestamp(),         patch->timestamp );
00313   appendStringAttribute(  id, attrPatchCategory(),          patch->category );
00314   appendStringAttribute(  id, attrPatchId(),                patch->id );
00315   appendBooleanAttribute( id, attrPatchRebootNeeded(),      patch->rebootNeeded );
00316   appendBooleanAttribute( id, attrPatchAffectsPkgManager(), patch->affectsPkgManager );
00317 
00318 
00319   DBG << "got patch " << patch->name << ", atoms: ";
00320   // cosume atoms
00321   for (set<data::ResObject_Ptr>::const_iterator p = patch->atoms.begin();
00322        p != patch->atoms.end(); ++p)
00323   {
00324     data::PackageAtom_Ptr atom = dynamic_pointer_cast<data::PackageAtom>(*p);
00325     if (atom)
00326     {
00327       DBG << atom->name << "(atom) ";
00328       consumePackageAtom(repository_id, atom);
00329       continue;
00330     }
00331 
00332     data::Script_Ptr script = dynamic_pointer_cast<data::Script>(*p);
00333     if (script)
00334     {
00335       DBG << script->name << "(script) ";
00336       consumeScript(repository_id, script);
00337       continue;
00338     }
00339 
00340     data::Message_Ptr message = dynamic_pointer_cast<data::Message>(*p);
00341     if (message)
00342     {
00343       DBG << message->name << "(message) ";
00344       consumeMessage(repository_id, message);
00345       continue;
00346     }
00347 
00348     ERR << " ignoring !badatom! ";
00349     if (*p) ERR << (*p)->name;
00350     ERR << endl;
00351   }
00352 
00353   DBG << endl;
00354   return id;
00355 }
00356 
00357 RecordId CacheStore::consumePackageAtom( const data::RecordId & repository_id,
00358                                      const data::PackageAtom_Ptr & atom )
00359 {
00360   RecordId id = appendResolvable( repository_id, ResTraits<Atom>::kind,
00361       NVRA( atom->name, atom->edition, atom->arch ), atom->deps );
00362   appendResObjectAttributes( id, atom );
00363   appendPackageBaseAttributes( id, atom );
00364 
00365   for (set<data::PatchRpm_Ptr>::const_iterator p = atom->patchRpms.begin();
00366        p != atom->patchRpms.end(); ++p)
00367     appendPatchRpm(repository_id, *p);
00368 
00369   for (set<data::DeltaRpm_Ptr>::const_iterator d = atom->deltaRpms.begin();
00370        d != atom->deltaRpms.end(); ++d)
00371     appendDeltaRpm(repository_id, *d);
00372   return id;
00373 }
00374 
00375 RecordId CacheStore::consumeMessage( const data::RecordId & repository_id,
00376                                  const data::Message_Ptr & message )
00377 {
00378   RecordId id = appendResolvable( repository_id, ResTraits<Message>::kind,
00379       NVRA( message->name, message->edition, message->arch ), message->deps );
00380   appendResObjectAttributes( id, message );
00381 
00382   appendTranslatedStringAttribute( id, attrMessageText(), message->text );
00383   return id;
00384 }
00385 
00386 RecordId CacheStore::consumeScript( const data::RecordId & repository_id,
00387                                 const data::Script_Ptr & script )
00388 {
00389   RecordId id = appendResolvable( repository_id, ResTraits<Script>::kind,
00390       NVRA( script->name, script->edition, script->arch ), script->deps );
00391   appendResObjectAttributes( id, script );
00392 
00393   appendStringAttribute( id, attrScriptDoScript(), script->doScript );
00394   appendOnMediaLocation( id, attrScriptDoScriptLocation, script->doScriptLocation );
00395   appendStringAttribute( id, attrScriptUndoScript(), script->undoScript );
00396   appendOnMediaLocation( id, attrScriptUndoScriptLocation, script->undoScriptLocation );
00397   return id;
00398 }
00399 
00400 RecordId CacheStore::consumePattern( const data::RecordId & repository_id,
00401                                      const data::Pattern_Ptr & pattern )
00402 {
00403   RecordId id = appendResolvable( repository_id, ResTraits<Pattern>::kind,
00404       NVRA( pattern->name, pattern->edition, pattern->arch ), pattern->deps );
00405   appendResObjectAttributes( id, pattern );
00406 
00407   appendBooleanAttribute( id, attrPatternIsDefault(), pattern->isDefault );
00408   appendBooleanAttribute( id, attrPatternUserVisible(), pattern->userVisible );
00409   appendTranslatedStringAttribute( id, attrPatternCategory(), pattern->category );
00410   appendStringAttribute( id, attrPatternIcon(), pattern->icon );
00411   appendStringAttribute( id, attrPatternOrder(), pattern->order );
00412 
00413   // We store them as string. They are
00414   // (sometimes) evaluated by the YaST UI.
00415   appendStringContainerAttribute( id, attrPatternUiIncludes(), pattern->includes.begin(), pattern->includes.end() );
00416   appendStringContainerAttribute( id, attrPatternUiExtends(),  pattern->extends.begin(),  pattern->extends.end() );
00417 
00418   return id;
00419 }
00420 
00421 RecordId CacheStore::consumeProduct( const data::RecordId & repository_id,
00422                                  const data::Product_Ptr & product )
00423 {
00424   RecordId id = appendResolvable( repository_id, ResTraits<Product>::kind,
00425       NVRA( product->name, product->edition, product->arch ), product->deps );
00426   appendResObjectAttributes( id, product );
00427 
00428   appendStringAttribute( id, attrProductType(), product->type );
00429   appendTranslatedStringAttribute( id, attrProductShortName(), product->shortName );
00430   appendTranslatedStringAttribute( id, attrProductLongName(), product->longName );
00431   appendStringContainerAttribute( id, attrProductFlags(), product->flags.begin(), product->flags.end() );
00432   appendStringAttribute( id, attrProductReleasenotesUrl(), product->releasenotesUrl.asString() );
00433   appendStringContainerAttribute( id, attrProductUpdateUrls(), product->updateUrls );
00434   appendStringContainerAttribute( id, attrProductExtraUrls(), product->extraUrls );
00435   appendStringContainerAttribute( id, attrProductOptionalUrls(), product->optionalUrls );
00436   appendStringAttribute( id, attrProductDistributionName(), product->distributionName );
00437   appendStringAttribute( id, attrProductDistributionEdition(), product->distributionEdition.asString() );
00438   return id;
00439 }
00440 
00441 RecordId CacheStore::consumeChangelog( const data::RecordId &resolvable_id,
00442                                    const Changelog & changelog )
00443 {
00447   return data::noRecordId;
00448 }
00449 
00450 RecordId CacheStore::consumeFilelist( const data::RecordId &resolvable_id,
00451                                   const data::Filenames & filenames )
00452 {
00454   return data::noRecordId;
00455 }
00456 
00457 void CacheStore::consumeDiskUsage( const data::RecordId &resolvable_id,
00458                                   const DiskUsage &disk )
00459 {
00460   // iterate over entries
00461   for ( DiskUsage::const_iterator it = disk.begin();
00462         it != disk.end();
00463         ++it )
00464   {
00465     data::RecordId dirid = lookupOrAppendDirName( (*it).path );
00466     try
00467     {
00468       _pimpl->update_disk_usage_cmd->bind(":resolvable_id", resolvable_id);
00469       _pimpl->update_disk_usage_cmd->bind(":dir_name_id", dirid);
00470       _pimpl->update_disk_usage_cmd->bind(":files", (int)(*it)._files );
00471       _pimpl->update_disk_usage_cmd->bind(":size", (int)(*it)._size );
00472       _pimpl->update_disk_usage_cmd->executenonquery();
00473     }
00474     catch ( const sqlite3x::database_error &e )
00475     {
00476       ZYPP_RETHROW(e);
00477     }
00478   }
00479   //MIL << "disk usage for " << resolvable_id << " consumed" << endl;
00480 }
00481 
00482 void CacheStore::updatePackageLang( const data::RecordId & resolvable_id,
00483                                     const data::Packagebase_Ptr & data_r )
00484 {
00485   appendTranslatedStringAttribute( resolvable_id, attrResObjectSummary(),          data_r->summary );
00486   appendTranslatedStringAttribute( resolvable_id, attrResObjectDescription(),      data_r->description );
00487   appendTranslatedStringAttribute( resolvable_id, attrResObjectLicenseToConfirm(), data_r->licenseToConfirm );
00488   appendTranslatedStringAttribute( resolvable_id, attrResObjectInsnotify(),        data_r->insnotify );
00489   appendTranslatedStringAttribute( resolvable_id, attrResObjectDelnotify(),        data_r->delnotify );
00490 }
00491 
00492 RecordId CacheStore::appendResolvable( const RecordId &repository_id,
00493                                        const Resolvable::Kind &kind,
00494                                        const NVRA &nvra,
00495                                        const data::Dependencies &deps )
00496 {
00497   return appendResolvable( repository_id,
00498                            kind,
00499                            nvra,
00500                            deps,
00501                            data::noRecordId );
00502 }
00503 
00504 data::RecordId
00505     CacheStore::appendResolvable( const data::RecordId &repository_id,
00506                                   const Resolvable::Kind &kind,
00507                                   const NVRA &nvra,
00508                                   const data::Dependencies &deps,
00509                                   const data::RecordId &shared_id )
00510 {
00511   _pimpl->append_resolvable_cmd->bind( ":name", nvra.name );
00512   _pimpl->append_resolvable_cmd->bind( ":version", nvra.edition.version() );
00513   _pimpl->append_resolvable_cmd->bind( ":release", nvra.edition.release() );
00514   _pimpl->append_resolvable_cmd->bind( ":epoch", static_cast<int>( nvra.edition.epoch() ) );
00515   _pimpl->append_resolvable_cmd->bind( ":arch", lookupOrAppendType("arch", nvra.arch.asString()) );
00516   _pimpl->append_resolvable_cmd->bind( ":kind", lookupOrAppendType("kind", kind.asString()) );
00517   _pimpl->append_resolvable_cmd->bind( ":repository_id", repository_id );
00518 
00519   if ( shared_id == data::noRecordId )
00520     _pimpl->append_resolvable_cmd->bind(":shared_id");
00521   else
00522     _pimpl->append_resolvable_cmd->bind( ":shared_id", shared_id );
00523 
00524   _pimpl->append_resolvable_cmd->executenonquery();
00525 
00526   long long id = _pimpl->con.insertid();
00527 
00528   appendDependencies( id, deps );
00529   /*
00530   _pimpl->insert_resolvable_in_repository_cmd->bind(":repository_id", repository_id);
00531   _pimpl->insert_resolvable_in_repository_cmd->bind(":resolvable_id", id);
00532   _pimpl->insert_resolvable_in_repository_cmd->executenonquery();*/
00533 
00534   return id;
00535 }
00536 
00537 void CacheStore::appendDependencies( const RecordId &resolvable_id, const data::Dependencies &deps )
00538 {
00539   for ( data::Dependencies::const_iterator it = deps.begin(); it != deps.end(); ++it )
00540   {
00541     appendDependencyList( resolvable_id, it->first, it->second );
00542   }
00543 }
00544 
00545 void CacheStore::appendDependencyList( const RecordId &resolvable_id, zypp::Dep deptype, const data::DependencyList &caps )
00546 {
00547   for ( data::DependencyList::const_iterator it = caps.begin(); it != caps.end(); ++it )
00548   {
00549     appendDependency( resolvable_id, deptype, *it );
00550   }
00551 }
00552 
00553 void CacheStore::appendDependency( const RecordId &resolvable_id, zypp::Dep deptype, capability::CapabilityImpl::Ptr cap )
00554 {
00555   if ( cap == 0 )
00556   {
00557     DBG << "invalid capability" << endl;
00558     return;
00559   }
00560 
00561   if ( capability::isKind<NamedCap>(cap) )
00562   {
00563       appendNamedDependency( resolvable_id, deptype, capability::asKind<NamedCap>(cap) );
00564   }
00565   else if ( capability::isKind<FileCap>(cap) )
00566   {
00567     appendFileDependency( resolvable_id, deptype, capability::asKind<FileCap>(cap) );
00568     return;
00569   }
00570   else if ( capability::isKind<ModaliasCap>(cap) )
00571   {
00572       appendModaliasDependency( resolvable_id, deptype, capability::asKind<ModaliasCap>(cap) );
00573   }
00574   else if ( capability::isKind<HalCap>(cap) )
00575   {
00576       appendHalDependency( resolvable_id, deptype, capability::asKind<HalCap>(cap) );
00577   }
00578   else if ( capability::isKind<FilesystemCap>(cap) )
00579   {
00580       appendFilesystemDependency( resolvable_id, deptype, capability::asKind<FilesystemCap>(cap) );
00581   }
00582   else if ( capability::isKind<SplitCap>(cap) )
00583   {
00584       appendSplitDependency( resolvable_id, deptype, capability::asKind<SplitCap>(cap) );
00585   }
00586   else
00587   {
00588       appendUnknownDependency( resolvable_id, deptype, cap );
00589   }
00590 }
00591 
00592 
00593 void CacheStore::appendNamedDependency( const RecordId &resolvable_id, zypp::Dep deptype, capability::NamedCap::Ptr cap )
00594 {
00595   if ( !cap )
00596     ZYPP_THROW(Exception("bad versioned dep"));
00597   //DBG << "versioned : " << cap << endl;
00598 
00599   //RecordId capability_id = appendDependencyEntry( resolvable_id, deptype, cap->refers() );
00600   RecordId name_id = lookupOrAppendName(cap->name());
00601 
00602   _pimpl->append_named_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00603   _pimpl->append_named_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00604   _pimpl->append_named_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00605 
00606   //_pimpl->append_named_dependency_cmd->bind( ":capability_id", capability_id);
00607   _pimpl->append_named_dependency_cmd->bind( ":name_id", name_id);
00608   _pimpl->append_named_dependency_cmd->bind( ":version", cap->edition().version() );
00609   _pimpl->append_named_dependency_cmd->bind( ":release", cap->edition().release() );
00610   _pimpl->append_named_dependency_cmd->bind( ":epoch", static_cast<int>( cap->edition().epoch() ) );
00611   _pimpl->append_named_dependency_cmd->bind( ":relation", lookupOrAppendType("rel", cap->op().asString()) );
00612   _pimpl->append_named_dependency_cmd->executenonquery();
00613 
00614   //delete cmd;
00615 }
00616 
00617 void CacheStore::appendModaliasDependency( const RecordId &resolvable_id,
00618                                                  zypp::Dep deptype,
00619                                                  capability::ModaliasCap::Ptr cap )
00620 {
00621   if ( !cap )
00622     ZYPP_THROW(Exception("Null modalias capability"));
00623 
00624   _pimpl->append_modalias_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00625   _pimpl->append_modalias_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00626   _pimpl->append_modalias_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00627 
00628   //_pimpl->append_modalias_dependency_cmd->bind( ":capability_id", capability_id);
00629   _pimpl->append_modalias_dependency_cmd->bind( ":name", cap->name());
00630   _pimpl->append_modalias_dependency_cmd->bind( ":pkgname", cap->pkgname());
00631   _pimpl->append_modalias_dependency_cmd->bind( ":value", cap->value());
00632   _pimpl->append_modalias_dependency_cmd->bind( ":relation", lookupOrAppendType("rel", cap->op().asString()) );
00633 
00634   _pimpl->append_modalias_dependency_cmd->executenonquery();
00635   //delete cmd;
00636 }
00637 
00638 void CacheStore::appendHalDependency( const RecordId &resolvable_id,
00639                                                  zypp::Dep deptype,
00640                                                  capability::HalCap::Ptr cap )
00641 {
00642   if ( !cap )
00643     ZYPP_THROW(Exception("Null HAL capability"));
00644 
00645   MIL << "HAL cap [ rid: " << resolvable_id << " | deptype: " << deptype << " | cap: "
00646     << cap << endl;
00647 
00648   _pimpl->append_hal_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00649   _pimpl->append_hal_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00650   _pimpl->append_hal_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00651 
00652   //_pimpl->append_hal_dependency_cmd->bind( ":capability_id", capability_id);
00653   _pimpl->append_hal_dependency_cmd->bind( ":name", cap->name());
00654   _pimpl->append_hal_dependency_cmd->bind( ":value", cap->value());
00655   _pimpl->append_hal_dependency_cmd->bind( ":relation", lookupOrAppendType("rel", cap->op().asString()) );
00656 
00657   _pimpl->append_hal_dependency_cmd->executenonquery();
00658   //delete cmd;
00659 }
00660 
00661 void CacheStore::appendFileDependency( const RecordId &resolvable_id, zypp::Dep deptype,
00662                                        capability::FileCap::Ptr cap )
00663 {
00664   if ( !cap )
00665     ZYPP_THROW(Exception("Null file capability"));
00666 
00667   //RecordId capability_id = appendDependencyEntry( resolvable_id, deptype, cap->refers() );
00668   RecordId file_id = lookupOrAppendFile(cap->filename());
00669 
00670   _pimpl->append_file_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00671   _pimpl->append_file_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00672   _pimpl->append_file_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00673 
00674   //_pimpl->append_file_dependency_cmd->bind( ":capability_id", capability_id);
00675   _pimpl->append_file_dependency_cmd->bind( ":file_id", file_id);
00676 
00677   _pimpl->append_file_dependency_cmd->executenonquery();
00678   //delete cmd;
00679 }
00680 
00681 void CacheStore::appendFilesystemDependency( const data::RecordId &resolvable_id,
00682                                              zypp::Dep deptype,
00683                                              capability::FilesystemCap::Ptr cap )
00684 {
00685   if ( !cap )
00686     ZYPP_THROW(Exception("bad versioned dep"));
00687   //DBG << "versioned : " << cap << endl;
00688 
00689   //RecordId capability_id = appendDependencyEntry( resolvable_id, deptype, cap->refers() );
00690   RecordId name_id = lookupOrAppendName(cap->name());
00691 
00692   _pimpl->append_filesystem_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00693   _pimpl->append_filesystem_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00694   _pimpl->append_filesystem_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00695 
00696   //_pimpl->append_filesystem_dependency_cmd->bind( ":capability_id", capability_id);
00697   _pimpl->append_filesystem_dependency_cmd->bind( ":name_id", name_id);
00698   _pimpl->append_filesystem_dependency_cmd->executenonquery();
00699 }
00700 
00701 
00702 void CacheStore::appendSplitDependency( const data::RecordId &resolvable_id,
00703                                         zypp::Dep deptype,
00704                                         capability::SplitCap::Ptr cap )
00705 {
00706   if ( !cap )
00707     ZYPP_THROW(Exception("bad versioned dep"));
00708   //DBG << "versioned : " << cap << endl;
00709 
00710   //RecordId capability_id = appendDependencyEntry( resolvable_id, deptype, cap->refers() );
00711   RecordId name_id = lookupOrAppendName(cap->name());
00712   RecordId file_id = lookupOrAppendFile(cap->path());
00713 
00714   _pimpl->append_split_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00715   _pimpl->append_split_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00716   _pimpl->append_split_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00717 
00718   //_pimpl->append_split_dependency_cmd->bind( ":capability_id", capability_id);
00719   _pimpl->append_split_dependency_cmd->bind( ":name_id", name_id);
00720   _pimpl->append_split_dependency_cmd->bind( ":file_id", file_id);
00721   _pimpl->append_split_dependency_cmd->executenonquery();
00722 }
00723 
00724 void CacheStore::appendUnknownDependency( const RecordId &resolvable_id,
00725                                                zypp::Dep deptype,
00726                                                capability::CapabilityImpl::Ptr cap )
00727 {
00728   if ( !cap )
00729     ZYPP_THROW(Exception("Null unknown capability"));
00730 
00731   _pimpl->append_other_dependency_cmd->bind( ":resolvable_id", resolvable_id );
00732   _pimpl->append_other_dependency_cmd->bind( ":dependency_type", lookupOrAppendType("deptype", deptype.asString()) );
00733   _pimpl->append_other_dependency_cmd->bind( ":refers_kind", lookupOrAppendType("kind", cap->refers().asString()) );
00734   _pimpl->append_other_dependency_cmd->bind( ":value", cap->encode());
00735 
00736   _pimpl->append_other_dependency_cmd->executenonquery();
00737   //delete cmd;
00738 }
00739 
00740 
00742 RecordId CacheStore::appendPatchRpm(const zypp::data::RecordId &repository_id, const data::PatchRpm_Ptr & prpm)
00743 {
00744   RecordId id;
00745 
00746   _pimpl->insert_patchrpm_cmd->bind(":repository_id", repository_id);
00747 
00748   _pimpl->insert_patchrpm_cmd->bind(":name",    prpm->name);
00749   _pimpl->insert_patchrpm_cmd->bind(":version", prpm->edition.version());
00750   _pimpl->insert_patchrpm_cmd->bind(":release", prpm->edition.release());
00751   _pimpl->insert_patchrpm_cmd->bind(":epoch",   (int) prpm->edition.epoch());
00752   _pimpl->insert_patchrpm_cmd->bind(":arch",    lookupOrAppendType("arch", prpm->arch.asString()));
00753 
00754   _pimpl->insert_patchrpm_cmd->bind(":media_nr", (int) prpm->location.medianr());
00755   _pimpl->insert_patchrpm_cmd->bind(":location", prpm->location.filename().asString());
00756   _pimpl->insert_patchrpm_cmd->bind(":checksum", prpm->location.checksum().checksum());
00757   _pimpl->insert_patchrpm_cmd->bind(":checksum_type", prpm->location.checksum().type());
00758   _pimpl->insert_patchrpm_cmd->bind(":download_size", static_cast<ByteCount::SizeType>(prpm->location.downloadSize()));
00759   _pimpl->insert_patchrpm_cmd->bind(":build_time", prpm->buildTime.asSeconds());
00760   _pimpl->insert_patchrpm_cmd->executenonquery();
00761 
00762   id = _pimpl->con.insertid();
00763 
00764   for (set<data::BaseVersion_Ptr>::const_iterator bv = prpm->baseVersions.begin();
00765        bv != prpm->baseVersions.end(); ++bv)
00766   {
00767     _pimpl->append_patch_baseversion_cmd->bind(":patch_package_id", id);
00768     _pimpl->append_patch_baseversion_cmd->bind(":version", (*bv)->edition.version());
00769     _pimpl->append_patch_baseversion_cmd->bind(":release", (*bv)->edition.release());
00770     _pimpl->append_patch_baseversion_cmd->bind(":epoch", (int) (*bv)->edition.epoch());
00771     _pimpl->append_patch_baseversion_cmd->executenonquery();
00772   }
00773 
00774   return id;
00775 }
00776 
00777 
00779 RecordId CacheStore::appendDeltaRpm(const zypp::data::RecordId &repository_id, const data::DeltaRpm_Ptr & drpm)
00780 {
00781   RecordId id;
00782 
00783   _pimpl->insert_deltarpm_cmd->bind(":repository_id", repository_id);
00784 
00785   _pimpl->insert_deltarpm_cmd->bind(":name",    drpm->name);
00786   _pimpl->insert_deltarpm_cmd->bind(":version", drpm->edition.version());
00787   _pimpl->insert_deltarpm_cmd->bind(":release", drpm->edition.release());
00788   _pimpl->insert_deltarpm_cmd->bind(":epoch",   (int) drpm->edition.epoch());
00789   _pimpl->insert_deltarpm_cmd->bind(":arch",    lookupOrAppendType("arch", drpm->arch.asString()));
00790 
00791   _pimpl->insert_deltarpm_cmd->bind(":media_nr", (int) drpm->location.medianr());
00792   _pimpl->insert_deltarpm_cmd->bind(":location", drpm->location.filename().asString());
00793   _pimpl->insert_deltarpm_cmd->bind(":checksum", drpm->location.checksum().checksum());
00794   _pimpl->insert_deltarpm_cmd->bind(":checksum", drpm->location.checksum().checksum());
00795   _pimpl->insert_deltarpm_cmd->bind(":checksum_type", drpm->location.checksum().type());
00796   _pimpl->insert_deltarpm_cmd->bind(":download_size", static_cast<ByteCount::SizeType>(drpm->location.downloadSize()));
00797   _pimpl->insert_deltarpm_cmd->bind(":build_time", drpm->buildTime.asSeconds());
00798 
00799   _pimpl->insert_deltarpm_cmd->bind(":baseversion_version", drpm->baseVersion.edition.version());
00800   _pimpl->insert_deltarpm_cmd->bind(":baseversion_release", drpm->baseVersion.edition.release());
00801   _pimpl->insert_deltarpm_cmd->bind(":baseversion_epoch", (int) drpm->baseVersion.edition.epoch());
00802   _pimpl->insert_deltarpm_cmd->bind(":baseversion_build_time", drpm->baseVersion.buildTime.asSeconds());
00803   _pimpl->insert_deltarpm_cmd->bind(":baseversion_checksum", drpm->baseVersion.checkSum.checksum());
00804   _pimpl->insert_deltarpm_cmd->bind(":baseversion_sequence_info", drpm->baseVersion.sequenceInfo);
00805 
00806   _pimpl->insert_deltarpm_cmd->executenonquery();
00807   id = _pimpl->con.insertid();
00808 
00809   return id;
00810 }
00811 
00812 
00813 RecordId CacheStore::lookupOrAppendFile( const Pathname &path )
00814 {
00815   RecordId dir_name_id = lookupOrAppendDirName(path.dirname().asString());
00816   RecordId file_name_id = lookupOrAppendFileName(path.basename());
00817 
00818   _pimpl->select_file_cmd->bind(":dir_name_id", dir_name_id);
00819   _pimpl->select_file_cmd->bind(":file_name_id", file_name_id);
00820   long long id = 0;
00821 
00822   try
00823   {
00824     sqlite3_reader reader= _pimpl->select_file_cmd->executereader();
00825     if (!reader.read())
00826     {
00827       // does not exist
00828       _pimpl->insert_file_cmd->bind(":dir_name_id", dir_name_id);
00829       _pimpl->insert_file_cmd->bind(":file_name_id", file_name_id);
00830       _pimpl->insert_file_cmd->executenonquery();
00831       id = _pimpl->con.insertid();
00832       return id;
00833    }
00834    return reader.getint64(0);
00835   }
00836   catch ( const sqlite3x::database_error &e )
00837   {
00838     ZYPP_RETHROW(e);
00839   }
00840   return id;
00841 }
00842 
00843 void CacheStore::updateRepositoryStatus( const RecordId &id,
00844                                          const RepoStatus &status )
00845 {
00846   sqlite3_command cmd( _pimpl->con, "update repositories set checksum=:checksum, timestamp=:timestamp where id=:repository_id;");
00847   cmd.bind(":repository_id", id);
00848   cmd.bind(":checksum", status.checksum());
00849   cmd.bind(":timestamp", static_cast<int>((Date::ValueType) status.timestamp()) );
00850   try
00851   {
00852     cmd.executenonquery();
00853   }
00854   catch ( const sqlite3x::database_error &e )
00855   {
00856     ZYPP_RETHROW(e);
00857   }
00858 }
00859 
00860 RecordId CacheStore::lookupOrAppendRepository( const string &alias )
00861 {
00862   _pimpl->select_repository_cmd->bind(":alias", alias);
00863   long long id = 0;
00864   try
00865   {
00866     sqlite3_reader reader= _pimpl->select_repository_cmd->executereader();
00867     if (!reader.read())
00868     {
00869       // does not exist
00870       _pimpl->insert_repository_cmd->bind(":alias", alias);
00871       _pimpl->insert_repository_cmd->bind(":timestamp", static_cast<int>((Date::ValueType) Date::now()) );
00872       _pimpl->insert_repository_cmd->executenonquery();
00873       id = _pimpl->con.insertid();
00874       return id;
00875    }
00876    return reader.getint64(0);
00877   }
00878   catch ( const sqlite3x::database_error &e )
00879   {
00880     ZYPP_RETHROW(e);
00881   }
00882   return id;
00883 }
00884 
00885 void CacheStore::cleanRepository( const data::RecordId &id,
00886                                   const ProgressData::ReceiverFnc & progressrcv )
00887 {
00888   sqlite3_command cmd( _pimpl->con, "delete from repositories where id=:id");
00889   _pimpl->con.setprogresshandler(progressrcv);
00890   cmd.bind(":id", id);
00891 
00892   try
00893   {
00894     cmd.executenonquery();
00895   }
00896   catch ( const sqlite3x::database_error &e )
00897   {
00898     ZYPP_CAUGHT(e);
00899     CacheRecordNotFoundException enew;
00900     enew.remember(e);
00901     _pimpl->con.resetprogresshandler();
00902     ZYPP_THROW(enew);
00903   }
00904   _pimpl->con.resetprogresshandler();
00905 }
00906 
00907 void CacheStore::cleanRepository( const std::string &alias,
00908                                   const ProgressData::ReceiverFnc & progressrcv )
00909 {
00910   cleanRepository(lookupRepository(alias), progressrcv);
00911 }
00912 
00913 RepoStatus CacheStore::repositoryStatus( const data::RecordId &id )
00914 {
00915   sqlite3_command cmd( _pimpl->con, "select id,alias,checksum,timestamp from repositories where id=:id");
00916   cmd.bind(":id", id);
00917 
00918   try
00919   {
00920     sqlite3_reader reader = cmd.executereader();
00921     RepoStatus status;
00922     if ( reader.read() )
00923     {
00924       status.setChecksum( reader.getstring(2) );
00925       status.setTimestamp( reader.getstring(3) );
00926       return status;
00927     }
00928     else
00929       ZYPP_THROW(CacheRecordNotFoundException());
00930   }
00931   catch ( const sqlite3x::database_error &e )
00932   {
00933     ZYPP_RETHROW(e);
00934   }
00935 }
00936 
00937 RepoStatus CacheStore::repositoryStatus( const string &alias )
00938 {
00939   return repositoryStatus(lookupRepository(alias));
00940 }
00941 
00942 bool CacheStore::isCached( const string &alias )
00943 {
00944   sqlite3_command cmd(_pimpl->con, "select id from repositories where alias=:alias;");
00945   cmd.bind(":alias", alias);
00946   try
00947   {
00948     sqlite3_reader reader= cmd.executereader();
00949     if (!reader.read())
00950     {
00951       return false;
00952    }
00953    return true;
00954   }
00955   catch ( const sqlite3x::database_error &e )
00956   {
00957     ZYPP_RETHROW(e);
00958   }
00959   return false;
00960 }
00961 
00962 RecordId CacheStore::lookupRepository( const string &alias )
00963 {
00964   long long id = 0;
00965   sqlite3_command cmd(_pimpl->con, "select id from repositories where alias=:alias;");
00966   cmd.bind(":alias", alias);
00967   try
00968   {
00969     sqlite3_reader reader= cmd.executereader();
00970     if (!reader.read())
00971     {
00972       // does not exist
00973       ZYPP_THROW(CacheRecordNotFoundException());
00974    }
00975    return reader.getint64(0);
00976   }
00977   catch ( const sqlite3x::database_error &e )
00978   {
00979     ZYPP_RETHROW(e);
00980   }
00981   return id;
00982 }
00983 
00984 RecordId CacheStore::lookupOrAppendType( const string &klass, const string &name )
00985 {
00986   pair<string, string> thetype = make_pair(klass,name);
00987   if ( _pimpl->type_cache.find(thetype) != _pimpl->type_cache.end() )
00988   {
00989     //_pimpl->name_cache_hits++;
00990     return _pimpl->type_cache[thetype];
00991   }
00992 
00993   _pimpl->select_type_cmd->bind(":class", klass);
00994   _pimpl->select_type_cmd->bind(":name", name);
00995   long long id = 0;
00996   try
00997   {
00998     sqlite3_reader reader= _pimpl->select_type_cmd->executereader();
00999     if (!reader.read())
01000     {
01001       // does not exist
01002       _pimpl->insert_type_cmd->bind(":class", klass);
01003       _pimpl->insert_type_cmd->bind(":name", name);
01004       _pimpl->insert_type_cmd->executenonquery();
01005       id = _pimpl->con.insertid();
01006    }
01007    else
01008    {
01009       id = reader.getint64(0);
01010    }
01011    _pimpl->type_cache[thetype] = id;
01012    return id;
01013   }
01014   catch ( const sqlite3x::database_error &e )
01015   {
01016     ZYPP_RETHROW(e);
01017   }
01018   return id;
01019 }
01020 
01021 RecordId CacheStore::lookupOrAppendName( const string &name )
01022 {
01023   if ( _pimpl->name_cache.find(name) != _pimpl->name_cache.end() )
01024   {
01025     _pimpl->name_cache_hits++;
01026     return _pimpl->name_cache[name];
01027   }
01028   long long id = 0;
01029   try
01030   {
01031     _pimpl->select_name_cmd->bind(":name", name);
01032     sqlite3_reader reader= _pimpl->select_name_cmd->executereader();
01033     if (!reader.read())
01034     {
01035       // does not exist
01036       _pimpl->insert_name_cmd->bind(":name", name);
01037       _pimpl->insert_name_cmd->executenonquery();
01038       id = _pimpl->con.insertid();
01039     }
01040     else
01041     {
01042       id = reader.getint64(0);
01043     }
01044     _pimpl->name_cache[name] = id;
01045     return id;
01046   }
01047   catch ( const sqlite3x::database_error &e )
01048   {
01049     ZYPP_RETHROW(e);
01050   }
01051   return id;
01052 }
01053 
01054 RecordId CacheStore::lookupOrAppendDirName( const string &name )
01055 {
01056   if ( _pimpl->dir_cache.find(name) != _pimpl->dir_cache.end() )
01057   {
01058     _pimpl->dir_cache_hits++;
01059     return _pimpl->dir_cache[name];
01060   }
01061   long long id = 0;
01062   try
01063   {
01064     _pimpl->select_dirname_cmd->bind(":name", name);
01065     sqlite3_reader reader= _pimpl->select_dirname_cmd->executereader();
01066     if (!reader.read())
01067     {
01068       // does not exist
01069       _pimpl->insert_dirname_cmd->bind(":name", name);
01070       _pimpl->insert_dirname_cmd->executenonquery();
01071       id = _pimpl->con.insertid();
01072     }
01073     else
01074     {
01075       id = reader.getint64(0);
01076     }
01077     _pimpl->dir_cache[name] = id;
01078     return id;
01079   }
01080   catch ( const sqlite3x::database_error &e )
01081   {
01082     ZYPP_RETHROW(e);
01083   }
01084   return id;
01085 }
01086 
01087 RecordId CacheStore::lookupOrAppendFileName( const string &name )
01088 {
01089   long long id = 0;
01090   try
01091   {
01092     _pimpl->select_filename_cmd->bind(":name", name);
01093     sqlite3_reader reader= _pimpl->select_filename_cmd->executereader();
01094     if (!reader.read())
01095     {
01096       // does not exist
01097       _pimpl->insert_filename_cmd->bind(":name", name);
01098       _pimpl->insert_filename_cmd->executenonquery();
01099       id = _pimpl->con.insertid();
01100       return id;
01101    }
01102    return reader.getint64(0);
01103   }
01104   catch ( const sqlite3x::database_error &e )
01105   {
01106     ZYPP_RETHROW(e);
01107   }
01108   return id;
01109 }
01110 
01111 void CacheStore::setSharedData( const data::RecordId &resolvable_id,
01112                                 const data::RecordId &shared_id )
01113 {
01114   _pimpl->set_shared_flag_cmd->bind(":resolvable_id", resolvable_id);
01115 
01116   if ( shared_id == data::noRecordId )
01117    _pimpl->set_shared_flag_cmd->bind(":shared_id");
01118   else
01119    _pimpl->set_shared_flag_cmd->bind(":shared_id", shared_id);
01120 
01121   _pimpl->set_shared_flag_cmd->executenonquery();
01122 }
01123 
01124 void CacheStore::appendBooleanAttribute( const data::RecordId & resolvable_id,
01125                                          const std::string & klass,
01126                                          const std::string & name,
01127                                          bool value)
01128 {
01129   RecordId type_id = lookupOrAppendType( klass, name );
01130   appendNumericAttribute( resolvable_id, type_id, value ? 1 : 0 );
01131 }
01132 
01133 void CacheStore::appendNumericAttribute( const data::RecordId &resolvable_id,
01134                                          const std::string &klass,
01135                                          const std::string &name,
01136                                          int value )
01137 {
01138   RecordId type_id = lookupOrAppendType( klass, name );
01139   appendNumericAttribute( resolvable_id, type_id, value );
01140 }
01141 
01142 void CacheStore::appendNumericAttribute( const RecordId &resolvable_id,
01143                                          const RecordId &type_id,
01144                                          int value )
01145 {
01146   // weak resolvable_id
01147   _pimpl->append_num_attribute_cmd->bind(":rid", resolvable_id );
01148   _pimpl->append_num_attribute_cmd->bind(":attr_id", type_id );
01149 
01150   _pimpl->append_num_attribute_cmd->bind(":value", value );
01151 
01152   _pimpl->append_num_attribute_cmd->executenonquery();
01153 }
01154 
01155 
01156 void CacheStore::appendTranslatedStringAttribute( const data::RecordId &resolvable_id,
01157                                                   const std::string &klass,
01158                                                   const std::string &name,
01159                                                   const TranslatedText &text )
01160 {
01161   set<Locale> locales = text.locales();
01162   for ( set<Locale>::const_iterator it = locales.begin(); it != locales.end(); ++it )
01163   {
01164     appendStringAttributeTranslation( resolvable_id, *it, klass, name, text.text(*it) );
01165   }
01166 }
01167 
01168 
01169 void CacheStore::appendStringAttributeTranslation( const data::RecordId &resolvable_id,
01170                                                    const Locale &locale,
01171                                                    const std::string &klass,
01172                                                    const std::string &name,
01173                                                    const std::string &text )
01174 {
01175   // don't bother with writing if the string is empty
01176   if (text.empty()) return;
01177 
01178   RecordId lang_id = lookupOrAppendType("lang", locale.code() );
01179   RecordId type_id = lookupOrAppendType( klass, name );
01180   appendStringAttribute( resolvable_id, lang_id, type_id, text );
01181 }
01182 
01183 void CacheStore::appendStringAttribute( const data::RecordId &resolvable_id,
01184                                         const std::string &klass,
01185                                         const std::string &name,
01186                                         const std::string &value )
01187 {
01188   // don't bother with writing if the string is empty
01189   if (value.empty()) return;
01190 
01191   RecordId type_id = lookupOrAppendType(klass, name);
01192   appendStringAttribute( resolvable_id, type_id, value );
01193 }
01194 
01195 void CacheStore::appendStringAttribute( const RecordId &resolvable_id,
01196                                         const RecordId &type_id,
01197                                         const std::string &value )
01198 {
01199   // don't bother with writing if the string is empty
01200   if (value.empty()) return;
01201 
01202   RecordId lang_id = lookupOrAppendType("lang", "none");
01203   appendStringAttribute( resolvable_id, lang_id, type_id, value );
01204 }
01205 
01206 void CacheStore::appendStringAttribute( const RecordId &resolvable_id,
01207                             const RecordId &lang_id,
01208                             const RecordId &type_id,
01209                             const string &value )
01210 {
01211   // don't bother with writing if the string is empty
01212   if (value.empty()) return;
01213 
01214   // weak resolvable_id
01215   _pimpl->append_text_attribute_cmd->bind(":rid", resolvable_id );
01216   _pimpl->append_text_attribute_cmd->bind(":lang_id", lang_id );
01217   _pimpl->append_text_attribute_cmd->bind(":attr_id", type_id );
01218 
01219   _pimpl->append_text_attribute_cmd->bind(":text", value );
01220 
01221   _pimpl->append_text_attribute_cmd->executenonquery();
01222 }
01223 
01224 }
01225 }
01226 

Generated on Tue Sep 25 19:23:00 2007 for libzypp by  doxygen 1.5.3