libzypp 17.37.17
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 <utility>
16#include <zypp-core/base/InputStream>
17#include <zypp/base/IOStream.h>
18#include <zypp/base/Logger.h>
19#include <zypp-core/parser/ParseException>
20
22
23using std::endl;
24
26namespace zypp
27{
29 namespace parser
30 {
31
33 //
34 // class HistoryLogReader::Impl
35 //
38 {
39 Impl( Pathname &&historyFile_r, Options &&options_r, ProcessData &&callback_r )
40 : _filename( std::move(historyFile_r) )
41 , _options( std::move(options_r) )
42 , _callback( std::move(callback_r) )
43 {}
44
45 bool parseLine( const std::string & line_r, unsigned int lineNr_r );
46
47 void readAll( const ProgressData::ReceiverFnc & progress_r );
48 void readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r );
49 void readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r );
50
51 void addActionFilter( const HistoryActionID & action_r )
52 {
53 if ( action_r == HistoryActionID::NONE )
54 _actionfilter.clear();
55 else
56 _actionfilter.insert( action_r.asString() );
57 }
58
60 Options _options;
62 std::set<std::string> _actionfilter;
63 };
64
65 bool HistoryLogReader::Impl::parseLine( const std::string & line_r, unsigned lineNr_r )
66 {
67 // parse into fields
69 str::splitEscaped( line_r, std::back_inserter(fields), "|", true );
70
71 if ( fields.size() < 2 ) {
72 WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
73 return true; // At least an action field[1] is needed!
74 }
75 fields[1] = str::trim( std::move(fields[1]) ); // for whatever reason writer is padding the action field
76
77 if ( !_actionfilter.empty() && !_actionfilter.count( fields[1] ) )
78 return true;
79
80 // move into data class
82 try
83 {
84 data = HistoryLogData::create( fields );
85 }
86 catch ( const Exception & excpt )
87 {
88 ZYPP_CAUGHT( excpt );
89 if ( _options.testFlag( IGNORE_INVALID_ITEMS ) )
90 {
91 WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
92 return true;
93 }
94 else
95 {
96 ERR << "Invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
97 ParseException newexcpt( str::Str() << "Error in history log on line #" << lineNr_r );
98 newexcpt.remember( excpt );
99 ZYPP_THROW( newexcpt );
100 }
101 }
102
103 // consume data
104 if ( _callback && !_callback( data ) )
105 {
106 WAR << "Stop parsing requested by consumer callback on line #" << lineNr_r << endl;
107 return false;
108 }
109 return true;
110 }
111
113 {
115 iostr::EachLine line( is );
116
117 ProgressData pd;
118 pd.sendTo( progress_r );
119 pd.toMin();
120
121 for ( ; line; line.next(), pd.tick() )
122 {
123 // ignore comments
124 if ( (*line)[0] == '#' )
125 continue;
126
127 if ( ! parseLine( *line, line.lineNo() ) )
128 break; // requested by consumer callback
129 }
130
131 pd.toMax();
132 }
133
134 void HistoryLogReader::Impl::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
135 {
137 iostr::EachLine line( is );
138
139 ProgressData pd;
140 pd.sendTo( progress_r );
141 pd.toMin();
142
143 bool pastDate = false;
144 for ( ; line; line.next(), pd.tick() )
145 {
146 const std::string & s = *line;
147
148 // ignore comments
149 if ( s[0] == '#' )
150 continue;
151
152 if ( pastDate )
153 {
154 if ( ! parseLine( s, line.lineNo() ) )
155 break; // requested by consumer callback
156 }
157 else
158 {
159 Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
160 if ( logDate > date_r )
161 {
162 pastDate = true;
163 if ( ! parseLine( s, line.lineNo() ) )
164 break; // requested by consumer callback
165 }
166 }
167 }
168
169 pd.toMax();
170 }
171
172 void HistoryLogReader::Impl::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
173 {
175 iostr::EachLine line( is );
176
177 ProgressData pd;
178 pd.sendTo( progress_r );
179 pd.toMin();
180
181 bool pastFromDate = false;
182 for ( ; line; line.next(), pd.tick() )
183 {
184 const std::string & s = *line;
185
186 // ignore comments
187 if ( s[0] == '#' )
188 continue;
189
190 Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
191
192 // past toDate - stop reading
193 if ( logDate >= toDate_r )
194 break;
195
196 // past fromDate - start reading
197 if ( !pastFromDate && logDate > fromDate_r )
198 pastFromDate = true;
199
200 if ( pastFromDate )
201 {
202 if ( ! parseLine( s, line.lineNo() ) )
203 break; // requested by consumer callback
204 }
205 }
206
207 pd.toMax();
208 }
209
211 //
212 // class HistoryLogReader
213 //
215
216 HistoryLogReader::HistoryLogReader( Pathname historyFile_r, Options options_r, ProcessData callback_r )
217 : _pimpl( new HistoryLogReader::Impl( std::move(historyFile_r), std::move(options_r), std::move(callback_r) ) )
218 {}
219
222
223 void HistoryLogReader::setIgnoreInvalidItems( bool ignoreInvalid_r )
224 { _pimpl->_options.setFlag( IGNORE_INVALID_ITEMS, ignoreInvalid_r ); }
225
227 { return _pimpl->_options.testFlag( IGNORE_INVALID_ITEMS ); }
228
230 { _pimpl->readAll( progress_r ); }
231
232 void HistoryLogReader::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
233 { _pimpl->readFrom( date_r, progress_r ); }
234
235 void HistoryLogReader::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
236 { _pimpl->readFromTo( fromDate_r, toDate_r, progress_r ); }
237
239 { _pimpl->addActionFilter( action_r ); }
240
241 } // namespace parser
242
243} // 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:153
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
static Ptr create(FieldVector &fields_r)
Factory method creating HistoryLogData classes.
std::vector< std::string > FieldVector
shared_ptr< HistoryLogData > Ptr
Helper to create and pass std::istream.
Definition inputstream.h:57
Maintain [min,max] and counter (value) for progress counting.
bool tick()
Leave counter value unchanged (still alive).
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
bool toMax()
Set counter value to current max value (unless no range).
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
bool toMin()
Set counter value to current min value.
Simple lineparser: Traverse each line in a file.
Definition IOStream.h:113
unsigned lineNo() const
Return the current line number.
Definition IOStream.h:127
bool next()
Advance to next line.
Definition IOStream.cc:72
@ IGNORE_INVALID_ITEMS
ignore invalid items and continue parsing
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.
function< bool(const HistoryLogData::Ptr &)> ProcessData
Callback type to consume a single history line split into fields.
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(Pathname historyFile_r, zypp::parser::HistoryLogReader::Options options_r, 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.
Definition Arch.h:364
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:665
std::string trim(const std::string &s, const Trim trim_r)
Definition String.cc:226
Easy-to use interface to the ZYPP dependency resolver.
Enumeration of known history actions.
const std::string & asString(bool pad=false) const
void addActionFilter(const HistoryActionID &action_r)
Impl(Pathname &&historyFile_r, Options &&options_r, ProcessData &&callback_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)
void readAll(const ProgressData::ReceiverFnc &progress_r)
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101