libzypp 17.31.23
HistoryLogReader.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9
13#include <iostream>
14
15#include <zypp-core/base/InputStream>
16#include <zypp/base/IOStream.h>
17#include <zypp/base/Logger.h>
18#include <zypp-core/parser/ParseException>
19
21
22using std::endl;
23
25namespace zypp
26{
28 namespace parser
29 {
30
32 //
33 // class HistoryLogReader::Impl
34 //
37 {
38 Impl( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r )
39 : _filename( historyFile_r )
40 , _options( options_r )
41 , _callback( callback_r )
42 {}
43
44 bool parseLine( const std::string & line_r, unsigned int lineNr_r );
45
46 void readAll( const ProgressData::ReceiverFnc & progress_r );
47 void readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r );
48 void readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r );
49
50 void addActionFilter( const HistoryActionID & action_r )
51 {
52 if ( action_r == HistoryActionID::NONE )
53 _actionfilter.clear();
54 else
55 _actionfilter.insert( action_r.asString() );
56 }
57
59 Options _options;
61 std::set<std::string> _actionfilter;
62 };
63
64 bool HistoryLogReader::Impl::parseLine( const std::string & line_r, unsigned lineNr_r )
65 {
66 // parse into fields
68 str::splitEscaped( line_r, std::back_inserter(fields), "|", true );
69
70 if ( fields.size() < 2 ) {
71 WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
72 return true; // At least an action field[1] is needed!
73 }
74 fields[1] = str::trim( std::move(fields[1]) ); // for whatever reason writer is padding the action field
75
76 if ( !_actionfilter.empty() && !_actionfilter.count( fields[1] ) )
77 return true;
78
79 // move into data class
81 try
82 {
83 data = HistoryLogData::create( fields );
84 }
85 catch ( const Exception & excpt )
86 {
87 ZYPP_CAUGHT( excpt );
88 if ( _options.testFlag( IGNORE_INVALID_ITEMS ) )
89 {
90 WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
91 return true;
92 }
93 else
94 {
95 ERR << "Invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
96 ParseException newexcpt( str::Str() << "Error in history log on line #" << lineNr_r );
97 newexcpt.remember( excpt );
98 ZYPP_THROW( newexcpt );
99 }
100 }
101
102 // consume data
103 if ( _callback && !_callback( data ) )
104 {
105 WAR << "Stop parsing requested by consumer callback on line #" << lineNr_r << endl;
106 return false;
107 }
108 return true;
109 }
110
112 {
113 InputStream is( _filename );
114 iostr::EachLine line( is );
115
116 ProgressData pd;
117 pd.sendTo( progress_r );
118 pd.toMin();
119
120 for ( ; line; line.next(), pd.tick() )
121 {
122 // ignore comments
123 if ( (*line)[0] == '#' )
124 continue;
125
126 if ( ! parseLine( *line, line.lineNo() ) )
127 break; // requested by consumer callback
128 }
129
130 pd.toMax();
131 }
132
133 void HistoryLogReader::Impl::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
134 {
135 InputStream is( _filename );
136 iostr::EachLine line( is );
137
138 ProgressData pd;
139 pd.sendTo( progress_r );
140 pd.toMin();
141
142 bool pastDate = false;
143 for ( ; line; line.next(), pd.tick() )
144 {
145 const std::string & s = *line;
146
147 // ignore comments
148 if ( s[0] == '#' )
149 continue;
150
151 if ( pastDate )
152 {
153 if ( ! parseLine( s, line.lineNo() ) )
154 break; // requested by consumer callback
155 }
156 else
157 {
158 Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
159 if ( logDate > date_r )
160 {
161 pastDate = true;
162 if ( ! parseLine( s, line.lineNo() ) )
163 break; // requested by consumer callback
164 }
165 }
166 }
167
168 pd.toMax();
169 }
170
171 void HistoryLogReader::Impl::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
172 {
173 InputStream is( _filename );
174 iostr::EachLine line( is );
175
176 ProgressData pd;
177 pd.sendTo( progress_r );
178 pd.toMin();
179
180 bool pastFromDate = false;
181 for ( ; line; line.next(), pd.tick() )
182 {
183 const std::string & s = *line;
184
185 // ignore comments
186 if ( s[0] == '#' )
187 continue;
188
189 Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
190
191 // past toDate - stop reading
192 if ( logDate >= toDate_r )
193 break;
194
195 // past fromDate - start reading
196 if ( !pastFromDate && logDate > fromDate_r )
197 pastFromDate = true;
198
199 if ( pastFromDate )
200 {
201 if ( ! parseLine( s, line.lineNo() ) )
202 break; // requested by consumer callback
203 }
204 }
205
206 pd.toMax();
207 }
208
210 //
211 // class HistoryLogReader
212 //
214
215 HistoryLogReader::HistoryLogReader( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r )
216 : _pimpl( new HistoryLogReader::Impl( historyFile_r, options_r, callback_r ) )
217 {}
218
220 {}
221
222 void HistoryLogReader::setIgnoreInvalidItems( bool ignoreInvalid_r )
223 { _pimpl->_options.setFlag( IGNORE_INVALID_ITEMS, ignoreInvalid_r ); }
224
226 { return _pimpl->_options.testFlag( IGNORE_INVALID_ITEMS ); }
227
229 { _pimpl->readAll( progress_r ); }
230
231 void HistoryLogReader::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
232 { _pimpl->readFrom( date_r, progress_r ); }
233
234 void HistoryLogReader::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
235 { _pimpl->readFromTo( fromDate_r, toDate_r, progress_r ); }
236
238 { _pimpl->addActionFilter( action_r ); }
239
240 } // namespace parser
242} // namespace zypp
#define HISTORY_LOG_DATE_FORMAT
Store and operate on date (time_t).
Definition: Date.h:33
Base class for Exception.
Definition: Exception.h:146
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
shared_ptr< HistoryLogData > Ptr
static Ptr create(FieldVector &fields_r)
Factory method creating HistoryLogData classes.
std::vector< std::string > FieldVector
Helper to create and pass std::istream.
Definition: inputstream.h:57
Maintain [min,max] and counter (value) for progress counting.
Definition: progressdata.h:132
bool tick()
Leave counter value unchanged (still alive).
Definition: progressdata.h:280
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: progressdata.h:229
bool toMax()
Set counter value to current max value (unless no range).
Definition: progressdata.h:276
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: progressdata.h:140
bool toMin()
Set counter value to current min value.
Definition: progressdata.h:272
Simple lineparser: Traverse each line in a file.
Definition: IOStream.h:112
unsigned lineNo() const
Return the current line number.
Definition: IOStream.h:126
bool next()
Advance to next line.
Definition: IOStream.cc:72
Zypp history file parser.
@ IGNORE_INVALID_ITEMS
ignore invalid items and continue parsing
function< bool(const HistoryLogData::Ptr &)> ProcessData
Callback type to consume a single history line split into fields.
void setIgnoreInvalidItems(bool ignoreInvalid=false)
Set the reader to ignore invalid log entries and continue with the rest.
void readFrom(const Date &date, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read log from specified date.
void addActionFilter(const HistoryActionID &action_r)
Process only specific HistoryActionIDs.
bool ignoreInvalidItems() const
Whether the reader is set to ignore invalid log entries.
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
void readAll(const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read the whole log file.
HistoryLogReader(const Pathname &historyFile_r, const Options &options_r, const ProcessData &callback_r)
Ctor taking file to parse and data consumer callback.
void readFromTo(const Date &fromDate, const Date &toDate, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read log between fromDate and toDate.
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
Definition: String.h:595
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
Enumeration of known history actions.
const std::string & asString(bool pad=false) const
static const HistoryActionID NONE
std::set< std::string > _actionfilter
void addActionFilter(const HistoryActionID &action_r)
void readFromTo(const Date &fromDate_r, const Date &toDate_r, const ProgressData::ReceiverFnc &progress_r)
bool parseLine(const std::string &line_r, unsigned int lineNr_r)
void readFrom(const Date &date_r, const ProgressData::ReceiverFnc &progress_r)
Impl(const Pathname &historyFile_r, const Options &options_r, const ProcessData &callback_r)
void readAll(const ProgressData::ReceiverFnc &progress_r)
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define ERR
Definition: Logger.h:98
#define WAR
Definition: Logger.h:97