- FilelistsFileReader complete
authorJan Kupec <jkupec@suse.cz>
Mon, 21 May 2007 02:02:35 +0000 (02:02 +0000)
committerJan Kupec <jkupec@suse.cz>
Mon, 21 May 2007 02:02:35 +0000 (02:02 +0000)
- YUMParser changed to use ResolvableDataConsumer iface instead of
  CacheStore

devel/devel.jkupec/YUMParser.cc
devel/devel.jkupec/YUMParser.h
devel/devel.jkupec/YUMParser_test.cc
zypp/CMakeLists.txt
zypp/data/ResolvableData.h
zypp/data/ResolvableDataConsumer.h
zypp/parser/yum/FilelistsFileReader.cc [new file with mode: 0644]
zypp/parser/yum/FilelistsFileReader.h [new file with mode: 0644]
zypp2/cache/CacheStore.cpp
zypp2/cache/CacheStore.h

index ad97c89..d1cc85e 100644 (file)
@@ -16,6 +16,7 @@
 #include "zypp/parser/yum/PatchesFileReader.h"
 #include "zypp/parser/yum/PatchFileReader.h"
 #include "zypp/parser/yum/OtherFileReader.h"
+#include "zypp/parser/yum/FilelistsFileReader.h"
 
 #include "YUMParser.h"
 
@@ -38,16 +39,16 @@ namespace zypp
     return true;
   }
 
+
   YUMParser::YUMParser(
-      const zypp::data::RecordId &catalog_id,
-      zypp::cache::CacheStore &consumer,
+      const data::RecordId & catalog_id,
+      data::ResolvableDataConsumer & consumer,
       const ProgressData::ReceiverFnc & progress)
     :
       _consumer(consumer), _catalog_id(catalog_id)
   {
     _ticks.name("YUMParser");
     _ticks.sendTo(progress);
-    MIL << "constructed" << endl;
   }
 
 
@@ -61,6 +62,7 @@ namespace zypp
     return true;
   }
 
+
   bool YUMParser::primary_CB(const data::Package_Ptr & package_r)
   {
     _consumer.consumePackage( _catalog_id, package_r );
@@ -114,6 +116,21 @@ namespace zypp
   }
 
 
+  bool YUMParser::filelist_CB(const data::Resolvable_Ptr & res_ptr, const data::Filenames & filenames)
+  {
+    _consumer.consumeFilelist(_catalog_id, res_ptr, filenames);
+/*
+    DBG << "got filelist for "
+      << res_ptr->name << res_ptr->edition << " "
+      << res_ptr->arch
+      << endl;
+
+    DBG << "last entry: " << filenames.front() << endl;
+*/
+    return true;
+  }
+
+
   void YUMParser::start(const Pathname &cache_dir)
   {
     zypp::parser::yum::RepomdFileReader(
@@ -178,6 +195,15 @@ namespace zypp
           break;
         }
 
+        case YUMResourceType::FILELISTS_e:
+        {
+          zypp::parser::yum::FilelistsFileReader(
+            cache_dir + job.filename(),
+            bind(&YUMParser::filelist_CB, this, _1, _2),
+            &progress_function);
+          break;
+        }
+
         default:
         {
           WAR << "Don't know how to read "
index c1a6fb9..ce16b83 100644 (file)
@@ -11,7 +11,7 @@
 #define YUMPARSER_H_
 
 #include "zypp/base/Logger.h"
-#include "zypp2/cache/CacheStore.h"
+#include "zypp/data/ResolvableDataConsumer.h"
 #include "zypp/data/ResolvableData.h"
 #include "zypp/source/yum/YUMResourceType.h"
 #include "zypp/ProgressData.h"
@@ -27,8 +27,9 @@ namespace zypp
     namespace yum
     {
 
+
   /**
-   * 
+   * Structure encapsulating YUM parser data type and filename.
    */
   struct YUMParserJob
   {
@@ -39,7 +40,9 @@ namespace zypp
     const YUMResourceType & type() const { return _type; } 
 
   private:
+    /** File to be processed */
     Pathname _filename;
+    /** Type of YUM file */
     YUMResourceType _type;
   };
 
@@ -51,8 +54,8 @@ namespace zypp
   {
   public:
     YUMParser(
-      const zypp::data::RecordId & catalog_id,
-      zypp::cache::CacheStore & consumer,
+      const data::RecordId & catalog_id,
+      data::ResolvableDataConsumer & consumer,
       const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc()
     );
 
@@ -66,17 +69,18 @@ namespace zypp
     bool patches_CB(const OnMediaLocation &loc, const std::string & patch_id);
     bool patch_CB(const data::Patch_Ptr & patch);
     bool other_CB(const data::Resolvable_Ptr & res_ptr, const Changelog & changelog);
+    bool filelist_CB(const data::Resolvable_Ptr & res_ptr, const data::Filenames & filenames);
 
   private:
-    zypp::cache::CacheStore & _consumer;
-    
+    data::ResolvableDataConsumer & _consumer;
+
     /** ID of the repository record in the DB (catalogs.id) */
-    zypp::data::RecordId _catalog_id;
+    data::RecordId _catalog_id;
 
     /** List of parser jobs read from repomd.xml and patches.xml files. */
     std::list<YUMParserJob> _jobs;
 
-    /** Progress reporting object. */
+    /** Progress reporting object for overall YUM parser progress. */
     ProgressData _ticks;
   };
 
@@ -88,3 +92,4 @@ namespace zypp
 #endif /*YUMPARSER_H_*/
 
 // vim: set ts=2 sts=2 sw=2 et ai:
+
index d334775..d4b2a07 100644 (file)
@@ -2,10 +2,9 @@
 #include "zypp/ZYppFactory.h"
 #include "zypp/base/Logger.h"
 #include "zypp/base/LogControl.h"
-#include "zypp/parser/yum/PrimaryFileReader.h"
-#include "YUMParser.h"
-#include "zypp/parser/ParserProgress.h"
 #include "zypp/base/Measure.h"
+#include "zypp2/cache/CacheStore.h"
+#include "YUMParser.h"
 
 
 
index 5b96ee7..51e6559 100644 (file)
@@ -555,6 +555,7 @@ SET( zypp_parser_yum_SRCS
   parser/yum/PatchesFileReader.cc
   parser/yum/PrimaryFileReader.cc
   parser/yum/OtherFileReader.cc
+  parser/yum/FilelistsFileReader.cc
   parser/yum/PatchFileReader.cc
 )
 
@@ -575,6 +576,7 @@ SET( zypp_parser_yum_HEADERS
   parser/yum/PatchesFileReader.h
   parser/yum/PrimaryFileReader.h
   parser/yum/OtherFileReader.h
+  parser/yum/FilelistsFileReader.h
   parser/yum/PatchFileReader.h
   parser/yum/schemanames.h
 )
index a80edac..de05d8b 100644 (file)
@@ -42,6 +42,10 @@ namespace data
 
   typedef DefaultIntegral<unsigned,0u>              MediaNr;
 
+  /** List of files contained in a package (info for UI) */
+  typedef std::list<std::string>                    Filenames;
+
+
   /** Data to retrieve a file from some media. */
   struct Location
   {
index af0b313..69b343d 100644 (file)
@@ -34,7 +34,8 @@ namespace data
     virtual void consumeMessage( const data::RecordId &catalog_id, data::Message_Ptr ) = 0;
     virtual void consumeScript( const data::RecordId &catalog_id, data::Script_Ptr ) = 0;
 
-    virtual void consumeChangelog( const data::RecordId &catalog_id, data::Resolvable_Ptr, Changelog ) = 0;
+    virtual void consumeChangelog( const data::RecordId & catalog_id, const data::Resolvable_Ptr &, const Changelog & ) = 0;
+    virtual void consumeFilelist( const data::RecordId & catalog_id, const data::Resolvable_Ptr &, const data::Filenames & ) = 0;
 
     //virtual void consumeSourcePackage( const data::SrcPackage_Ptr ) = 0;
   };
diff --git a/zypp/parser/yum/FilelistsFileReader.cc b/zypp/parser/yum/FilelistsFileReader.cc
new file mode 100644 (file)
index 0000000..b5d2498
--- /dev/null
@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+
+#include <fstream>
+
+#include "zypp/parser/yum/FilelistsFileReader.h"
+
+#undef ZYPP_BASE_LOGGER_LOGGROUP
+#define ZYPP_BASE_LOGGER_LOGGROUP "parser"
+
+using namespace std;
+using namespace zypp::xml;
+
+namespace zypp
+{
+  namespace parser
+  {
+    namespace yum
+    {
+
+
+  // --------------------------------------------------------------------------
+
+  /*
+   * xpath and multiplicity of processed nodes are included in the code
+   * for convenience:
+   *
+   * // xpath: <xpath> (?|*|+)
+   *
+   * if multiplicity is ommited, then the node has multiplicity 'one'.
+   */
+
+  // --------------------------------------------------------------------------
+
+  FilelistsFileReader::FilelistsFileReader(
+      const Pathname & filelist_file,
+      const ProcessPackage & callback,
+      const ProgressData::ReceiverFnc & progress)
+    :
+      _callback(callback)
+  {
+    _ticks.sendTo(progress);
+    _ticks.name("filelist.xml.gz");
+
+    Reader reader(filelist_file);
+    MIL << "Reading " << filelist_file << endl;
+    reader.foreachNode(bind(&FilelistsFileReader::consumeNode, this, _1));
+  }
+
+  // --------------------------------------------------------------------------
+
+  bool FilelistsFileReader::consumeNode(Reader & reader_r)
+  {
+    if (reader_r->nodeType() == XML_READER_TYPE_ELEMENT)
+    {
+      // xpath: /filelists
+      if (reader_r->name() == "filelists")
+      {
+        unsigned total_packages;
+        zypp::str::strtonum(reader_r->getAttribute("packages").asString(), total_packages);
+        _ticks.range(total_packages);
+        _ticks.toMin();
+        return true;
+      }
+
+      // xpath: /filelists/package (+)
+      if (reader_r->name() == "package")
+      {
+        _resolvable = new data::Resolvable;
+        _filenames.clear();
+
+        _resolvable->name = reader_r->getAttribute("name").asString();
+        _resolvable->arch = Arch(reader_r->getAttribute("arch").asString());
+
+        return true;
+      }
+
+      // xpath: /filelists/package/version
+      if (reader_r->name() == "version")
+      {
+        _resolvable->edition = Edition(reader_r->getAttribute("ver").asString(),
+                                    reader_r->getAttribute("rel").asString(),
+                                    reader_r->getAttribute("epoch").asString());
+        return true;
+      }
+
+      // xpath: /filelists/package/file (*)
+      if (reader_r->name() == "file")
+      {
+        // ignoring type dir/ghost  reader_r->getAttribute("type").asString();
+        _filenames.push_back(reader_r.nodeText().asString());
+        return true;
+      }
+    }
+
+    else if (reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT)
+    {
+      // xpath: /filelists/package
+      if (reader_r->name() == "package")
+      {
+        if (_callback && !_filenames.empty())
+          _callback(handoutResolvable(), _filenames);
+
+        _ticks.incr();
+
+        return true;
+      }
+
+      // xpath: /filelists
+      if (reader_r->name() == "filelists")
+      {
+        _ticks.toMax();
+        return true;
+      }
+    }
+
+    return true;
+  }
+
+  // --------------------------------------------------------------------------
+
+  data::Resolvable_Ptr FilelistsFileReader::handoutResolvable()
+  {
+    data::Resolvable_Ptr ret;
+    ret.swap(_resolvable);
+    return ret;
+  }
+
+
+    } // ns yum
+  } // ns parser
+} // ns zypp
+
+// vim: set ts=2 sts=2 sw=2 et ai:
+
diff --git a/zypp/parser/yum/FilelistsFileReader.h b/zypp/parser/yum/FilelistsFileReader.h
new file mode 100644 (file)
index 0000000..ca9c241
--- /dev/null
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+
+#ifndef FILELISTFILEREADER_H_
+#define FILELISTFILEREADER_H_
+
+#include "zypp/base/Function.h"
+#include "zypp/base/Logger.h"
+#include "zypp/parser/xml/Reader.h"
+#include "zypp/data/ResolvableData.h"
+#include "zypp/ProgressData.h"
+
+namespace zypp
+{
+  namespace parser
+  {
+    namespace yum
+    {
+
+
+  /**
+   * Reads through a filelists.xml.gz file and collects list of file contained
+   * in packages.
+   *
+   * After each package is read, a \ref data::Resolvable
+   * and \ref data::Filenames is prepared and \ref _callback
+   * is called with these two objects passed in.
+   *
+   * The \ref _callback is provided on construction.
+   *
+   * \code
+   * FilelistsFileReader reader(filelists_file,
+   *                        bind(&SomeClass::callbackfunc, &SomeClassInstance, _1, _2));
+   * \endcode
+   */
+  class FilelistsFileReader
+  {
+  public:
+    /**
+     * Callback definition.
+     */
+    typedef function<bool(const data::Resolvable_Ptr &, const data::Filenames &)> ProcessPackage;
+
+    /**
+     * Constructor
+     * \param filelists_file the filelists.xml.gz file you want to read
+     * \param callback function to process \ref _resolvable data.
+     * \param progress progress reporting object
+     *
+     * \see FilelistsFileReader::ProcessPackage
+     */
+    FilelistsFileReader(
+      const Pathname & filelists_file,
+      const ProcessPackage & callback,
+      const ProgressData::ReceiverFnc & progress = ProgressData::ReceiverFnc());
+
+  private:
+
+    /**
+     * Callback provided to the XML parser.
+     */
+    bool consumeNode(xml::Reader & reader_r);
+
+    /**
+     * Creates a new \ref data::Resolvable_Ptr, swaps its contents with
+     * \ref _resolvable and returns it. Used to hand-out the data object to its consumer
+     * (a \ref ProcessPackage function) after it has been read.
+     */
+    data::Resolvable_Ptr handoutResolvable();
+
+  private:
+
+    /**
+     * Pointer to the \ref zypp::data::Resolvable object for storing the NVRA
+     * data.
+     */
+    zypp::data::Resolvable_Ptr _resolvable;
+
+    /**
+     * Changelog of \ref _resolvable.
+     */
+    data::Filenames _filenames;
+
+    /**
+     * Callback for processing package metadata passed in through constructor.
+     */
+    ProcessPackage _callback;
+
+    /**
+     * Progress reporting object.
+     */
+    ProgressData _ticks;
+  };
+
+
+    } // ns zypp
+  } // ns parser
+} // ns yum
+
+#endif /*FILELISTFILEREADER_H_*/
+
+// vim: set ts=2 sts=2 sw=2 et ai:
index 5780301..b004ebc 100644 (file)
@@ -264,7 +264,7 @@ void CacheStore::consumeProduct( const data::RecordId &catalog_id, data::Product
   consumeResObject( id, product );
 }
 
-void CacheStore::consumeChangelog( const data::RecordId &catalog_id, data::Resolvable_Ptr resolvable, Changelog changelog )
+void CacheStore::consumeChangelog( const data::RecordId &catalog_id, const data::Resolvable_Ptr & resolvable, const Changelog & changelog )
 {
   // TODO
   // maybe consumeChangelog(const data::RecordId & resolvable_id, Changelog changelog) will
@@ -272,6 +272,14 @@ void CacheStore::consumeChangelog( const data::RecordId &catalog_id, data::Resol
   // resolvable. (first, we'll see how fast is the inserting without remembering those ids)
 }
 
+void CacheStore::consumeFilelist( const data::RecordId &catalog_id, const data::Resolvable_Ptr & resolvable, const data::Filenames & filenames )
+{
+  // TODO
+  // maybe consumeFilelist(const data::RecordId & resolvable_id, data::Filenames &) will
+  // be needed
+}
+
+
 void CacheStore::consumeResObject( const data::RecordId &rid, data::ResObject_Ptr res )
 {
   appendTranslatedStringAttribute( rid, "ResObject", "description", res->description );
index 3e08a5e..a758575 100644 (file)
@@ -131,7 +131,17 @@ namespace zypp
        * \param resolvable resolvable for which the changelog data are to be saved
        * \param changelog  the changelog
       */
-      virtual void consumeChangelog( const data::RecordId &catalog_id, data::Resolvable_Ptr resolvable, Changelog changelog );
+      virtual void consumeChangelog( const data::RecordId &catalog_id, const data::Resolvable_Ptr & resolvable, const Changelog & changelog );
+
+      /**
+       * Implementation of the \ref ResolvableConsumer interface
+       *
+       * Consume filelist of a resolvable, inserting it in the cache.
+       * \param catalog_id ownership.
+       * \param resolvable resolvable for which the filelist is to be saved
+       * \param filenames  list of filenames the resolvable contains
+      */
+      virtual void consumeFilelist( const data::RecordId &catalog_id, const data::Resolvable_Ptr & resolvable, const data::Filenames & filenames );
 
       /**
        * Appends a resolvable to the store.