libzypp 9.41.1
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00009 00013 #include <sstream> 00014 00015 #include "zypp/base/PtrTypes.h" 00016 #include "zypp/base/String.h" 00017 #include "zypp/base/Logger.h" 00018 #include "zypp/parser/ParseException.h" 00019 00020 #include "zypp/HistoryLogData.h" 00021 00022 using namespace std; 00023 00025 namespace zypp 00026 { 00027 using parser::ParseException; 00028 00030 // 00031 // class HistoryActionID 00032 // 00034 00035 const HistoryActionID HistoryActionID::NONE (HistoryActionID::NONE_e); 00036 const HistoryActionID HistoryActionID::INSTALL (HistoryActionID::INSTALL_e); 00037 const HistoryActionID HistoryActionID::REMOVE (HistoryActionID::REMOVE_e); 00038 const HistoryActionID HistoryActionID::REPO_ADD (HistoryActionID::REPO_ADD_e); 00039 const HistoryActionID HistoryActionID::REPO_REMOVE (HistoryActionID::REPO_REMOVE_e); 00040 const HistoryActionID HistoryActionID::REPO_CHANGE_ALIAS (HistoryActionID::REPO_CHANGE_ALIAS_e); 00041 const HistoryActionID HistoryActionID::REPO_CHANGE_URL (HistoryActionID::REPO_CHANGE_URL_e); 00042 00043 HistoryActionID::HistoryActionID(const std::string & strval_r) 00044 : _id(parse(strval_r)) 00045 {} 00046 00047 HistoryActionID::ID HistoryActionID::parse( const std::string & strval_r ) 00048 { 00049 typedef std::map<std::string,ID> MapType; 00050 static MapType _table; 00051 if ( _table.empty() ) 00052 { 00053 // initialize it 00054 _table["install"] = INSTALL_e; 00055 _table["remove"] = REMOVE_e; 00056 _table["radd"] = REPO_ADD_e; 00057 _table["rremove"] = REPO_REMOVE_e; 00058 _table["ralias"] = REPO_CHANGE_ALIAS_e; 00059 _table["rurl"] = REPO_CHANGE_URL_e; 00060 _table["NONE"] = _table["none"] = NONE_e; 00061 } 00062 00063 MapType::const_iterator it = _table.find( strval_r ); 00064 if ( it != _table.end() ) 00065 return it->second; 00066 // else: 00067 WAR << "Unknown history action ID '" + strval_r + "'" << endl; 00068 return NONE_e; 00069 } 00070 00071 00072 const std::string & HistoryActionID::asString( bool pad ) const 00073 { 00074 typedef std::pair<std::string,std::string> PairType; 00075 typedef std::map<ID, PairType> MapType; 00076 static MapType _table; 00077 if ( _table.empty() ) 00078 { 00079 // initialize it pad(7) (for now) 00080 _table[INSTALL_e] = PairType( "install" , "install" ); 00081 _table[REMOVE_e] = PairType( "remove" , "remove " ); 00082 _table[REPO_ADD_e] = PairType( "radd" , "radd " ); 00083 _table[REPO_REMOVE_e] = PairType( "rremove" , "rremove" ); 00084 _table[REPO_CHANGE_ALIAS_e] = PairType( "ralias" , "ralias " ); 00085 _table[REPO_CHANGE_URL_e] = PairType( "rurl" , "rurl " ); 00086 _table[NONE_e] = PairType( "NONE" , "NONE " ); 00087 } 00088 00089 return( pad ? _table[_id].second : _table[_id].first ); 00090 } 00091 00092 std::ostream & operator << (std::ostream & str, const HistoryActionID & id) 00093 { return str << id.asString(); } 00094 00096 00098 // 00099 // class HistoryLogData::Impl 00100 // 00102 class HistoryLogData::Impl 00103 { 00104 public: 00105 Impl( FieldVector & fields_r, size_type expect_r ) 00106 { 00107 _checkFields( fields_r, expect_r ); 00108 _field.swap( fields_r ); 00109 // For whatever reason writer is ' '-padding the action field 00110 // but we don't want to modify the vector before we moved it. 00111 _field[ACTION_INDEX] = str::trim( _field[ACTION_INDEX] ); 00112 _action = HistoryActionID( _field[ACTION_INDEX] ); 00113 } 00114 00115 Impl( FieldVector & fields_r, HistoryActionID action_r, size_type expect_r ) 00116 { 00117 _checkFields( fields_r, expect_r ); 00118 // For whatever reason writer is ' '-padding the action field 00119 // but we don't want to modify the vector before we moved it. 00120 std::string trimmed( str::trim( fields_r[ACTION_INDEX] ) ); 00121 _action = HistoryActionID( trimmed ); 00122 if ( _action != action_r ) 00123 { 00124 ZYPP_THROW( ParseException( str::form( "Bad action id. Got %s, expected %s.", 00125 _action.asString().c_str(), 00126 action_r.asString().c_str() ) ) ); 00127 } 00128 _field.swap( fields_r ); 00129 // now adjust action field: 00130 _field[ACTION_INDEX] = trimmed; 00131 } 00132 00133 void _checkFields( const FieldVector & fields_r, size_type expect_r ) 00134 { 00135 if ( expect_r < 2 ) // at least 2 fields (date and action) are required 00136 expect_r = 2; 00137 if ( fields_r.size() < expect_r ) 00138 { 00139 ZYPP_THROW( ParseException( str::form( "Bad number of fields. Got %zd, expected at least %zd.", 00140 fields_r.size(), 00141 expect_r ) ) ); 00142 } 00143 try 00144 { 00145 _date = Date( fields_r[DATE_INDEX], HISTORY_LOG_DATE_FORMAT ); 00146 } 00147 catch ( const std::exception & excpt ) 00148 { 00149 ZYPP_THROW( ParseException( excpt.what() ) ); // invalid date format 00150 } 00151 // _action handled later 00152 } 00153 00154 public: 00155 FieldVector _field; 00156 Date _date; 00157 HistoryActionID _action; 00158 }; 00159 00161 // 00162 // class HistoryLogData 00163 // 00165 00166 HistoryLogData::HistoryLogData( FieldVector & fields_r, size_type expect_r ) 00167 : _pimpl( new Impl( fields_r, expect_r ) ) 00168 {} 00169 00170 HistoryLogData::HistoryLogData( FieldVector & fields_r, HistoryActionID expectedId_r, size_type expect_r ) 00171 : _pimpl( new Impl( fields_r, expectedId_r, expect_r ) ) 00172 {} 00173 00174 HistoryLogData::~HistoryLogData() 00175 {} 00176 00177 HistoryLogData::Ptr HistoryLogData::create( FieldVector & fields_r ) 00178 { 00179 if ( fields_r.size() >= 2 ) 00180 { 00181 // str::trim( _field[ACTION_INDEX] ); 00182 switch ( HistoryActionID( str::trim( fields_r[ACTION_INDEX] ) ).toEnum() ) 00183 { 00184 #define OUTS(E,T) case HistoryActionID::E: return Ptr( new T( fields_r ) ); break; 00185 OUTS( INSTALL_e, HistoryLogDataInstall ); 00186 OUTS( REMOVE_e, HistoryLogDataRemove ); 00187 OUTS( REPO_ADD_e, HistoryLogDataRepoAdd ); 00188 OUTS( REPO_REMOVE_e, HistoryLogDataRepoRemove ); 00189 OUTS( REPO_CHANGE_ALIAS_e, HistoryLogDataRepoAliasChange ); 00190 OUTS( REPO_CHANGE_URL_e, HistoryLogDataRepoUrlChange ); 00191 #undef OUTS 00192 // intentionally no default: 00193 case HistoryActionID::NONE_e: 00194 break; 00195 } 00196 } 00197 // unknown action or invalid fields? Ctor will accept or throw. 00198 return Ptr( new HistoryLogData( fields_r ) ); 00199 } 00200 00201 bool HistoryLogData::empty() const 00202 { return _pimpl->_field.empty(); } 00203 00204 HistoryLogData::size_type HistoryLogData::size() const 00205 { return _pimpl->_field.size(); } 00206 00207 HistoryLogData::const_iterator HistoryLogData::begin() const 00208 { return _pimpl->_field.begin(); } 00209 00210 HistoryLogData::const_iterator HistoryLogData::end() const 00211 { return _pimpl->_field.end(); } 00212 00213 const std::string & HistoryLogData::optionalAt( size_type idx_r ) const 00214 { 00215 static const std::string _empty; 00216 return( idx_r < size() ? _pimpl->_field[idx_r] : _empty ); 00217 } 00218 00219 const std::string & HistoryLogData::at( size_type idx_r ) const 00220 { return _pimpl->_field.at( idx_r ); } 00221 00222 00223 Date HistoryLogData::date() const 00224 { return _pimpl->_date; } 00225 00226 HistoryActionID HistoryLogData::action() const 00227 { return _pimpl->_action; } 00228 00229 00230 std::ostream & operator<<( std::ostream & str, const HistoryLogData & obj ) 00231 { return str << str::joinEscaped( obj.begin(), obj.end(), '|' ); } 00232 00234 // class HistoryLogDataInstall 00236 HistoryLogDataInstall::HistoryLogDataInstall( FieldVector & fields_r ) 00237 : HistoryLogData( fields_r ) 00238 {} 00239 std::string HistoryLogDataInstall::name() const { return optionalAt( NAME_INDEX ); } 00240 Edition HistoryLogDataInstall::edition() const { return Edition( optionalAt( EDITION_INDEX ) ); } 00241 Arch HistoryLogDataInstall::arch() const { return Arch( optionalAt( ARCH_INDEX ) ); } 00242 std::string HistoryLogDataInstall::reqby() const { return optionalAt( REQBY_INDEX ); } 00243 std::string HistoryLogDataInstall::repoAlias() const { return optionalAt( REPOALIAS_INDEX ); } 00244 CheckSum HistoryLogDataInstall::checksum() const { return optionalAt( CHEKSUM_INDEX ); } 00245 std::string HistoryLogDataInstall::userdata() const { return optionalAt( USERDATA_INDEX ); } 00246 00248 // class HistoryLogDataRemove 00250 HistoryLogDataRemove::HistoryLogDataRemove( FieldVector & fields_r ) 00251 : HistoryLogData( fields_r ) 00252 {} 00253 std::string HistoryLogDataRemove::name() const { return optionalAt( NAME_INDEX ); } 00254 Edition HistoryLogDataRemove::edition() const { return Edition( optionalAt( EDITION_INDEX ) ); } 00255 Arch HistoryLogDataRemove::arch() const { return Arch( optionalAt( ARCH_INDEX ) ); } 00256 std::string HistoryLogDataRemove::reqby() const { return optionalAt( REQBY_INDEX ); } 00257 std::string HistoryLogDataRemove::userdata() const { return optionalAt( USERDATA_INDEX ); } 00258 00260 // class HistoryLogDataRepoAdd 00262 HistoryLogDataRepoAdd::HistoryLogDataRepoAdd( FieldVector & fields_r ) 00263 : HistoryLogData( fields_r ) 00264 {} 00265 std::string HistoryLogDataRepoAdd::alias() const { return optionalAt( ALIAS_INDEX ); } 00266 Url HistoryLogDataRepoAdd::url() const { return optionalAt( URL_INDEX ); } 00267 std::string HistoryLogDataRepoAdd::userdata() const { return optionalAt( USERDATA_INDEX ); } 00268 00270 // class HistoryLogDataRepoRemove 00272 HistoryLogDataRepoRemove::HistoryLogDataRepoRemove( FieldVector & fields_r ) 00273 : HistoryLogData( fields_r ) 00274 {} 00275 std::string HistoryLogDataRepoRemove::alias() const { return optionalAt( ALIAS_INDEX ); } 00276 std::string HistoryLogDataRepoRemove::userdata() const { return optionalAt( USERDATA_INDEX ); } 00277 00279 // class HistoryLogDataRepoAliasChange 00281 HistoryLogDataRepoAliasChange::HistoryLogDataRepoAliasChange( FieldVector & fields_r ) 00282 : HistoryLogData( fields_r ) 00283 {} 00284 std::string HistoryLogDataRepoAliasChange::oldAlias() const { return optionalAt( OLDALIAS_INDEX ); } 00285 std::string HistoryLogDataRepoAliasChange::newAlias() const { return optionalAt( NEWALIAS_INDEX ); } 00286 std::string HistoryLogDataRepoAliasChange::userdata() const { return optionalAt( USERDATA_INDEX ); } 00287 00289 // class HistoryLogDataRepoUrlChange 00291 HistoryLogDataRepoUrlChange::HistoryLogDataRepoUrlChange( FieldVector & fields_r ) 00292 : HistoryLogData( fields_r ) 00293 {} 00294 std::string HistoryLogDataRepoUrlChange::alias() const { return optionalAt( ALIAS_INDEX ); } 00295 Url HistoryLogDataRepoUrlChange::newUrl() const { return optionalAt( NEWURL_INDEX ); } 00296 std::string HistoryLogDataRepoUrlChange::userdata() const { return optionalAt( USERDATA_INDEX ); } 00297 00298 00299 #if defined(WITH_DEPRECATED_HISTORYITEM_API) 00300 00301 00302 00303 00304 00305 00306 HistoryItem::HistoryItem(FieldVector & fields) 00307 { 00308 if (fields.size() <= 2) 00309 ZYPP_THROW(ParseException( 00310 str::form("Bad number of fields. Got %zd, expected more than %d.", 00311 fields.size(), 2))); 00312 00313 date = Date(fields[0], HISTORY_LOG_DATE_FORMAT); 00314 action = HistoryActionID(str::trim(fields[1])); 00315 } 00316 00317 void HistoryItem::dumpTo(ostream & str) const 00318 { 00319 str << date.form(HISTORY_LOG_DATE_FORMAT) << "|" << action.asString(); 00320 } 00321 00322 ostream & operator<<(ostream & str, const HistoryItem & obj) 00323 { 00324 obj.dumpTo(str); 00325 return str; 00326 } 00327 00328 00330 // 00331 // CLASS NAME: HistoryItemInstall (deprecated!) 00332 // 00334 00335 HistoryItemInstall::HistoryItemInstall(FieldVector & fields) 00336 : HistoryItem(fields) 00337 { 00338 if (fields.size() < 8) 00339 ZYPP_THROW(ParseException( 00340 str::form("Bad number of fields. Got %zu, expected %u.", 00341 fields.size(), 8))); 00342 00343 name = fields[2]; 00344 edition = Edition(fields[3]); 00345 arch = Arch(fields[4]); 00346 reqby = fields[5]; 00347 repoalias = fields[6]; 00348 checksum = CheckSum::sha(fields[7]); 00349 } 00350 00351 void HistoryItemInstall::dumpTo(ostream & str) const 00352 { 00353 HistoryItem::dumpTo(str); 00354 str << "|" 00355 << name << "|" 00356 << edition << "|" 00357 << arch << "|" 00358 << reqby << "|" 00359 << repoalias << "|" 00360 << checksum; 00361 } 00362 00363 ostream & operator<<(ostream & str, const HistoryItemInstall & obj) 00364 { 00365 obj.dumpTo(str); 00366 return str; 00367 } 00368 00369 00371 // 00372 // CLASS NAME: HistoryItemRemove (deprecated!) 00373 // 00375 00376 HistoryItemRemove::HistoryItemRemove(FieldVector & fields) 00377 : HistoryItem(fields) 00378 { 00379 if (fields.size() < 6) 00380 ZYPP_THROW(ParseException( 00381 str::form("Bad number of fields. Got %zu, expected %u.", 00382 fields.size(), 6))); 00383 00384 name = fields[2]; 00385 edition = Edition(fields[3]); 00386 arch = Arch(fields[4]); 00387 reqby = fields[5]; 00388 } 00389 00390 void HistoryItemRemove::dumpTo(ostream & str) const 00391 { 00392 HistoryItem::dumpTo(str); 00393 str << "|" 00394 << name << "|" 00395 << edition << "|" 00396 << arch << "|" 00397 << reqby; 00398 } 00399 00400 ostream & operator<<(ostream & str, const HistoryItemRemove & obj) 00401 { 00402 obj.dumpTo(str); 00403 return str; 00404 } 00405 00406 00408 // 00409 // CLASS NAME: HistoryItemRepoAdd (deprecated!) 00410 // 00412 00413 HistoryItemRepoAdd::HistoryItemRepoAdd(FieldVector & fields) 00414 : HistoryItem(fields) 00415 { 00416 if (fields.size() < 4) 00417 ZYPP_THROW(ParseException( 00418 str::form("Bad number of fields. Got %zu, expected %u.", 00419 fields.size(), 4))); 00420 00421 alias = fields[2]; 00422 url = Url(fields[3]); 00423 } 00424 00425 void HistoryItemRepoAdd::dumpTo(ostream & str) const 00426 { 00427 HistoryItem::dumpTo(str); 00428 str << "|" 00429 << alias << "|" 00430 << url; 00431 } 00432 00433 ostream & operator<<(ostream & str, const HistoryItemRepoAdd & obj) 00434 { 00435 obj.dumpTo(str); 00436 return str; 00437 } 00438 00439 00441 // 00442 // CLASS NAME: HistoryItemRepoRemove (deprecated!) 00443 // 00445 00446 HistoryItemRepoRemove::HistoryItemRepoRemove(FieldVector & fields) 00447 : HistoryItem(fields) 00448 { 00449 if (fields.size() < 3) 00450 ZYPP_THROW(ParseException( 00451 str::form("Bad number of fields. Got %zu, expected %u.", 00452 fields.size(), 3))); 00453 00454 alias = fields[2]; 00455 } 00456 00457 void HistoryItemRepoRemove::dumpTo(ostream & str) const 00458 { 00459 HistoryItem::dumpTo(str); 00460 str << "|" << alias; 00461 } 00462 00463 ostream & operator<<(ostream & str, const HistoryItemRepoRemove & obj) 00464 { 00465 obj.dumpTo(str); 00466 return str; 00467 } 00468 00469 00471 // 00472 // CLASS NAME: HistoryItemRepoAliasChange (deprecated!) 00473 // 00475 00476 HistoryItemRepoAliasChange::HistoryItemRepoAliasChange(FieldVector & fields) 00477 : HistoryItem(fields) 00478 { 00479 if (fields.size() < 4) 00480 ZYPP_THROW(ParseException( 00481 str::form("Bad number of fields. Got %zu, expected %u.", 00482 fields.size(), 4))); 00483 00484 oldalias = fields[2]; 00485 newalias = fields[3]; 00486 } 00487 00488 void HistoryItemRepoAliasChange::dumpTo(ostream & str) const 00489 { 00490 HistoryItem::dumpTo(str); 00491 str << "|" << oldalias << "|" << newalias; 00492 } 00493 00494 ostream & operator<<(ostream & str, const HistoryItemRepoAliasChange & obj) 00495 { 00496 obj.dumpTo(str); 00497 return str; 00498 } 00499 00500 00502 // 00503 // CLASS NAME: HistoryItemRepoUrlChange (deprecated!) 00504 // 00506 00507 HistoryItemRepoUrlChange::HistoryItemRepoUrlChange(FieldVector & fields) 00508 : HistoryItem(fields) 00509 { 00510 if (fields.size() < 4) 00511 ZYPP_THROW(ParseException( 00512 str::form("Bad number of fields. Got %zu, expected %u.", 00513 fields.size(), 4))); 00514 00515 alias = fields[2]; 00516 newurl = Url(fields[3]); 00517 } 00518 00519 void HistoryItemRepoUrlChange::dumpTo(ostream & str) const 00520 { 00521 HistoryItem::dumpTo(str); 00522 str << "|" << alias << "|" << newurl; 00523 } 00524 00525 ostream & operator<<(ostream & str, const HistoryItemRepoUrlChange & obj) 00526 { 00527 obj.dumpTo(str); 00528 return str; 00529 } 00530 #endif // WITH_DEPRECATED_HISTORYITEM_API 00531 00532 } // namespace zypp