HistoryLog reader:
[platform/upstream/libzypp.git] / zypp / parser / HistoryLogReader.cc
index 8309b54..e339a76 100644 (file)
@@ -31,16 +31,68 @@ namespace zypp
 
   /////////////////////////////////////////////////////////////////////
   //
-  // CLASS NAME: HistoryLogReader
+  // CLASS NAME: HistoryLogReader::Impl
   //
   /////////////////////////////////////////////////////////////////////
 
-  HistoryLogReader::HistoryLogReader( const Pathname & historyFile,
-                                      const ProcessItem & callback )
-    : _filename(historyFile), _callback(callback)
+  struct HistoryLogReader::Impl
+  {
+    Impl( const Pathname & historyFile, const ProcessItem & callback );
+    ~Impl()
+    {}
+
+    HistoryItem::Ptr createHistoryItem(HistoryItem::FieldVector & fields);
+
+    void readAll(const ProgressData::ReceiverFnc & progress);
+
+    Pathname _filename;
+    ProcessItem _callback;
+    bool _ignoreInvalid;
+  };
+
+  HistoryLogReader::Impl::Impl( const Pathname & historyFile,
+                                const ProcessItem & callback )
+    : _filename(historyFile), _callback(callback), _ignoreInvalid(false)
   {}
 
-  void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress)
+  HistoryItem::Ptr
+  HistoryLogReader::Impl::createHistoryItem(HistoryItem::FieldVector & fields)
+  {
+    HistoryActionID aid(str::trim(fields[1]));
+    switch (aid.toEnum())
+    {
+    case HistoryActionID::INSTALL_e:
+        return HistoryItemInstall::Ptr(new HistoryItemInstall(fields));
+      break;
+
+    case HistoryActionID::REMOVE_e:
+      return HistoryItemRemove::Ptr(new HistoryItemRemove(fields));
+      break;
+
+    case HistoryActionID::REPO_ADD_e:
+      return HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields));
+      break;
+
+    case HistoryActionID::REPO_REMOVE_e:
+      return HistoryItemRepoRemove::Ptr(new HistoryItemRepoRemove(fields));
+      break;
+
+    case HistoryActionID::REPO_CHANGE_ALIAS_e:
+      return HistoryItemRepoAliasChange::Ptr(new HistoryItemRepoAliasChange(fields));
+      break;
+
+    case HistoryActionID::REPO_CHANGE_URL_e:
+      return HistoryItemRepoUrlChange::Ptr(new HistoryItemRepoUrlChange(fields));
+      break;
+
+    default:
+      WAR << "Unknown history log action type: " << fields[1] << endl;
+    }
+
+    return HistoryItem::Ptr();
+  }
+
+  void HistoryLogReader::Impl::readAll(const ProgressData::ReceiverFnc & progress)
   {
     InputStream is(_filename);
     iostr::EachLine line(is);
@@ -49,14 +101,15 @@ namespace zypp
     pd.sendTo( progress );
     pd.toMin();
 
-    for (; line; line.next(), pd.tick())
+    HistoryItem::FieldVector fields;
+    HistoryItem::Ptr item_ptr;
+    for (; line; line.next(), pd.tick(), fields.clear(), item_ptr.reset())
     {
       const string & s = *line;
       if (s[0] == '#') // ignore comments
         continue;
 
-      // determine action
-      HistoryItem::FieldVector fields;
+      // parse fields
       str::splitEscaped(s, back_inserter(fields), "|", true);
 
       if (fields.size() <= 2)
@@ -64,46 +117,33 @@ namespace zypp
           str::form("Bad number of fields. Got %ld, expected more than %d.",
             fields.size(), 2)));
 
-      // parse into the data structures
-      HistoryActionID aid(str::trim(fields[1]));
       try
       {
-        switch (aid.toEnum())
-        {
-        case HistoryActionID::INSTALL_e:
-            _callback(HistoryItemInstall::Ptr(new HistoryItemInstall(fields)));
-          break;
-
-        case HistoryActionID::REMOVE_e:
-          _callback(HistoryItemRemove::Ptr(new HistoryItemRemove(fields)));
-          break;
-
-        case HistoryActionID::REPO_ADD_e:
-          _callback(HistoryItemRepoAdd::Ptr(new HistoryItemRepoAdd(fields)));
-          break;
-
-        case HistoryActionID::REPO_REMOVE_e:
-          _callback(HistoryItemRepoRemove::Ptr(new HistoryItemRepoRemove(fields)));
-          break;
-
-        case HistoryActionID::REPO_CHANGE_ALIAS_e:
-          _callback(HistoryItemRepoAliasChange::Ptr(new HistoryItemRepoAliasChange(fields)));
-          break;
-
-        case HistoryActionID::REPO_CHANGE_URL_e:
-          _callback(HistoryItemRepoUrlChange::Ptr(new HistoryItemRepoUrlChange(fields)));
-          break;
+        item_ptr = createHistoryItem(fields);
+      }
+      catch (const Exception & e)
+      {
+        ZYPP_CAUGHT(e);
+        ERR << "Invalid history log entry on line #" << line.lineNo() << ":" << endl
+            << s << endl;
 
-        default:
-          WAR << "Unknown history log action type: " << fields[1] << endl;
+        if (!_ignoreInvalid)
+        {
+          ParseException newe(
+              str::form("Error in history log on line #%u.", line.lineNo() ) );
+          newe.remember(e);
+          ZYPP_THROW(newe);
         }
       }
-      catch (const Exception & e)
+
+      if (item_ptr)
+        _callback(item_ptr);
+      else if (!_ignoreInvalid)
       {
-        ParseException newe(
-            str::form("Error in history log on line #%u.", line.lineNo()));
-        newe.remember(e);
-        ZYPP_THROW(newe);
+        ParseException
+          e(str::form("Error in history log on line #%u.", line.lineNo()));
+        e.addHistory("Unknown entry type.");
+        ZYPP_THROW(e);
       }
     }
 
@@ -111,9 +151,29 @@ namespace zypp
   }
 
 
+  /////////////////////////////////////////////////////////////////////
+  //
+  // CLASS NAME: HistoryLogReader
+  //
+  /////////////////////////////////////////////////////////////////////
+
+  HistoryLogReader::HistoryLogReader( const Pathname & historyFile,
+                                      const ProcessItem & callback )
+    : _pimpl(new HistoryLogReader::Impl(historyFile, callback))
+  {}
+
   HistoryLogReader::~HistoryLogReader()
   {}
 
+  void HistoryLogReader::setIgnoreInvalidItems(bool ignoreInvalid)
+  { _pimpl->_ignoreInvalid = ignoreInvalid; }
+
+  bool HistoryLogReader::ignoreInvalidItems() const
+  { return _pimpl->_ignoreInvalid; }
+
+  void HistoryLogReader::readAll(const ProgressData::ReceiverFnc & progress)
+  { _pimpl->readAll(progress); }
+
 
     /////////////////////////////////////////////////////////////////
   } // namespace parser