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
1.5.3