libzypp  11.13.5
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 namespace std;
23 
25 namespace zypp
26 {
27 
28  namespace parser
29  {
30 
31 
33  //
34  // CLASS NAME: HistoryLogReader::Impl
35  //
37 
39  {
40  Impl( const Pathname & historyFile, const ProcessItem & callback );
41  ~Impl()
42  {}
43 
44  HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields);
45  void parseLine(const string & line, unsigned int lineNr);
46 
47  void readAll(const ProgressData::ReceiverFnc & progress);
48  void readFrom(const Date & date,
49  const ProgressData::ReceiverFnc & progress);
50  void readFromTo(
51  const Date & fromDate, const Date & toDate,
52  const ProgressData::ReceiverFnc & progress);
53 
54  Pathname _filename;
57  };
58 
59  HistoryLogReader::Impl::Impl( const Pathname & historyFile,
60  const ProcessItem & callback )
61  : _filename(historyFile), _callback(callback), _ignoreInvalid(false)
62  {}
63 
66  {
67  HistoryActionID aid(str::trim(fields[1]));
68  switch (aid.toEnum())
69  {
71  return HistoryItemInstall::Ptr(new HistoryItemInstall(fields));
72  break;
73 
75  return HistoryItemRemove::Ptr(new HistoryItemRemove(fields));
76  break;
77 
79  return HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields));
80  break;
81 
84  break;
85 
88  break;
89 
92  break;
93 
94  default:
95  WAR << "Unknown history log action type: " << fields[1] << endl;
96  }
97 
98  return HistoryItem::Ptr();
99  }
100 
101  void HistoryLogReader::Impl::parseLine(const string & line, unsigned int lineNr)
102  {
104  HistoryItem::Ptr item_ptr;
105 
106  // parse into fields
107  str::splitEscaped(line, back_inserter(fields), "|", true);
108 
109  if (fields.size() <= 2)
110  {
112  e(str::form("Error in history log on line #%u.", lineNr));
113  e.addHistory(
114  str::form("Bad number of fields. Got %zd, expected more than %d.",
115  fields.size(), 2));
116  ZYPP_THROW(e);
117  }
118 
119  try
120  {
121  item_ptr = createHistoryItem(fields);
122  }
123  catch (const Exception & e)
124  {
125  ZYPP_CAUGHT(e);
126  ERR << "Invalid history log entry on line #" << lineNr << ":" << endl
127  << line << endl;
128 
129  if (!_ignoreInvalid)
130  {
131  ParseException newe(
132  str::form("Error in history log on line #%u.", lineNr ) );
133  newe.remember(e);
134  ZYPP_THROW(newe);
135  }
136  }
137 
138  if (item_ptr)
139  _callback(item_ptr);
140  else if (!_ignoreInvalid)
141  {
143  e(str::form("Error in history log on line #%u.", lineNr));
144  e.addHistory("Unknown entry type.");
145  ZYPP_THROW(e);
146  }
147  }
148 
150  {
151  InputStream is(_filename);
152  iostr::EachLine line(is);
153 
154  ProgressData pd;
155  pd.sendTo( progress );
156  pd.toMin();
157 
158  for (; line; line.next(), pd.tick() )
159  {
160  // ignore comments
161  if ((*line)[0] == '#')
162  continue;
163 
164  parseLine(*line, line.lineNo());
165  }
166 
167  pd.toMax();
168  }
169 
171  const ProgressData::ReceiverFnc & progress)
172  {
173  InputStream is(_filename);
174  iostr::EachLine line(is);
175 
176  ProgressData pd;
177  pd.sendTo( progress );
178  pd.toMin();
179 
180  bool pastDate = false;
181  for (; line; line.next(), pd.tick())
182  {
183  const string & s = *line;
184 
185  // ignore comments
186  if (s[0] == '#')
187  continue;
188 
189  if (pastDate)
190  parseLine(s, line.lineNo());
191  else
192  {
193  Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
194  if (logDate > date)
195  {
196  pastDate = true;
197  parseLine(s, line.lineNo());
198  }
199  }
200  }
201 
202  pd.toMax();
203  }
204 
206  const Date & fromDate, const Date & toDate,
207  const ProgressData::ReceiverFnc & progress)
208  {
209  InputStream is(_filename);
210  iostr::EachLine line(is);
211 
212  ProgressData pd;
213  pd.sendTo(progress);
214  pd.toMin();
215 
216  bool pastFromDate = false;
217  for (; line; line.next(), pd.tick())
218  {
219  const string & s = *line;
220 
221  // ignore comments
222  if (s[0] == '#')
223  continue;
224 
225  Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
226 
227  // past toDate - stop reading
228  if (logDate >= toDate)
229  break;
230 
231  // past fromDate - start reading
232  if (!pastFromDate && logDate > fromDate)
233  pastFromDate = true;
234 
235  if (pastFromDate)
236  parseLine(s, line.lineNo());
237  }
238 
239  pd.toMax();
240  }
241 
243  //
244  // CLASS NAME: HistoryLogReader
245  //
247 
248  HistoryLogReader::HistoryLogReader( const Pathname & historyFile,
249  const ProcessItem & callback )
250  : _pimpl(new HistoryLogReader::Impl(historyFile, callback))
251  {}
252 
254  {}
255 
257  { _pimpl->_ignoreInvalid = ignoreInvalid; }
258 
260  { return _pimpl->_ignoreInvalid; }
261 
263  { _pimpl->readAll(progress); }
264 
265  void HistoryLogReader::readFrom(const Date & date,
266  const ProgressData::ReceiverFnc & progress)
267  { _pimpl->readFrom(date, progress); }
268 
270  const Date & fromDate, const Date & toDate,
271  const ProgressData::ReceiverFnc & progress)
272  { _pimpl->readFromTo(fromDate, toDate, progress); }
273 
274 
276  } // namespace parser
279 } // namespace zypp