HistoryLogReader.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00013 #include <iostream>
00014
00015 #include "zypp/base/InputStream.h"
00016 #include "zypp/base/IOStream.h"
00017 #include "zypp/base/Logger.h"
00018 #include "zypp/parser/ParseException.h"
00019
00020 #include "zypp/parser/HistoryLogReader.h"
00021
00022 using namespace std;
00023
00025 namespace zypp
00026 {
00027
00028 namespace parser
00029 {
00030
00031
00033
00034
00035
00037
00038 struct HistoryLogReader::Impl
00039 {
00040 Impl( const Pathname & historyFile, const ProcessItem & callback );
00041 ~Impl()
00042 {}
00043
00044 HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields);
00045 void parseLine(const string & line, unsigned int lineNr);
00046
00047 void readAll(const ProgressData::ReceiverFnc & progress);
00048 void readFrom(const Date & date,
00049 const ProgressData::ReceiverFnc & progress);
00050 void readFromTo(
00051 const Date & fromDate, const Date & toDate,
00052 const ProgressData::ReceiverFnc & progress);
00053
00054 Pathname _filename;
00055 ProcessItem _callback;
00056 bool _ignoreInvalid;
00057 };
00058
00059 HistoryLogReader::Impl::Impl( const Pathname & historyFile,
00060 const ProcessItem & callback )
00061 : _filename(historyFile), _callback(callback), _ignoreInvalid(false)
00062 {}
00063
00064 HistoryItem::Ptr
00065 HistoryLogReader::Impl::createHistoryItem(HistoryItem::FieldVector & fields)
00066 {
00067 HistoryActionID aid(str::trim(fields[1]));
00068 switch (aid.toEnum())
00069 {
00070 case HistoryActionID::INSTALL_e:
00071 return HistoryItemInstall::Ptr(new HistoryItemInstall(fields));
00072 break;
00073
00074 case HistoryActionID::REMOVE_e:
00075 return HistoryItemRemove::Ptr(new HistoryItemRemove(fields));
00076 break;
00077
00078 case HistoryActionID::REPO_ADD_e:
00079 return HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields));
00080 break;
00081
00082 case HistoryActionID::REPO_REMOVE_e:
00083 return HistoryItemRepoRemove::Ptr(new HistoryItemRepoRemove(fields));
00084 break;
00085
00086 case HistoryActionID::REPO_CHANGE_ALIAS_e:
00087 return HistoryItemRepoAliasChange::Ptr(new HistoryItemRepoAliasChange(fields));
00088 break;
00089
00090 case HistoryActionID::REPO_CHANGE_URL_e:
00091 return HistoryItemRepoUrlChange::Ptr(new HistoryItemRepoUrlChange(fields));
00092 break;
00093
00094 default:
00095 WAR << "Unknown history log action type: " << fields[1] << endl;
00096 }
00097
00098 return HistoryItem::Ptr();
00099 }
00100
00101 void HistoryLogReader::Impl::parseLine(const string & line, unsigned int lineNr)
00102 {
00103 HistoryItem::FieldVector fields;
00104 HistoryItem::Ptr item_ptr;
00105
00106
00107 str::splitEscaped(line, back_inserter(fields), "|", true);
00108
00109 if (fields.size() <= 2)
00110 {
00111 ParseException
00112 e(str::form("Error in history log on line #%u.", lineNr));
00113 e.addHistory(
00114 str::form("Bad number of fields. Got %zd, expected more than %d.",
00115 fields.size(), 2));
00116 ZYPP_THROW(e);
00117 }
00118
00119 try
00120 {
00121 item_ptr = createHistoryItem(fields);
00122 }
00123 catch (const Exception & e)
00124 {
00125 ZYPP_CAUGHT(e);
00126 ERR << "Invalid history log entry on line #" << lineNr << ":" << endl
00127 << line << endl;
00128
00129 if (!_ignoreInvalid)
00130 {
00131 ParseException newe(
00132 str::form("Error in history log on line #%u.", lineNr ) );
00133 newe.remember(e);
00134 ZYPP_THROW(newe);
00135 }
00136 }
00137
00138 if (item_ptr)
00139 _callback(item_ptr);
00140 else if (!_ignoreInvalid)
00141 {
00142 ParseException
00143 e(str::form("Error in history log on line #%u.", lineNr));
00144 e.addHistory("Unknown entry type.");
00145 ZYPP_THROW(e);
00146 }
00147 }
00148
00149 void HistoryLogReader::Impl::readAll(const ProgressData::ReceiverFnc & progress)
00150 {
00151 InputStream is(_filename);
00152 iostr::EachLine line(is);
00153
00154 ProgressData pd;
00155 pd.sendTo( progress );
00156 pd.toMin();
00157
00158 for (; line; line.next(), pd.tick() )
00159 {
00160
00161 if ((*line)[0] == '#')
00162 continue;
00163
00164 parseLine(*line, line.lineNo());
00165 }
00166
00167 pd.toMax();
00168 }
00169
00170 void HistoryLogReader::Impl::readFrom(const Date & date,
00171 const ProgressData::ReceiverFnc & progress)
00172 {
00173 InputStream is(_filename);
00174 iostr::EachLine line(is);
00175
00176 ProgressData pd;
00177 pd.sendTo( progress );
00178 pd.toMin();
00179
00180 bool pastDate = false;
00181 for (; line; line.next(), pd.tick())
00182 {
00183 const string & s = *line;
00184
00185
00186 if (s[0] == '#')
00187 continue;
00188
00189 if (pastDate)
00190 parseLine(s, line.lineNo());
00191 else
00192 {
00193 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
00194 if (logDate > date)
00195 {
00196 pastDate = true;
00197 parseLine(s, line.lineNo());
00198 }
00199 }
00200 }
00201
00202 pd.toMax();
00203 }
00204
00205 void HistoryLogReader::Impl::readFromTo(
00206 const Date & fromDate, const Date & toDate,
00207 const ProgressData::ReceiverFnc & progress)
00208 {
00209 InputStream is(_filename);
00210 iostr::EachLine line(is);
00211
00212 ProgressData pd;
00213 pd.sendTo(progress);
00214 pd.toMin();
00215
00216 bool pastFromDate = false;
00217 for (; line; line.next(), pd.tick())
00218 {
00219 const string & s = *line;
00220
00221
00222 if (s[0] == '#')
00223 continue;
00224
00225 Date logDate(s.substr(0, s.find('|')), HISTORY_LOG_DATE_FORMAT);
00226
00227
00228 if (logDate >= toDate)
00229 break;
00230
00231
00232 if (!pastFromDate && logDate > fromDate)
00233 pastFromDate = true;
00234
00235 if (pastFromDate)
00236 parseLine(s, line.lineNo());
00237 }
00238
00239 pd.toMax();
00240 }
00241
00243
00244
00245
00247
00248 HistoryLogReader::HistoryLogReader( const Pathname & historyFile,
00249 const ProcessItem & callback )
00250 : _pimpl(new HistoryLogReader::Impl(historyFile, callback))
00251 {}
00252
00253 HistoryLogReader::~HistoryLogReader()
00254 {}
00255
00256 void HistoryLogReader::setIgnoreInvalidItems(bool ignoreInvalid)
00257 { _pimpl->_ignoreInvalid = ignoreInvalid; }
00258
00259 bool HistoryLogReader::ignoreInvalidItems() const
00260 { return _pimpl->_ignoreInvalid; }
00261
00262 void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress)
00263 { _pimpl->readAll(progress); }
00264
00265 void HistoryLogReader::readFrom(const Date & date,
00266 const ProgressData::ReceiverFnc & progress)
00267 { _pimpl->readFrom(date, progress); }
00268
00269 void HistoryLogReader::readFromTo(
00270 const Date & fromDate, const Date & toDate,
00271 const ProgressData::ReceiverFnc & progress)
00272 { _pimpl->readFromTo(fromDate, toDate, progress); }
00273
00274
00276 }
00279 }