Hello community, here is the log from the commit of package libzypp for openSUSE:Factory checked in at 2012-12-05 13:58:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libzypp (Old) and /work/SRC/openSUSE:Factory/.libzypp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libzypp", Maintainer is "[email protected]" Changes: -------- --- /work/SRC/openSUSE:Factory/libzypp/libzypp.changes 2012-12-03 09:55:11.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.libzypp.new/libzypp.changes 2012-12-05 13:59:01.000000000 +0100 @@ -1,0 +2,13 @@ +Mon Dec 3 14:31:59 CET 2012 - [email protected] + +- HistoryLogReader: new HistoryLogData based API for parsing the new + history file entries (fate#312521) + The old HistoryItem based API is deprecated but will + still be available for a while if you compile with + -DWITH_DEPRECATED_HISTORYITEM_API. +- Write userdata string to history log (fate#312521) +- Add HistoryLogReader testcases +- Adapt to libsolv 'medianr'-changes +- version 12.5.0 (0) + +------------------------------------------------------------------- Old: ---- libzypp-12.4.0.tar.bz2 New: ---- libzypp-12.5.0.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libzypp.spec ++++++ --- /var/tmp/diff_new_pack.PIz27v/_old 2012-12-05 13:59:02.000000000 +0100 +++ /var/tmp/diff_new_pack.PIz27v/_new 2012-12-05 13:59:02.000000000 +0100 @@ -24,7 +24,7 @@ Group: System/Packages BuildRoot: %{_tmppath}/%{name}-%{version}-build Summary: Package, Patch, Pattern, and Product Management -Version: 12.4.0 +Version: 12.5.0 Release: 1 Source: %{name}-%{version}.tar.bz2 Source1: %{name}-rpmlintrc ++++++ libzypp-12.4.0.tar.bz2 -> libzypp-12.5.0.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/VERSION.cmake new/libzypp-12.5.0/VERSION.cmake --- old/libzypp-12.4.0/VERSION.cmake 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/VERSION.cmake 2012-12-03 14:41:52.000000000 +0100 @@ -60,9 +60,9 @@ # SET(LIBZYPP_MAJOR "12") SET(LIBZYPP_COMPATMINOR "0") -SET(LIBZYPP_MINOR "4") +SET(LIBZYPP_MINOR "5") SET(LIBZYPP_PATCH "0") # -# LAST RELEASED: 12.4.0 (0) +# LAST RELEASED: 12.5.0 (0) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/package/libzypp.changes new/libzypp-12.5.0/package/libzypp.changes --- old/libzypp-12.4.0/package/libzypp.changes 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/package/libzypp.changes 2012-12-03 14:41:52.000000000 +0100 @@ -1,4 +1,17 @@ ------------------------------------------------------------------- +Mon Dec 3 14:31:59 CET 2012 - [email protected] + +- HistoryLogReader: new HistoryLogData based API for parsing the new + history file entries (fate#312521) + The old HistoryItem based API is deprecated but will + still be available for a while if you compile with + -DWITH_DEPRECATED_HISTORYITEM_API. +- Write userdata string to history log (fate#312521) +- Add HistoryLogReader testcases +- Adapt to libsolv 'medianr'-changes +- version 12.5.0 (0) + +------------------------------------------------------------------- Thu Nov 22 01:14:42 CET 2012 - [email protected] - Update zypp-po.tar.bz2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/tests/parser/HistoryLogReader_test.cc new/libzypp-12.5.0/tests/parser/HistoryLogReader_test.cc --- old/libzypp-12.4.0/tests/parser/HistoryLogReader_test.cc 2012-11-23 18:11:09.000000000 +0100 +++ new/libzypp-12.5.0/tests/parser/HistoryLogReader_test.cc 2012-12-03 14:41:53.000000000 +0100 @@ -1,29 +1,75 @@ #include "TestSetup.h" +#define WITH_DEPRECATED_HISTORYITEM_API #include "zypp/parser/HistoryLogReader.h" #include "zypp/parser/ParseException.h" using namespace zypp; +#if defined(WITH_DEPRECATED_HISTORYITEM_API) namespace { - bool ProcessItem( const HistoryItem::Ptr & ptr ) + bool OldApi_ProcessItem( const HistoryItem::Ptr & ptr ) { DBG << ptr << endl; return true; } } -// Must be the first test! +BOOST_AUTO_TEST_CASE(OldApi_basic) +{ + parser::HistoryLogReader parser( TESTS_SRC_DIR "/parser/HistoryLogReader_test.dat", + OldApi_ProcessItem ); + + BOOST_CHECK_EQUAL( parser.ignoreInvalidItems(), false ); + BOOST_CHECK_THROW( parser.readAll(), parser::ParseException ); + + parser.setIgnoreInvalidItems( true ); + BOOST_CHECK_EQUAL( parser.ignoreInvalidItems(), true ); + parser.readAll(); +} + +#endif // WITH_DEPRECATED_HISTORYITEM_API + +namespace +{ + bool ProcessData( const HistoryLogData::Ptr & ptr ) + { + DBG << ptr->date() << " | " << ptr << endl; + + return true; + } +} + + BOOST_AUTO_TEST_CASE(basic) { + std::vector<HistoryLogData::Ptr> history; parser::HistoryLogReader parser( TESTS_SRC_DIR "/parser/HistoryLogReader_test.dat", - ProcessItem ); + parser::HistoryLogReader::Options(), + [&history]( HistoryLogData::Ptr ptr )->bool { + history.push_back( ptr ); + return true; + } ); BOOST_CHECK_EQUAL( parser.ignoreInvalidItems(), false ); BOOST_CHECK_THROW( parser.readAll(), parser::ParseException ); parser.setIgnoreInvalidItems( true ); BOOST_CHECK_EQUAL( parser.ignoreInvalidItems(), true ); + + history.clear(); parser.readAll(); + BOOST_CHECK_EQUAL( history.size(), 7 ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRepoAdd> ( history[0] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataInstall> ( history[1] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataInstall> ( history[2] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRemove> ( history[3] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRepoRemove> ( history[4] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRemove> ( history[5] ) ); + BOOST_CHECK( dynamic_pointer_cast<HistoryLogData> ( history[6] ) ); + + BOOST_CHECK_EQUAL( (*history[1])[HistoryLogDataInstall::USERDATA_INDEX], "trans|ID" ); // properly (un)escaped? + HistoryLogDataInstall::Ptr p = dynamic_pointer_cast<HistoryLogDataInstall>( history[1] ); + BOOST_CHECK_EQUAL( p->userdata(), "trans|ID" ); // properly (un)escaped? } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/tests/parser/HistoryLogReader_test.dat new/libzypp-12.5.0/tests/parser/HistoryLogReader_test.dat --- old/libzypp-12.4.0/tests/parser/HistoryLogReader_test.dat 2012-11-23 18:11:09.000000000 +0100 +++ new/libzypp-12.5.0/tests/parser/HistoryLogReader_test.dat 2012-12-03 14:41:53.000000000 +0100 @@ -1,5 +1,5 @@ 2009-09-29 07:24:46|radd |InstallationImage|file:/usr/src/packages/BUILD/openSUSE-images-11.2/gnome_cd/home/rpmdir| -2009-09-29 07:25:29|install|update-test-security|0-2.35|noarch|root@opensuse|InstallationImage|d99de2872270cbd436b0c10af85c286a1365a348| +2009-09-29 07:25:29|install|update-test-security|0-2.35|noarch|root@opensuse|InstallationImage|d99de2872270cbd436b0c10af85c286a1365a348|trans\|ID 2011-07-18 18:08:09|install|kernel-source|2.6.37.6-0.5.1|noarch||repo-update|7823612d9ca3de086c2cd4dca936f6a3f3e9313d| # 2009-09-29 07:25:30 filesystem.rpm installed ok # Additional rpm output: @@ -7,5 +7,6 @@ 2009-09-29 07:47:59|remove |PolicyKit-doc|0.9-15.20|x86_64|root@opensuse|trans\|ID 2009-09-29 07:47:32|rremove|InstallationImage| 2010-06-01 16:11:17|remove |xchat-python|2.8.6-43.13|x86_64|2848:y2base| -2010-06-01 16:11:17|bad |xchat-python|2.8.6-43.13|x86_64|2848:y2base| -[/] +2010-06-01 16:11:17|bad |unknown action field +discard\|one field +discard|to fields but bad date diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/zypp/CMakeLists.txt new/libzypp-12.5.0/zypp/CMakeLists.txt --- old/libzypp-12.4.0/zypp/CMakeLists.txt 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/zypp/CMakeLists.txt 2012-12-03 14:41:52.000000000 +0100 @@ -4,6 +4,9 @@ ADD_DEFINITIONS(-DLOCALEDIR="${CMAKE_INSTALL_PREFIX}/share/locale" -DTEXTDOMAIN="zypp" -DZYPP_DLL ) +# 2012-12-03: HistoryLogReader: deprecate old API based in HistoryItem; use HistoryLogData based one +ADD_DEFINITIONS(-DWITH_DEPRECATED_HISTORYITEM_API=1) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) #FILE(WRITE filename "message to write"... ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/zypp/HistoryLogData.cc new/libzypp-12.5.0/zypp/HistoryLogData.cc --- old/libzypp-12.4.0/zypp/HistoryLogData.cc 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/zypp/HistoryLogData.cc 2012-12-03 14:41:52.000000000 +0100 @@ -21,14 +21,14 @@ using namespace std; +/////////////////////////////////////////////////////////////////// namespace zypp { using parser::ParseException; - /////////////////////////////////////////////////////////////////// // - // CLASS NAME : HistoryActionID + // class HistoryActionID // /////////////////////////////////////////////////////////////////// @@ -61,12 +61,11 @@ } MapType::const_iterator it = _table.find( strval_r ); - if ( it == _table.end() ) - { - WAR << "Unknown history action ID '" + strval_r + "'" << endl; - return NONE_e; - } - return it->second; + if ( it != _table.end() ) + return it->second; + // else: + WAR << "Unknown history action ID '" + strval_r + "'" << endl; + return NONE_e; } @@ -95,13 +94,215 @@ /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + // + // class HistoryLogData::Impl + // + /////////////////////////////////////////////////////////////////// + class HistoryLogData::Impl + { + public: + Impl( FieldVector & fields_r, size_type expect_r ) + { + _checkFields( fields_r, expect_r ); + _field.swap( fields_r ); + // For whatever reason writer is ' '-padding the action field + // but we don't want to modify the vector before we moved it. + _field[ACTION_INDEX] = str::trim( _field[ACTION_INDEX] ); + _action = HistoryActionID( _field[ACTION_INDEX] ); + } - ///////////////////////////////////////////////////////////////////// + Impl( FieldVector & fields_r, HistoryActionID action_r, size_type expect_r ) + { + _checkFields( fields_r, expect_r ); + // For whatever reason writer is ' '-padding the action field + // but we don't want to modify the vector before we moved it. + std::string trimmed( str::trim( fields_r[ACTION_INDEX] ) ); + _action = HistoryActionID( trimmed ); + if ( _action != action_r ) + { + ZYPP_THROW( ParseException( str::form( "Bad action id. Got %s, expected %s.", + _action.asString().c_str(), + action_r.asString().c_str() ) ) ); + } + _field.swap( fields_r ); + // now adjust action field: + _field[ACTION_INDEX] = trimmed; + } + + void _checkFields( const FieldVector & fields_r, size_type expect_r ) + { + if ( expect_r < 2 ) // at least 2 fields (date and action) are required + expect_r = 2; + if ( fields_r.size() < expect_r ) + { + ZYPP_THROW( ParseException( str::form( "Bad number of fields. Got %zd, expected at least %zd.", + fields_r.size(), + expect_r ) ) ); + } + try + { + _date = Date( fields_r[DATE_INDEX], HISTORY_LOG_DATE_FORMAT ); + } + catch ( const std::exception & excpt ) + { + ZYPP_THROW( ParseException( excpt.what() ) ); // invalid date format + } + // _action handled later + } + + public: + FieldVector _field; + Date _date; + HistoryActionID _action; + }; + + /////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItem + // class HistoryLogData // - ///////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + + HistoryLogData::HistoryLogData( FieldVector & fields_r, size_type expect_r ) + : _pimpl( new Impl( fields_r, expect_r ) ) + {} + + HistoryLogData::HistoryLogData( FieldVector & fields_r, HistoryActionID expectedId_r, size_type expect_r ) + : _pimpl( new Impl( fields_r, expectedId_r, expect_r ) ) + {} + + HistoryLogData::~HistoryLogData() + {} + + HistoryLogData::Ptr HistoryLogData::create( FieldVector & fields_r ) + { + if ( fields_r.size() >= 2 ) + { + // str::trim( _field[ACTION_INDEX] ); + switch ( HistoryActionID( str::trim( fields_r[ACTION_INDEX] ) ).toEnum() ) + { +#define OUTS(E,T) case HistoryActionID::E: return Ptr( new T( fields_r ) ); break; + OUTS( INSTALL_e, HistoryLogDataInstall ); + OUTS( REMOVE_e, HistoryLogDataRemove ); + OUTS( REPO_ADD_e, HistoryLogDataRepoAdd ); + OUTS( REPO_REMOVE_e, HistoryLogDataRepoRemove ); + OUTS( REPO_CHANGE_ALIAS_e, HistoryLogDataRepoAliasChange ); + OUTS( REPO_CHANGE_URL_e, HistoryLogDataRepoUrlChange ); +#undef OUTS + // intentionally no default: + case HistoryActionID::NONE_e: + break; + } + } + // unknown action or invalid fields? Ctor will accept or throw. + return Ptr( new HistoryLogData( fields_r ) ); + } + + bool HistoryLogData::empty() const + { return _pimpl->_field.empty(); } + + HistoryLogData::size_type HistoryLogData::size() const + { return _pimpl->_field.size(); } + HistoryLogData::const_iterator HistoryLogData::begin() const + { return _pimpl->_field.begin(); } + + HistoryLogData::const_iterator HistoryLogData::end() const + { return _pimpl->_field.end(); } + + const std::string & HistoryLogData::optionalAt( size_type idx_r ) const + { + static const std::string _empty; + return( idx_r < size() ? _pimpl->_field[idx_r] : _empty ); + } + + const std::string & HistoryLogData::at( size_type idx_r ) const + { return _pimpl->_field.at( idx_r ); } + + + Date HistoryLogData::date() const + { return _pimpl->_date; } + + HistoryActionID HistoryLogData::action() const + { return _pimpl->_action; } + + + std::ostream & operator<<( std::ostream & str, const HistoryLogData & obj ) + { return str << str::joinEscaped( obj.begin(), obj.end(), '|' ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataInstall + /////////////////////////////////////////////////////////////////// + HistoryLogDataInstall::HistoryLogDataInstall( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataInstall::name() const { return optionalAt( NAME_INDEX ); } + Edition HistoryLogDataInstall::edition() const { return Edition( optionalAt( EDITION_INDEX ) ); } + Arch HistoryLogDataInstall::arch() const { return Arch( optionalAt( ARCH_INDEX ) ); } + std::string HistoryLogDataInstall::reqby() const { return optionalAt( REQBY_INDEX ); } + std::string HistoryLogDataInstall::repoAlias() const { return optionalAt( REPOALIAS_INDEX ); } + CheckSum HistoryLogDataInstall::checksum() const { return optionalAt( CHEKSUM_INDEX ); } + std::string HistoryLogDataInstall::userdata() const { return optionalAt( USERDATA_INDEX ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataRemove + /////////////////////////////////////////////////////////////////// + HistoryLogDataRemove::HistoryLogDataRemove( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataRemove::name() const { return optionalAt( NAME_INDEX ); } + Edition HistoryLogDataRemove::edition() const { return Edition( optionalAt( EDITION_INDEX ) ); } + Arch HistoryLogDataRemove::arch() const { return Arch( optionalAt( ARCH_INDEX ) ); } + std::string HistoryLogDataRemove::reqby() const { return optionalAt( REQBY_INDEX ); } + std::string HistoryLogDataRemove::userdata() const { return optionalAt( USERDATA_INDEX ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataRepoAdd + /////////////////////////////////////////////////////////////////// + HistoryLogDataRepoAdd::HistoryLogDataRepoAdd( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataRepoAdd::alias() const { return optionalAt( ALIAS_INDEX ); } + Url HistoryLogDataRepoAdd::url() const { return optionalAt( URL_INDEX ); } + std::string HistoryLogDataRepoAdd::userdata() const { return optionalAt( USERDATA_INDEX ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataRepoRemove + /////////////////////////////////////////////////////////////////// + HistoryLogDataRepoRemove::HistoryLogDataRepoRemove( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataRepoRemove::alias() const { return optionalAt( ALIAS_INDEX ); } + std::string HistoryLogDataRepoRemove::userdata() const { return optionalAt( USERDATA_INDEX ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataRepoAliasChange + /////////////////////////////////////////////////////////////////// + HistoryLogDataRepoAliasChange::HistoryLogDataRepoAliasChange( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataRepoAliasChange::oldAlias() const { return optionalAt( OLDALIAS_INDEX ); } + std::string HistoryLogDataRepoAliasChange::newAlias() const { return optionalAt( NEWALIAS_INDEX ); } + std::string HistoryLogDataRepoAliasChange::userdata() const { return optionalAt( USERDATA_INDEX ); } + + /////////////////////////////////////////////////////////////////// + // class HistoryLogDataRepoUrlChange + /////////////////////////////////////////////////////////////////// + HistoryLogDataRepoUrlChange::HistoryLogDataRepoUrlChange( FieldVector & fields_r ) + : HistoryLogData( fields_r ) + {} + std::string HistoryLogDataRepoUrlChange::alias() const { return optionalAt( ALIAS_INDEX ); } + Url HistoryLogDataRepoUrlChange::newUrl() const { return optionalAt( NEWURL_INDEX ); } + std::string HistoryLogDataRepoUrlChange::userdata() const { return optionalAt( USERDATA_INDEX ); } + + +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + /////////////////////////////////////////////////////////////////// + /// \class HistoryItem + /// \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. + /// They grant direct access to data members, so can not be extended + /// without losing binary compatibility. + /////////////////////////////////////////////////////////////////// HistoryItem::HistoryItem(FieldVector & fields) { if (fields.size() <= 2) @@ -127,7 +328,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemInstall + // CLASS NAME: HistoryItemInstall (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -168,7 +369,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemRemove + // CLASS NAME: HistoryItemRemove (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -205,7 +406,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemRepoAdd + // CLASS NAME: HistoryItemRepoAdd (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -238,7 +439,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemRepoRemove + // CLASS NAME: HistoryItemRepoRemove (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -268,7 +469,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemRepoAliasChange + // CLASS NAME: HistoryItemRepoAliasChange (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -299,7 +500,7 @@ ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryItemRepoUrlChange + // CLASS NAME: HistoryItemRepoUrlChange (deprecated!) // ///////////////////////////////////////////////////////////////////// @@ -326,6 +527,7 @@ obj.dumpTo(str); return str; } +#endif // WITH_DEPRECATED_HISTORYITEM_API - -} +} // namespace zypp +/////////////////////////////////////////////////////////////////// diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/zypp/HistoryLogData.h new/libzypp-12.5.0/zypp/HistoryLogData.h --- old/libzypp-12.4.0/zypp/HistoryLogData.h 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/zypp/HistoryLogData.h 2012-12-03 14:41:52.000000000 +0100 @@ -15,6 +15,7 @@ #include <iosfwd> +#include "zypp/APIConfig.h" #include "zypp/Date.h" #include "zypp/Edition.h" #include "zypp/Arch.h" @@ -23,6 +24,7 @@ #define HISTORY_LOG_DATE_FORMAT "%Y-%m-%d %H:%M:%S" +/////////////////////////////////////////////////////////////////// namespace zypp { /////////////////////////////////////////////////////////////////// @@ -71,14 +73,323 @@ }; /** \relates HistoryActionID */ + inline bool operator==( const HistoryActionID & lhs, const HistoryActionID & rhs ) + { return lhs.toEnum() == rhs.toEnum(); } + + /** \relates HistoryActionID */ + inline bool operator!=( const HistoryActionID & lhs, const HistoryActionID & rhs ) + { return lhs.toEnum() != rhs.toEnum(); } + + /** \relates HistoryActionID */ std::ostream & operator << (std::ostream & str, const HistoryActionID & id); /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogData + /// \brief A zypp history log line split into fields + /// \ingroup g_ZyppHistory + /// + /// Each valid history log line starts with a date and HistoryActionID + /// field. Subsequent fields depend on the kind of action. See derived + /// classes for convenient access to those flields. + /// + /// HistoryLogData itself provides mostly generic access to the fields + /// plain string values. Derived classes for well known entries tell + /// + /////////////////////////////////////////////////////////////////// + class HistoryLogData + { + public: + typedef shared_ptr<HistoryLogData> Ptr; + typedef shared_ptr<const HistoryLogData> constPtr; - ///////////////////////////////////////////////////////////////////// - // - // CLASS NAME: HistoryItem - // + typedef std::vector<std::string> FieldVector; + typedef FieldVector::size_type size_type; + typedef FieldVector::const_iterator const_iterator; + + public: + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has not at least \a expect_r entries + * \note 2 fields (date and action) are always required. + */ + explicit HistoryLogData( FieldVector & fields_r, size_type expect_r = 2 ); + + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or not at least \a expect_r entries. + * \note 2 fields (date and action) are always required. + */ + HistoryLogData( FieldVector & fields_r, HistoryActionID action_r, size_type expect_r = 2 ); + + /** Dtor */ + virtual ~HistoryLogData(); + + /** Factory method creating HistoryLogData classes. + * + * Moves \a fields_r into a HistoryLogData or derived object, depending on the + * HistoryActionID. For known action ids a coresponing HistoryLogData class + * is created, to allow convenient access to the field values. For unknown + * action ids a plain HistoryLogData object is created. \ref HistoryActionID + * \ref NONE_e id used in this case. + * + * \throws ParseException if \a fields_r does not contain the required format. + */ + static Ptr create( FieldVector & fields_r ); + + public: + /** Whether FieldVector is empty. */ + bool empty() const; + + /** Number of fields in vector. */ + size_type size() const; + + /** Iterator pointing to 1st element in vector (or end()). */ + const_iterator begin() const; + + /** Iterator pointing behind the last element in vector. */ + const_iterator end() const; + + /** Access (optional) field by number. + * \returns an empty string if \a idx_r is out of range. + * \see \ref at + */ + const std::string & optionalAt( size_type idx_r ) const; + /** \overload */ + const std::string & operator[]( size_type idx_r ) const + { return optionalAt( idx_r ); } + + /** Access (required) field by number. + * \throws std::out_of_range if \a idx_r is out of range. + * \see \ref optionalAt + */ + const std::string & at( size_type idx_r ) const; + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = 0, ///< date + ACTION_INDEX = 1, ///< HistoryActionID + }; + + public: + Date date() const; ///< date + HistoryActionID action() const; ///< HistoryActionID (or \c NONE_e if unknown) + + public: + class Impl; ///< Implementation class + private: + RWCOW_pointer<Impl> _pimpl; ///< Pointer to implementation + protected: + HistoryLogData & operator=( const HistoryLogData & ); ///< no base class assign + }; + + /** \relates HistoryLogData Stream output */ + std::ostream & operator<<( std::ostream & str, const HistoryLogData & obj ); + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataInstall + /// \brief A zypp history log line for an installed packaged. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataInstall : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataInstall> Ptr; + typedef shared_ptr<const HistoryLogDataInstall> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataInstall( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + NAME_INDEX, ///< package name + EDITION_INDEX, ///< package edition + ARCH_INDEX, ///< package architecture + REQBY_INDEX, ///< requested by (user@hostname, pid:appname, or empty (solver)) + REPOALIAS_INDEX, ///< repository providing the package + CHEKSUM_INDEX, ///< package checksum + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string name() const; ///< package name + Edition edition() const; ///< package edition + Arch arch() const; ///< package architecture + std::string reqby() const; ///< requested by (user@hostname, pid:appname, or empty (solver)) + std::string repoAlias() const; ///< repository providing the package + CheckSum checksum() const; ///< package checksum + std::string userdata() const; ///< userdata/transactionID + }; + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataRemove + /// \brief A zypp history log line for a removed packge. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataRemove : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataRemove> Ptr; + typedef shared_ptr<const HistoryLogDataRemove> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataRemove( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + NAME_INDEX, ///< package name + EDITION_INDEX, ///< package edition + ARCH_INDEX, ///< package architecture + REQBY_INDEX, ///< requested by (user@hostname, pid:appname, or empty (solver)) + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string name() const; ///< package name + Edition edition() const; ///< package edition + Arch arch() const; ///< package architecture + std::string reqby() const; ///< requested by (user@hostname, pid:appname, or empty (solver)) + std::string userdata() const; ///< userdata/transactionID + }; + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataRepoAdd + /// \brief A zypp history log line for an added repository. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataRepoAdd : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataRepoAdd> Ptr; + typedef shared_ptr<const HistoryLogDataRepoAdd> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataRepoAdd( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + ALIAS_INDEX, ///< repository alias + URL_INDEX, ///< repository url + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string alias() const; ///< repository alias + Url url() const; ///< repository url + std::string userdata() const; ///< userdata/transactionID + }; + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataRepoRemove + /// \brief A zypp history log line for a removed repository. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataRepoRemove : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataRepoRemove> Ptr; + typedef shared_ptr<const HistoryLogDataRepoRemove> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataRepoRemove( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + ALIAS_INDEX, ///< repository alias + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string alias() const; ///< repository alias + std::string userdata() const; ///< userdata/transactionID + }; + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataRepoAliasChange + /// \brief A zypp history log line for a repo alias change. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataRepoAliasChange : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataRepoAliasChange> Ptr; + typedef shared_ptr<const HistoryLogDataRepoAliasChange> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataRepoAliasChange( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + OLDALIAS_INDEX, ///< repositories old alias + NEWALIAS_INDEX, ///< repositories new alias + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string oldAlias() const; ///< repositories old alias + std::string newAlias() const; ///< repositories new alias + std::string userdata() const; ///< userdata/transactionID + }; + + /////////////////////////////////////////////////////////////////// + /// \class HistoryLogDataRepoUrlChange + /// \brief A zypp history log line for a repo url change. + /// \ingroup g_ZyppHistory + /////////////////////////////////////////////////////////////////// + class HistoryLogDataRepoUrlChange : public HistoryLogData + { + public: + typedef shared_ptr<HistoryLogDataRepoUrlChange> Ptr; + typedef shared_ptr<const HistoryLogDataRepoUrlChange> constPtr; + /** Ctor \b moving \a FieldVector (via swap). + * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields. + */ + HistoryLogDataRepoUrlChange( FieldVector & fields_r ); + + public: + enum Index ///< indices of known fields + { + DATE_INDEX = HistoryLogData::DATE_INDEX, + ACTION_INDEX = HistoryLogData::ACTION_INDEX, + ALIAS_INDEX, ///< repository alias + NEWURL_INDEX, ///< repositories new url + USERDATA_INDEX, ///< userdata/transactionID + }; + + public: + std::string alias() const; ///< repository alias + Url newUrl() const; ///< repositories new url + std::string userdata() const; ///< userdata/transactionID + }; + + +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + /////////////////////////////////////////////////////////////////// + /// \class HistoryItem + /// \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. + /// They grant direct access to data members, so can not be extended + /// without losing binary compatibility. + /////////////////////////////////////////////////////////////////// class HistoryItem { public: @@ -103,7 +414,8 @@ // // CLASS NAME: HistoryItemInstall // - class HistoryItemInstall : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemInstall : public HistoryItem { public: typedef shared_ptr<HistoryItemInstall> Ptr; @@ -129,7 +441,8 @@ // // CLASS NAME: HistoryItemRemove // - class HistoryItemRemove : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemRemove : public HistoryItem { public: typedef shared_ptr<HistoryItemRemove> Ptr; @@ -153,7 +466,8 @@ // // CLASS NAME: HistoryItemRepoAdd // - class HistoryItemRepoAdd : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemRepoAdd : public HistoryItem { public: typedef shared_ptr<HistoryItemRepoAdd> Ptr; @@ -175,7 +489,8 @@ // // CLASS NAME: HistoryItemRepoRemove // - class HistoryItemRepoRemove : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemRepoRemove : public HistoryItem { public: typedef shared_ptr<HistoryItemRepoRemove> Ptr; @@ -196,7 +511,8 @@ // // CLASS NAME: HistoryItemRepoAliasChange // - class HistoryItemRepoAliasChange : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemRepoAliasChange : public HistoryItem { public: typedef shared_ptr<HistoryItemRepoAliasChange> Ptr; @@ -218,7 +534,8 @@ // // CLASS NAME: HistoryItemRepoUrlChange // - class HistoryItemRepoUrlChange : public HistoryItem + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + class ZYPP_DEPRECATED HistoryItemRepoUrlChange : public HistoryItem { public: typedef shared_ptr<HistoryItemRepoUrlChange> Ptr; @@ -236,7 +553,8 @@ ///////////////////////////////////////////////////////////////////// std::ostream & operator<<(std::ostream & str, const HistoryItem & obj); +#endif // WITH_DEPRECATED_HISTORYITEM_API -} - +} // namespace zypp +/////////////////////////////////////////////////////////////////// #endif /* ZYPP_HISTORYLOGDATA_H_ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/zypp/parser/HistoryLogReader.cc new/libzypp-12.5.0/zypp/parser/HistoryLogReader.cc --- old/libzypp-12.4.0/zypp/parser/HistoryLogReader.cc 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/zypp/parser/HistoryLogReader.cc 2012-12-03 14:41:52.000000000 +0100 @@ -19,49 +19,195 @@ #include "zypp/parser/HistoryLogReader.h" -using namespace std; +using std::endl; /////////////////////////////////////////////////////////////////// namespace zypp -{ ///////////////////////////////////////////////////////////////// +{ /////////////////////////////////////////////////////////////////// namespace parser - { ///////////////////////////////////////////////////////////////// - + { ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryLogReader::Impl + // class HistoryLogReader::Impl // ///////////////////////////////////////////////////////////////////// - struct HistoryLogReader::Impl { - Impl( const Pathname & historyFile, const ProcessItem & callback ); - ~Impl() + Impl( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r ) + : _filename( historyFile_r ) + , _options( options_r ) + , _callback( callback_r ) {} - HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields); - void parseLine(const string & line, unsigned int lineNr); + bool parseLine( const std::string & line_r, unsigned int lineNr_r ); - void readAll( const ProgressData::ReceiverFnc & progress ); - void readFrom( const Date & date, const ProgressData::ReceiverFnc & progress ); - void readFromTo( const Date & fromDate, const Date & toDate, const ProgressData::ReceiverFnc & progress ); + void readAll( const ProgressData::ReceiverFnc & progress_r ); + void readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r ); + void readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r ); Pathname _filename; - ProcessItem _callback; - bool _ignoreInvalid; + Options _options; + ProcessData _callback; + +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + ProcessItem _oldAPICallback; + private: + HistoryItem::Ptr _oldAPIcreateHistoryItem( HistoryItem::FieldVector & fields ); + void _oldAPIparseLine(const std::string & line, unsigned int lineNr); +#endif // WITH_DEPRECATED_HISTORYITEM_API }; + bool HistoryLogReader::Impl::parseLine( const std::string & line_r, unsigned lineNr_r ) + { +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + if ( _oldAPICallback ) + { + _oldAPIparseLine( line_r, lineNr_r ); + return true; // old api did not eavluate callback return value :( + } +#endif // WITH_DEPRECATED_HISTORYITEM_API + + // parse into fields + HistoryLogData::FieldVector fields; + str::splitEscaped( line_r, std::back_inserter(fields), "|", true ); + if ( fields.size() >= 2 ) + str::trim( fields[1] ); // for whatever reason writer is padding the action field - HistoryLogReader::Impl::Impl( const Pathname & historyFile, const ProcessItem & callback ) - : _filename( historyFile ) - , _callback( callback ) - , _ignoreInvalid( false ) - {} + // move into data class + HistoryLogData::Ptr data; + try + { + data = HistoryLogData::create( fields ); + } + catch ( const Exception & excpt ) + { + ZYPP_CAUGHT( excpt ); + if ( _options.testFlag( IGNORE_INVALID_ITEMS ) ) + { + WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl; + return true; + } + else + { + ERR << "Invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl; + ParseException newexcpt( str::Str() << "Error in history log on line #" << lineNr_r ); + newexcpt.remember( excpt ); + ZYPP_THROW( newexcpt ); + } + } + + // consume data + if ( _callback && !_callback( data ) ) + { + WAR << "Stop parsing requested by consumer callback on line #" << lineNr_r << endl; + return false; + } + return true; + } + + void HistoryLogReader::Impl::readAll( const ProgressData::ReceiverFnc & progress_r ) + { + InputStream is( _filename ); + iostr::EachLine line( is ); + + ProgressData pd; + pd.sendTo( progress_r ); + pd.toMin(); + + for ( ; line; line.next(), pd.tick() ) + { + // ignore comments + if ( (*line)[0] == '#' ) + continue; + + if ( ! parseLine( *line, line.lineNo() ) ) + break; // requested by consumer callback + } + + pd.toMax(); + } + void HistoryLogReader::Impl::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r ) + { + InputStream is( _filename ); + iostr::EachLine line( is ); + + ProgressData pd; + pd.sendTo( progress_r ); + pd.toMin(); + + bool pastDate = false; + for ( ; line; line.next(), pd.tick() ) + { + const std::string & s = *line; + + // ignore comments + if ( s[0] == '#' ) + continue; + + if ( pastDate ) + { + if ( ! parseLine( s, line.lineNo() ) ) + break; // requested by consumer callback + } + else + { + Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT ); + if ( logDate > date_r ) + { + pastDate = true; + if ( ! parseLine( s, line.lineNo() ) ) + break; // requested by consumer callback + } + } + } - HistoryItem::Ptr HistoryLogReader::Impl::createHistoryItem( HistoryItem::FieldVector & fields ) + pd.toMax(); + } + + void HistoryLogReader::Impl::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r ) + { + InputStream is( _filename ); + iostr::EachLine line( is ); + + ProgressData pd; + pd.sendTo( progress_r ); + pd.toMin(); + + bool pastFromDate = false; + for ( ; line; line.next(), pd.tick() ) + { + const std::string & s = *line; + + // ignore comments + if ( s[0] == '#' ) + continue; + + Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT ); + + // past toDate - stop reading + if ( logDate >= toDate_r ) + break; + + // past fromDate - start reading + if ( !pastFromDate && logDate > fromDate_r ) + pastFromDate = true; + + if ( pastFromDate ) + { + if ( ! parseLine( s, line.lineNo() ) ) + break; // requested by consumer callback + } + } + + pd.toMax(); + } + + +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + HistoryItem::Ptr HistoryLogReader::Impl::_oldAPIcreateHistoryItem( HistoryItem::FieldVector & fields ) { HistoryActionID aid( str::trim( fields[1] ) ); switch ( aid.toEnum() ) @@ -95,9 +241,7 @@ } return HistoryItem::Ptr(); } - - - void HistoryLogReader::Impl::parseLine( const string & line, unsigned int lineNr ) + void HistoryLogReader::Impl::_oldAPIparseLine( const std::string & line, unsigned int lineNr ) { // parse into fields HistoryItem::FieldVector fields; @@ -105,7 +249,7 @@ if ( fields.size() <= 2 ) { - if ( !_ignoreInvalid ) + if ( ! _options.testFlag( IGNORE_INVALID_ITEMS ) ) { ParseException e( str::form( "Error in history log on line #%u.", lineNr ) ); e.addHistory( str::form( "Bad number of fields. Got %zd, expected more than %d.", fields.size(), 2 ) ); @@ -121,14 +265,14 @@ HistoryItem::Ptr item_ptr; try { - item_ptr = createHistoryItem( fields ); + item_ptr = _oldAPIcreateHistoryItem( fields ); } catch ( const Exception & e ) { ZYPP_CAUGHT(e); ERR << "Invalid history log entry on line #" << lineNr << " '"<< line << "'" << endl; - if ( !_ignoreInvalid ) + if ( ! _options.testFlag( IGNORE_INVALID_ITEMS ) ) { ParseException newe( str::form( "Error in history log on line #%u.", lineNr ) ); newe.remember( e ); @@ -138,9 +282,9 @@ if ( item_ptr ) { - _callback( item_ptr ); + _oldAPICallback( item_ptr ); } - else if ( !_ignoreInvalid ) + else if ( ! _options.testFlag( IGNORE_INVALID_ITEMS ) ) { ParseException e( str::form( "Error in history log on line #%u.", lineNr ) ); e.addHistory( "Unknown entry type." ); @@ -151,137 +295,44 @@ WAR << "Unknown history log action type: " << fields[1] << " on line #" << lineNr << endl; } } - - - void HistoryLogReader::Impl::readAll(const ProgressData::ReceiverFnc & progress) - { - InputStream is(_filename); - iostr::EachLine line(is); - - ProgressData pd; - pd.sendTo( progress ); - pd.toMin(); - - for (; line; line.next(), pd.tick() ) - { - // ignore comments - if ((*line)[0] == '#') - continue; - - parseLine(*line, line.lineNo()); - } - - pd.toMax(); - } - - void HistoryLogReader::Impl::readFrom(const Date & date, - const ProgressData::ReceiverFnc & progress) - { - InputStream is(_filename); - iostr::EachLine line(is); - - ProgressData pd; - pd.sendTo( progress ); - pd.toMin(); - - bool pastDate = false; - for (; line; line.next(), pd.tick()) - { - const string & s = *line; - - // ignore comments - if (s[0] == '#') - continue; - - if (pastDate) - parseLine(s, line.lineNo()); - else - { - Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT); - if (logDate > date) - { - pastDate = true; - parseLine(s, line.lineNo()); - } - } - } - - pd.toMax(); - } - - void HistoryLogReader::Impl::readFromTo( - const Date & fromDate, const Date & toDate, - const ProgressData::ReceiverFnc & progress) - { - InputStream is(_filename); - iostr::EachLine line(is); - - ProgressData pd; - pd.sendTo(progress); - pd.toMin(); - - bool pastFromDate = false; - for (; line; line.next(), pd.tick()) - { - const string & s = *line; - - // ignore comments - if (s[0] == '#') - continue; - - Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT); - - // past toDate - stop reading - if (logDate >= toDate) - break; - - // past fromDate - start reading - if (!pastFromDate && logDate > fromDate) - pastFromDate = true; - - if (pastFromDate) - parseLine(s, line.lineNo()); - } - - pd.toMax(); - } +#endif // WITH_DEPRECATED_HISTORYITEM_API ///////////////////////////////////////////////////////////////////// // - // CLASS NAME: HistoryLogReader + // class HistoryLogReader // ///////////////////////////////////////////////////////////////////// +#if defined(WITH_DEPRECATED_HISTORYITEM_API) HistoryLogReader::HistoryLogReader( const Pathname & historyFile, const ProcessItem & callback ) - : _pimpl(new HistoryLogReader::Impl(historyFile, callback)) + : _pimpl(new HistoryLogReader::Impl( historyFile, Options(), ProcessData() ) ) + { _pimpl->_oldAPICallback = callback; } +#endif // WITH_DEPRECATED_HISTORYITEM_API + + HistoryLogReader::HistoryLogReader( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r ) + : _pimpl( new HistoryLogReader::Impl( historyFile_r, options_r, callback_r ) ) {} HistoryLogReader::~HistoryLogReader() {} - void HistoryLogReader::setIgnoreInvalidItems(bool ignoreInvalid) - { _pimpl->_ignoreInvalid = ignoreInvalid; } + void HistoryLogReader::setIgnoreInvalidItems( bool ignoreInvalid_r ) + { _pimpl->_options.setFlag( IGNORE_INVALID_ITEMS, ignoreInvalid_r ); } bool HistoryLogReader::ignoreInvalidItems() const - { return _pimpl->_ignoreInvalid; } - - void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress) - { _pimpl->readAll(progress); } + { return _pimpl->_options.testFlag( IGNORE_INVALID_ITEMS ); } - void HistoryLogReader::readFrom(const Date & date, - const ProgressData::ReceiverFnc & progress) - { _pimpl->readFrom(date, progress); } + void HistoryLogReader::readAll( const ProgressData::ReceiverFnc & progress_r ) + { _pimpl->readAll( progress_r ); } - void HistoryLogReader::readFromTo( - const Date & fromDate, const Date & toDate, - const ProgressData::ReceiverFnc & progress) - { _pimpl->readFromTo(fromDate, toDate, progress); } + void HistoryLogReader::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r ) + { _pimpl->readFrom( date_r, progress_r ); } + void HistoryLogReader::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r ) + { _pimpl->readFromTo( fromDate_r, toDate_r, progress_r ); } - ///////////////////////////////////////////////////////////////// } // namespace parser /////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-12.4.0/zypp/parser/HistoryLogReader.h new/libzypp-12.5.0/zypp/parser/HistoryLogReader.h --- old/libzypp-12.4.0/zypp/parser/HistoryLogReader.h 2012-11-23 18:11:08.000000000 +0100 +++ new/libzypp-12.5.0/zypp/parser/HistoryLogReader.h 2012-12-03 14:41:52.000000000 +0100 @@ -14,20 +14,26 @@ #define ZYPP_PARSER_HISTORYLOGREADER_H_ #include "zypp/base/PtrTypes.h" +#include "zypp/base/Flags.h" #include "zypp/ProgressData.h" #include "zypp/Pathname.h" #include "zypp/HistoryLogData.h" +#if defined(WITH_DEPRECATED_HISTORYITEM_API) +#warning Support for HistoryItem based parsing will be removed in the future. +#warning Switch to the new HistoryLogData based HistoryLogReader API. +#endif // WITH_DEPRECATED_HISTORYITEM_API + /////////////////////////////////////////////////////////////////// namespace zypp -{ ///////////////////////////////////////////////////////////////// +{ class Date; /////////////////////////////////////////////////////////////////// namespace parser - { ///////////////////////////////////////////////////////////////// + { /////////////////////////////////////////////////////////////////// /// \class HistoryLogReader @@ -35,42 +41,69 @@ /// \ingroup g_ZyppHistory /// \ingroup g_ZyppParser /// - /// Reads a zypp history log file and calls the ProcessItem function - /// passed in the constructor for each item read. + /// Reads a zypp history log file and calls the \ref ProcessData callback + /// passed in the constructor for each valid history line read. The callbacks + /// return value indicates whether to continue parsing. /// /// \code - /// struct HistoryItemCollector - /// { - /// vector<HistoryItem::Ptr> items; - /// - /// bool operator()( const HistoryItem::Ptr & item_ptr ) + /// std::vector<HistoryLogData::Ptr> history; + /// parser::HistoryLogReader parser( ZConfig::instance().historyLogFile(), + /// HistoryLogReader::Options(), + /// [&history]( HistoryLogData::Ptr ptr )->bool { + /// history.push_back( ptr ); + /// return true; + /// } ); + /// parser.readAll(); + /// ... + /// if ( history[0]->action() == HistoryActionID::INSTALL ) /// { - /// items.push_back(item_ptr); - /// return true; + /// // generic access to data fields plain string values: + /// MIL << (*p)[HistoryLogDataInstall::USERDATA_INDEX] << endl; + /// + /// // The same maybe more convenient though derived classes: + /// HistoryLogDataInstall::Ptr ip( dynamic_pointer_cast<HistoryLogDataInstall>( p ) ); + /// MIL << ip->userdata() << endl; /// } - /// } - /// ... - /// HistoryItemCollector ic; - /// HistoryLogReader reader("/var/log/zypp/history", boost::ref(ic)); + /// \endcode + /// \see \ref HistoryLogData for how to access the individual data fields. /// - /// try - /// { - /// reader.readAll(); - /// } - /// catch (const Exception & e) - /// { - /// cout << e.asUserHistory() << endl; - /// } +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + /// \note The old API based in HistoryItem instead of HistoryLogData + /// is deprecated and may vanish in the future. The new API no longer + /// allows direct access to data members, you have to call access methods + /// instead. + /// \code + /// - // old style + /// - HistoryItem::Ptr ptr; + /// - Date d = ptr->date; + /// + // new style + /// + HistoryLogData::Ptr ptr; + /// + Date d = ptr->date(); /// \endcode - ///////////////////////////////////////////////////////////////////// +#endif // WITH_DEPRECATED_HISTORYITEM_API + /////////////////////////////////////////////////////////////////// class HistoryLogReader { public: - typedef function< bool( const HistoryItem::Ptr & )> ProcessItem; + + enum OptionBits ///< Parser option flags + { + IGNORE_INVALID_ITEMS = (1 << 0) ///< ignore invalid items and continue parsing + }; + ZYPP_DECLARE_FLAGS( Options, OptionBits ); public: - HistoryLogReader( const Pathname & repo_file, - const ProcessItem & callback ); + /** Callback type to consume a single history line split into fields. + * The return value indicates whether to continue parsing. + */ + typedef function< bool( const HistoryLogData::Ptr & )> ProcessData; + + /** Ctor taking file to parse and data consumer callback. + * As \a options_r argument pass \c HistoryLogReader::Options() to + * use the default stettings, or an OR'ed combination of \ref OptionBits. + */ + HistoryLogReader( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r ); + ~HistoryLogReader(); /** @@ -78,8 +111,7 @@ * * \param progress An optional progress data receiver function. */ - void readAll( - const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + void readAll( const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); /** * Read log from specified \a date. @@ -89,8 +121,7 @@ * * \see readFromTo() */ - void readFrom( const Date & date, - const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + void readFrom( const Date & date, const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); /** * Read log between \a fromDate and \a toDate. @@ -111,8 +142,7 @@ * \param toDate Date on which to stop reading. * \param progress An optional progress data receiver function. */ - void readFromTo( const Date & fromDate, const Date & toDate, - const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + void readFromTo( const Date & fromDate, const Date & toDate, const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc() ); /** * Set the reader to ignore invalid log entries and continue with the rest. @@ -132,14 +162,26 @@ /** Implementation */ class Impl; RW_pointer<Impl,rw_pointer::Scoped<Impl> > _pimpl; + +#if defined(WITH_DEPRECATED_HISTORYITEM_API) + public: + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. */ + typedef function< bool( const HistoryItem::Ptr & )> ProcessItem; + /** \deprecated Old unextensible \ref zypp::parser::HistoryLogReader data class. + * They grant direct access to data members, so can not be extended + * without losing binary compatibility. + */ + HistoryLogReader( const Pathname & repo_file, const ProcessItem & callback ) ZYPP_DEPRECATED; +#endif // WITH_DEPRECATED_HISTORYITEM_API }; - /////////////////////////////////////////////////////////////////// + /** \relates HistoryLogReader::Options */ + ZYPP_DECLARE_OPERATORS_FOR_FLAGS( HistoryLogReader::Options ); + /////////////////////////////////////////////////////////////////// + + } // namespace parser ///////////////////////////////////////////////////////////////// -} // namespace parser -/////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// } // namespace zypp /////////////////////////////////////////////////////////////////// -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
