1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
10 /** \file HistoryLogReader.cc
15 #include "zypp/base/InputStream.h"
16 #include "zypp/base/IOStream.h"
17 #include "zypp/base/Logger.h"
18 #include "zypp/parser/ParseException.h"
20 #include "zypp/parser/HistoryLogReader.h"
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
32 /////////////////////////////////////////////////////////////////////
34 // CLASS NAME: HistoryLogReader::Impl
36 /////////////////////////////////////////////////////////////////////
38 struct HistoryLogReader::Impl
40 Impl( const Pathname & historyFile, const ProcessItem & callback );
44 HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields);
45 void parseLine(const string & line, unsigned int lineNr);
47 void readAll(const ProgressData::ReceiverFnc & progress);
48 void readFrom(const Date & date,
49 const ProgressData::ReceiverFnc & progress);
51 const Date & fromDate, const Date & toDate,
52 const ProgressData::ReceiverFnc & progress);
55 ProcessItem _callback;
59 HistoryLogReader::Impl::Impl( const Pathname & historyFile,
60 const ProcessItem & callback )
61 : _filename(historyFile), _callback(callback), _ignoreInvalid(false)
65 HistoryLogReader::Impl::createHistoryItem(HistoryItem::FieldVector & fields)
67 HistoryActionID aid(str::trim(fields[1]));
70 case HistoryActionID::INSTALL_e:
71 return HistoryItemInstall::Ptr(new HistoryItemInstall(fields));
74 case HistoryActionID::REMOVE_e:
75 return HistoryItemRemove::Ptr(new HistoryItemRemove(fields));
78 case HistoryActionID::REPO_ADD_e:
79 return HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields));
82 case HistoryActionID::REPO_REMOVE_e:
83 return HistoryItemRepoRemove::Ptr(new HistoryItemRepoRemove(fields));
86 case HistoryActionID::REPO_CHANGE_ALIAS_e:
87 return HistoryItemRepoAliasChange::Ptr(new HistoryItemRepoAliasChange(fields));
90 case HistoryActionID::REPO_CHANGE_URL_e:
91 return HistoryItemRepoUrlChange::Ptr(new HistoryItemRepoUrlChange(fields));
95 WAR << "Unknown history log action type: " << fields[1] << endl;
98 return HistoryItem::Ptr();
101 void HistoryLogReader::Impl::parseLine(const string & line, unsigned int lineNr)
103 HistoryItem::FieldVector fields;
104 HistoryItem::Ptr item_ptr;
107 str::splitEscaped(line, back_inserter(fields), "|", true);
109 if (fields.size() <= 2)
112 e(str::form("Error in history log on line #%u.", lineNr));
114 str::form("Bad number of fields. Got %zd, expected more than %d.",
121 item_ptr = createHistoryItem(fields);
123 catch (const Exception & e)
126 ERR << "Invalid history log entry on line #" << lineNr << ":" << endl
132 str::form("Error in history log on line #%u.", lineNr ) );
140 else if (!_ignoreInvalid)
143 e(str::form("Error in history log on line #%u.", lineNr));
144 e.addHistory("Unknown entry type.");
149 void HistoryLogReader::Impl::readAll(const ProgressData::ReceiverFnc & progress)
151 InputStream is(_filename);
152 iostr::EachLine line(is);
155 pd.sendTo( progress );
158 for (; line; line.next(), pd.tick() )
161 if ((*line)[0] == '#')
164 parseLine(*line, line.lineNo());
170 void HistoryLogReader::Impl::readFrom(const Date & date,
171 const ProgressData::ReceiverFnc & progress)
173 InputStream is(_filename);
174 iostr::EachLine line(is);
177 pd.sendTo( progress );
180 bool pastDate = false;
181 for (; line; line.next(), pd.tick())
183 const string & s = *line;
190 parseLine(s, line.lineNo());
193 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
197 parseLine(s, line.lineNo());
205 void HistoryLogReader::Impl::readFromTo(
206 const Date & fromDate, const Date & toDate,
207 const ProgressData::ReceiverFnc & progress)
209 InputStream is(_filename);
210 iostr::EachLine line(is);
216 bool pastFromDate = false;
217 for (; line; line.next(), pd.tick())
219 const string & s = *line;
225 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
227 // past toDate - stop reading
228 if (logDate >= toDate)
231 // past fromDate - start reading
232 if (!pastFromDate && logDate > fromDate)
236 parseLine(s, line.lineNo());
242 /////////////////////////////////////////////////////////////////////
244 // CLASS NAME: HistoryLogReader
246 /////////////////////////////////////////////////////////////////////
248 HistoryLogReader::HistoryLogReader( const Pathname & historyFile,
249 const ProcessItem & callback )
250 : _pimpl(new HistoryLogReader::Impl(historyFile, callback))
253 HistoryLogReader::~HistoryLogReader()
256 void HistoryLogReader::setIgnoreInvalidItems(bool ignoreInvalid)
257 { _pimpl->_ignoreInvalid = ignoreInvalid; }
259 bool HistoryLogReader::ignoreInvalidItems() const
260 { return _pimpl->_ignoreInvalid; }
262 void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress)
263 { _pimpl->readAll(progress); }
265 void HistoryLogReader::readFrom(const Date & date,
266 const ProgressData::ReceiverFnc & progress)
267 { _pimpl->readFrom(date, progress); }
269 void HistoryLogReader::readFromTo(
270 const Date & fromDate, const Date & toDate,
271 const ProgressData::ReceiverFnc & progress)
272 { _pimpl->readFromTo(fromDate, toDate, progress); }
275 /////////////////////////////////////////////////////////////////
276 } // namespace parser
277 ///////////////////////////////////////////////////////////////////
278 /////////////////////////////////////////////////////////////////
280 ///////////////////////////////////////////////////////////////////