CacheInitializer.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00009 
00010 #include <vector>
00011 #include <sstream>
00012 #include <fstream>
00013 
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/String.h"
00016 #include "zypp/base/Measure.h"
00017 #include "zypp/cache/CacheInitializer.h"
00018 #include "zypp/target/store/PersistentStorage.h"
00019 #include "zypp/cache/Utils.h"
00020 #include "zypp/PathInfo.h"
00021 #include "sqlite-schema.h"
00022 
00023 using namespace sqlite3x;
00024 using namespace std;
00025 using zypp::debug::Measure;
00026 
00028 namespace zypp
00029 { 
00030 
00031 namespace cache
00032 { 
00033 
00034 struct CacheInitializer::Impl
00035 {
00036   Impl( const Pathname &root_r )
00037   : root(root_r), just_initialized(false),
00038     just_reinitialized(false)
00039   {
00040   }
00041   //typedef std::map<media::MediaNr, media::MediaAccessId> MediaMap
00042   shared_ptr<sqlite3x::sqlite3_connection> con;
00043   Pathname root;
00044   bool just_initialized;
00045   bool just_reinitialized;
00046 };
00047 
00048 CacheInitializer::CacheInitializer( const Pathname &root_r, const Pathname &db_file )
00049   : _pimpl( new Impl( root_r ) )
00050 {
00051   try
00052   {
00053      assert_dir( _pimpl->root );
00054     _pimpl->con.reset( new sqlite3_connection( ( _pimpl->root + db_file).asString().c_str()) );
00055     _pimpl->con->executenonquery("pragma synchronous = 0;");
00056     _pimpl->con->executenonquery("begin;");
00057     if( ! tablesCreated() )
00058     {
00059       createTables();
00060       _pimpl->just_initialized = true;
00061       //_pimpl->con->close();
00062       MIL << "Repository cache initialized" << std::endl;
00063     }
00064     else
00065     {
00066       int version = _pimpl->con->executeint("select version from db_info;");
00067       if ( version != ZYPP_CACHE_SCHEMA_VERSION )
00068       {
00069         WAR << "cache schema version is different from ZYpp cache version" << endl;
00070         // FIXME should this code ask first?
00071         sqlite3_command tables_cmd( *_pimpl->con, "select name from sqlite_master where type='table';");
00072         sqlite3_reader reader = tables_cmd.executereader();
00073         list<string> tables;
00074         while ( reader.read() )
00075         {
00076           string tablename = reader.getstring(0);
00077           if ( tablename != "sqlite_sequence" )
00078             tables.push_back(tablename);
00079         }
00080         reader.close();
00081         
00082         for ( list<string>::const_iterator it = tables.begin();
00083               it != tables.end();
00084               ++it )
00085         {
00086           MIL << "Removing table " << *it << endl;
00087           _pimpl->con->execute("drop table " + (*it) + ";");
00088         }
00089         
00090         createTables();
00091         _pimpl->just_reinitialized = true;
00092         MIL << "Repository cache re-initialized" << std::endl;
00093         _pimpl->con->executenonquery("commit;");
00094         return;
00095       }
00096       
00097       MIL << "Repository cache already initialized" << std::endl;
00098     }
00099   }
00100   catch( const exception &ex )
00101   {
00102     ZYPP_RETHROW(Exception(ex.what()));
00103     //ERR << "Exception Occured: " << ex.what() << endl;
00104   }
00105   _pimpl->con->executenonquery("commit;");
00106   _pimpl->con->close();
00107 }
00108 
00109 bool CacheInitializer::justInitialized() const
00110 {
00111   return _pimpl->just_initialized;
00112 }
00113 
00114 bool CacheInitializer::justReinitialized() const
00115 {
00116   return _pimpl->just_reinitialized;
00117 }
00118 
00119 CacheInitializer::~CacheInitializer()
00120 {
00121 
00122 }
00123 
00124 bool CacheInitializer::tablesCreated() const
00125 {
00126   Measure timer("Check tables exist");
00127   unsigned int count = _pimpl->con->executeint("select count(*) from sqlite_master where type='table';");
00128   timer.elapsed();
00129   return ( count > 0 );
00130 }
00131 
00132 void CacheInitializer::createTables()
00133 {
00134   //Measure timer("Create database tables");
00135   MIL << "Initializing cache schema..." << endl;
00136   //sqlite3_transaction trans(*_pimpl->con);
00137   //{
00138     string sql( schemaData, _schemaData_size);
00139     //ERR << "Executing " << statements[i] << endl;
00140     MIL << "Schema size: " << sql.size() << endl;
00141     _pimpl->con->execute(sql.c_str());
00142     sqlite3_command version_cmd( *_pimpl->con, "insert into db_info (version) values(:version);");
00143     version_cmd.bind(":version", ZYPP_CACHE_SCHEMA_VERSION);
00144     version_cmd.executenonquery();
00145   //}
00146   //trans.commit();
00147   //timer.elapsed();
00148 }
00149 
00150 std::ostream & CacheInitializer::dumpOn( std::ostream & str ) const
00151 {
00152   return str;
00153 }
00154 
00155 }
00156 }
00157 

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