SolvIdentFile: Save and restore a list of solvable names
authorMichael Andres <ma@suse.de>
Wed, 23 Apr 2014 09:11:07 +0000 (11:11 +0200)
committerMichael Andres <ma@suse.de>
Wed, 23 Apr 2014 11:28:05 +0000 (13:28 +0200)
zypp/CMakeLists.txt
zypp/target/SolvIdentFile.cc [new file with mode: 0644]
zypp/target/SolvIdentFile.h [new file with mode: 0644]

index de601e3..fd6dfcd 100644 (file)
@@ -571,6 +571,7 @@ INSTALL(  FILES
 SET( zypp_target_SRCS
   target/RpmPostTransCollector.cc
   target/RequestedLocalesFile.cc
+  target/SolvIdentFile.cc
   target/HardLocksFile.cc
   target/CommitPackageCache.cc
   target/CommitPackageCacheImpl.cc
@@ -585,6 +586,7 @@ SET( zypp_target_SRCS
 SET( zypp_target_HEADERS
   target/RpmPostTransCollector.h
   target/RequestedLocalesFile.h
+  target/SolvIdentFile.h
   target/HardLocksFile.h
   target/CommitPackageCache.h
   target/CommitPackageCacheImpl.h
diff --git a/zypp/target/SolvIdentFile.cc b/zypp/target/SolvIdentFile.cc
new file mode 100644 (file)
index 0000000..f09074a
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/target/SolvIdentFile.cc
+ *
+*/
+#include <iostream>
+#include <fstream>
+
+#include "zypp/base/LogTools.h"
+#include "zypp/base/IOStream.h"
+#include "zypp/base/String.h"
+
+#include "zypp/PathInfo.h"
+#include "zypp/TmpPath.h"
+#include "zypp/Date.h"
+
+#include "zypp/target/SolvIdentFile.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace target
+  { /////////////////////////////////////////////////////////////////
+
+    void SolvIdentFile::load( const Pathname & file_r, Data & data_r )
+    {
+      PathInfo pi( file_r );
+      if ( ! pi.isFile() )
+      {
+        WAR << "Can't read " << pi << endl;
+        return;
+      }
+      std::ifstream infile( file_r.c_str() );
+      for( iostr::EachLine in( infile ); in; in.next() )
+      {
+        std::string l( str::trim(*in) );
+        if ( ! l.empty() && l[0] != '#' )
+        {
+          data_r.insert( IdString(l) );
+        }
+      }
+      MIL << "Read " << pi << endl;
+    }
+
+    void SolvIdentFile::store( const Pathname & file_r, const Data & data_r )
+    {
+      filesystem::TmpFile tmp( filesystem::TmpFile::makeSibling( file_r ) );
+      filesystem::chmod( tmp.path(), 0644 );
+
+      std::ofstream outs( tmp.path().c_str() );
+      outs << "# " << file_r.basename() << " generated " << Date::now() << endl;
+      dumpRange( outs, data_r.begin(), data_r.end(), "#", "\n", "\n", "\n", "#\n" );
+      outs.close();
+
+      if ( outs.good() )
+      {
+        filesystem::rename( tmp.path(), file_r );
+        MIL << "Wrote " << PathInfo(file_r) << endl;
+      }
+      else
+      {
+        ERR << "Can't write " << PathInfo(tmp.path()) << endl;
+      }
+    }
+
+    /******************************************************************
+    **
+    ** FUNCTION NAME : operator<<
+    ** FUNCTION TYPE : std::ostream &
+    */
+    std::ostream & operator<<( std::ostream & str, const SolvIdentFile & obj )
+    {
+      str << obj.file() << ' ';
+      if ( obj._dataPtr )
+        str << obj.data();
+      else
+        str << "(unloaded)";
+      return str;
+    }
+
+    /////////////////////////////////////////////////////////////////
+  } // namespace target
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/target/SolvIdentFile.h b/zypp/target/SolvIdentFile.h
new file mode 100644 (file)
index 0000000..b44e2dd
--- /dev/null
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/target/SolvIdentFile.h
+ *
+*/
+#ifndef ZYPP_TARGET_SOLVIDENTFILE_H
+#define ZYPP_TARGET_SOLVIDENTFILE_H
+
+#include <iosfwd>
+
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/IdString.h"
+#include "zypp/Pathname.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace target
+  { /////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    /// \class SolvIdentFile
+    /// \short Save and restore a list of solvable names (ident IdString)
+    ///////////////////////////////////////////////////////////////////
+    class SolvIdentFile
+    {
+      friend std::ostream & operator<<( std::ostream & str, const SolvIdentFile & obj );
+      public:
+        typedef std::tr1::unordered_set<IdString> Data;
+
+      public:
+        /** Ctor taking the file to read/write. */
+        SolvIdentFile( const Pathname & file_r )
+        : _file( file_r )
+        {}
+
+        /** Return the file path. */
+        const Pathname & file() const
+        { return _file; }
+
+        /** Return the data.
+         * The file is read once on demand. Returns empty \ref Data if
+         * the file does not exist or is not readable.
+        */
+        const Data & data() const
+        {
+          if ( !_dataPtr )
+          {
+            _dataPtr.reset( new Data );
+            Data & mydata( *_dataPtr );
+            load( _file, mydata );
+          }
+          return *_dataPtr;
+        }
+
+        /** Store new \ref Data.
+         * Write the new \ref Data to file, unless we know it
+         * did not change. The directory containing file must
+         * exist.
+        */
+        void setData( const Data & data_r )
+        {
+          if ( !_dataPtr )
+            _dataPtr.reset( new Data );
+
+          if ( differs( *_dataPtr, data_r ) )
+          {
+            store( _file, data_r );
+            *_dataPtr = data_r;
+          }
+        }
+
+      private:
+        /** Helper testing whether two \ref Data differ. */
+        bool differs( const Data & lhs, const Data & rhs ) const
+        {
+
+          if ( lhs.size() != rhs.size() )
+            return true;
+          for_( it, lhs.begin(), lhs.end() )
+          {
+            if ( rhs.find( *it ) == rhs.end() )
+              return true;
+          }
+          return false;
+        }
+        /** Read \ref Data from \c file_r. */
+        static void load( const Pathname & file_r, Data & data_r );
+        /** Write \ref Data to \c file_r. */
+        static void store( const Pathname & file_r, const Data & data_r );
+
+      private:
+        Pathname                 _file;
+        mutable scoped_ptr<Data> _dataPtr;
+    };
+    ///////////////////////////////////////////////////////////////////
+
+    /** \relates SolvIdentFile Stream output */
+    std::ostream & operator<<( std::ostream & str, const SolvIdentFile & obj );
+
+    /////////////////////////////////////////////////////////////////
+  } // namespace target
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_TARGET_SOLVIDENTFILE_H