libzypp  17.1.1
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/base/InputStream.h"
16 #include "zypp/base/IOStream.h"
17 #include "zypp/base/Logger.h"
19 
21 
22 using std::endl;
23 
25 namespace 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 
51  Options _options;
53  };
54 
55  bool HistoryLogReader::Impl::parseLine( const std::string & line_r, unsigned lineNr_r )
56  {
57  // parse into fields
59  str::splitEscaped( line_r, std::back_inserter(fields), "|", true );
60  if ( fields.size() >= 2 )
61  str::trim( fields[1] ); // for whatever reason writer is padding the action field
62 
63  // move into data class
65  try
66  {
67  data = HistoryLogData::create( fields );
68  }
69  catch ( const Exception & excpt )
70  {
71  ZYPP_CAUGHT( excpt );
72  if ( _options.testFlag( IGNORE_INVALID_ITEMS ) )
73  {
74  WAR << "Ignore invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
75  return true;
76  }
77  else
78  {
79  ERR << "Invalid history log entry on line #" << lineNr_r << " '"<< line_r << "'" << endl;
80  ParseException newexcpt( str::Str() << "Error in history log on line #" << lineNr_r );
81  newexcpt.remember( excpt );
82  ZYPP_THROW( newexcpt );
83  }
84  }
85 
86  // consume data
87  if ( _callback && !_callback( data ) )
88  {
89  WAR << "Stop parsing requested by consumer callback on line #" << lineNr_r << endl;
90  return false;
91  }
92  return true;
93  }
94 
96  {
97  InputStream is( _filename );
98  iostr::EachLine line( is );
99 
100  ProgressData pd;
101  pd.sendTo( progress_r );
102  pd.toMin();
103 
104  for ( ; line; line.next(), pd.tick() )
105  {
106  // ignore comments
107  if ( (*line)[0] == '#' )
108  continue;
109 
110  if ( ! parseLine( *line, line.lineNo() ) )
111  break; // requested by consumer callback
112  }
113 
114  pd.toMax();
115  }
116 
117  void HistoryLogReader::Impl::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
118  {
119  InputStream is( _filename );
120  iostr::EachLine line( is );
121 
122  ProgressData pd;
123  pd.sendTo( progress_r );
124  pd.toMin();
125 
126  bool pastDate = false;
127  for ( ; line; line.next(), pd.tick() )
128  {
129  const std::string & s = *line;
130 
131  // ignore comments
132  if ( s[0] == '#' )
133  continue;
134 
135  if ( pastDate )
136  {
137  if ( ! parseLine( s, line.lineNo() ) )
138  break; // requested by consumer callback
139  }
140  else
141  {
142  Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
143  if ( logDate > date_r )
144  {
145  pastDate = true;
146  if ( ! parseLine( s, line.lineNo() ) )
147  break; // requested by consumer callback
148  }
149  }
150  }
151 
152  pd.toMax();
153  }
154 
155  void HistoryLogReader::Impl::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
156  {
157  InputStream is( _filename );
158  iostr::EachLine line( is );
159 
160  ProgressData pd;
161  pd.sendTo( progress_r );
162  pd.toMin();
163 
164  bool pastFromDate = false;
165  for ( ; line; line.next(), pd.tick() )
166  {
167  const std::string & s = *line;
168 
169  // ignore comments
170  if ( s[0] == '#' )
171  continue;
172 
173  Date logDate( s.substr( 0, s.find('|') ), HISTORY_LOG_DATE_FORMAT );
174 
175  // past toDate - stop reading
176  if ( logDate >= toDate_r )
177  break;
178 
179  // past fromDate - start reading
180  if ( !pastFromDate && logDate > fromDate_r )
181  pastFromDate = true;
182 
183  if ( pastFromDate )
184  {
185  if ( ! parseLine( s, line.lineNo() ) )
186  break; // requested by consumer callback
187  }
188  }
189 
190  pd.toMax();
191  }
192 
194  //
195  // class HistoryLogReader
196  //
198 
199  HistoryLogReader::HistoryLogReader( const Pathname & historyFile_r, const Options & options_r, const ProcessData & callback_r )
200  : _pimpl( new HistoryLogReader::Impl( historyFile_r, options_r, callback_r ) )
201  {}
202 
204  {}
205 
206  void HistoryLogReader::setIgnoreInvalidItems( bool ignoreInvalid_r )
207  { _pimpl->_options.setFlag( IGNORE_INVALID_ITEMS, ignoreInvalid_r ); }
208 
210  { return _pimpl->_options.testFlag( IGNORE_INVALID_ITEMS ); }
211 
213  { _pimpl->readAll( progress_r ); }
214 
215  void HistoryLogReader::readFrom( const Date & date_r, const ProgressData::ReceiverFnc & progress_r )
216  { _pimpl->readFrom( date_r, progress_r ); }
217 
218  void HistoryLogReader::readFromTo( const Date & fromDate_r, const Date & toDate_r, const ProgressData::ReceiverFnc & progress_r )
219  { _pimpl->readFromTo( fromDate_r, toDate_r, progress_r ); }
220 
221  } // namespace parser
223 } // namespace zypp
void readFrom(const Date &date_r, const ProgressData::ReceiverFnc &progress_r)
std::vector< std::string > FieldVector
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
Definition: String.h:578
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: ProgressData.h:226
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
bool next()
Advance to next line.
Definition: IOStream.cc:72
Impl(const Pathname &historyFile_r, const Options &options_r, const ProcessData &callback_r)
Zypp history file parserReads a zypp history log file and calls the ProcessData callback passed in th...
void readAll(const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read the whole log file.
unsigned lineNo() const
Return the current line number.
Definition: IOStream.h:126
void setIgnoreInvalidItems(bool ignoreInvalid=false)
Set the reader to ignore invalid log entries and continue with the rest.
bool toMax()
Set counter value to current max value (unless no range).
Definition: ProgressData.h:273
Helper to create and pass std::istream.
Definition: InputStream.h:56
Simple lineparser: Traverse each line in a file.
Definition: IOStream.h:111
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
#define ERR
Definition: Logger.h:66
function< bool(const HistoryLogData::Ptr &)> ProcessData
Callback type to consume a single history line split into fields.
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
bool toMin()
Set counter value to current min value.
Definition: ProgressData.h:269
Store and operate on date (time_t).
Definition: Date.h:32
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:210
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:221
ignore invalid items and continue parsing
#define WAR
Definition: Logger.h:65
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:130
HistoryLogReader(const Pathname &historyFile_r, const Options &options_r, const ProcessData &callback_r)
Ctor taking file to parse and data consumer callback.
void readAll(const ProgressData::ReceiverFnc &progress_r)
static Ptr create(FieldVector &fields_r)
Factory method creating HistoryLogData classes.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
void readFrom(const Date &date, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read log from specified date.
Base class for Exception.
Definition: Exception.h:145
bool tick()
Leave counter value unchanged (still alive).
Definition: ProgressData.h:277
#define HISTORY_LOG_DATE_FORMAT
void readFromTo(const Date &fromDate, const Date &toDate, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Read log between fromDate and toDate.
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
bool ignoreInvalidItems() const
Whether the reader is set to ignore invalid log entries.
shared_ptr< HistoryLogData > Ptr
bool parseLine(const std::string &line_r, unsigned int lineNr_r)
void readFromTo(const Date &fromDate_r, const Date &toDate_r, const ProgressData::ReceiverFnc &progress_r)