initial implementation of serialize/recovery PoolQuery (needed by FATE #120118)
authorJosef Reidinger <jreidinger@suse.cz>
Tue, 1 Apr 2008 14:14:13 +0000 (14:14 +0000)
committerJosef Reidinger <jreidinger@suse.cz>
Tue, 1 Apr 2008 14:14:13 +0000 (14:14 +0000)
VERSION.cmake
tests/zypp/PoolQuery_test.cc
tests/zypp/data/PoolQuery/savedqueries [new file with mode: 0644]
zypp/PoolQuery.cc
zypp/PoolQuery.h
zypp/PoolQueryUtil.h [new file with mode: 0644]

index fc40535..a010131 100644 (file)
@@ -45,6 +45,6 @@
 #
 
 SET(LIBZYPP_MAJOR "4")
-SET(LIBZYPP_MINOR "6")
+SET(LIBZYPP_MINOR "7")
 SET(LIBZYPP_COMPATMINOR "6")
-SET(LIBZYPP_PATCH "1")
+SET(LIBZYPP_PATCH "0")
index b7ce189..cbb4e2c 100644 (file)
@@ -1,9 +1,13 @@
 #include <stdio.h>
 #include <iostream>
+#include <iterator>
 #include <boost/test/auto_unit_test.hpp>
+#include <list>
 
 #include "zypp/ZYppFactory.h"
 #include "zypp/PoolQuery.h"
+#include "zypp/PoolQueryUtil.h"
+#include "zypp/TmpPath.h"
 
 #define BOOST_TEST_MODULE PoolQuery
 
@@ -43,4 +47,38 @@ BOOST_AUTO_TEST_CASE(pool_query)
 
   cout << "search done." << endl;
 #endif
+
+//test recovery from file
+  Pathname pathToQueries(TESTS_SRC_DIR);
+  pathToQueries += "/zypp/data/PoolQuery/savedqueries";
+
+  std::list<PoolQuery> savedQueries;
+
+  std::insert_iterator<std::list<PoolQuery> > ii(savedQueries, savedQueries.end());
+  readPoolQueriesFromFile(pathToQueries,ii);
+  BOOST_CHECK( savedQueries.size() == 2 );
+
+  filesystem::TmpFile tmp;
+  Pathname tmpPath = tmp.path();
+
+  savedQueries.clear();
+
+  PoolQuery q1;
+  PoolQuery q2;
+
+  q1.addKind( Resolvable::Kind::patch );
+  q2.addKind( Resolvable::Kind::patch );
+  q2.addKind( Resolvable::Kind::pattern );
+
+  savedQueries.push_front( q1 );
+  savedQueries.push_front( q2 );
+
+  writePoolQueriesToFile ( tmpPath, savedQueries.begin(), savedQueries.end() );
+  std::insert_iterator<std::list<PoolQuery> > ii2(savedQueries,
+      savedQueries.end());
+  //reread writed queries
+  readPoolQueriesFromFile( tmpPath, ii2);
+  //TODO test if 0==2 and 1==3
+  BOOST_CHECK( savedQueries.size() == 4 );
+
 }
diff --git a/tests/zypp/data/PoolQuery/savedqueries b/tests/zypp/data/PoolQuery/savedqueries
new file mode 100644 (file)
index 0000000..4662d2b
--- /dev/null
@@ -0,0 +1,5 @@
+#repo cannot be tested due to possibly missing allias
+kind: patch
+
+kind: product
+kind: pattern
index e5e1057..cea4e0d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/Solvable.h"
+#include "zypp/sat/SolvAttr.h"
 
 extern "C"
 {
@@ -198,6 +199,148 @@ namespace zypp
   {
     return str;
   }
+  
+
+  /**
+   * represents all atributes in PoolQuery except SolvAtributes, which is
+   * used as is (not needed extend anythink if someone add new solv attr)
+   */
+  struct PoolQueryAttr : public IdStringType<PoolQueryAttr>
+  {
+    private:
+      friend class IdStringType<PoolQueryAttr>;
+      IdString _str;
+
+    public:
+    
+    //noAttr
+    PoolQueryAttr():isSolvAttr(false){}
+
+    explicit PoolQueryAttr( const char* cstr_r )
+        : _str( cstr_r ),isSolvAttr(false){}
+
+    explicit PoolQueryAttr( const std::string & str_r )
+        : _str( str_r ),isSolvAttr(false)
+    {
+      if( _str==noAttr ){
+        sat::SolvAttr sa(str_r);
+        if( sa != sat::SolvAttr::noAttr )
+        {
+          isSolvAttr = true; 
+        }
+      }
+    }
+
+    //unknown atributes
+    static const PoolQueryAttr noAttr;
+
+    // own attributes
+    static const PoolQueryAttr nameAttr;
+    static const PoolQueryAttr repoAttr;
+    static const PoolQueryAttr kindAttr;
+
+    // exported attributes from SolvAtributes
+    bool isSolvAttr;
+  };
+
+  const PoolQueryAttr PoolQueryAttr::noAttr;
+
+  const PoolQueryAttr PoolQueryAttr::nameAttr( "name" );
+  const PoolQueryAttr PoolQueryAttr::repoAttr( "repo" );
+  const PoolQueryAttr PoolQueryAttr::kindAttr( "kind" );
+
+  //\TODO maybe ctor with stream can be usefull
+  bool PoolQuery::recover( istream &str, char delim )
+  {
+    bool finded_something = false; //indicates some atributes is finded
+    string s;
+    do {
+      if ( str.eof() )
+        break;
+
+      getline( str, s, delim );
+
+      if ((!s.empty()) && s[0]=='#') //comment
+      {
+        continue;
+      }
+
+      string::size_type pos = s.find(':');
+      if (s.empty() || pos == s.npos) // some garbage on line... act like blank line
+      {
+        if (finded_something) //is first blank line after record?
+        {
+          break;
+        }
+        else
+        {
+          continue;
+        }
+      }
+
+      finded_something = true;
+
+      string atrName(str::trim(string(s,0,pos))); // trimmed name of atribute
+      string atrValue(str::trim(string(s,pos+1,s.npos))); //trimmed value
+
+      PoolQueryAttr attribute( atrName );
+
+      if ( attribute==PoolQueryAttr::nameAttr)
+      {
+        //setName...maybe some regex test
+        break;
+      }
+      else if ( attribute==PoolQueryAttr::repoAttr )
+      {
+        addRepo( atrValue );
+      }
+      else if ( attribute==PoolQueryAttr::kindAttr )
+      {
+        addKind( Resolvable::Kind(atrValue) );
+      }
+      else if ( attribute==PoolQueryAttr::noAttr )
+      {
+        if (attribute.isSolvAttr)
+        {
+          //setAtribute
+        }
+        else
+        {
+          //log unknwon atribute
+        }
+      }
+      else
+      {
+        //some forget handle new atribute
+        ;
+      }
+      
+    } while ( true );
+
+    return finded_something;
+  }
+
+  void PoolQuery::serialize( ostream &str, char delim )
+  {
+    //separating delim
+    str << delim; 
+    //iterate thrue all settings and write it
+    
+    for_( it, _pimpl->_repos.begin(), _pimpl->_repos.end() )
+    {
+      str << "repo: " << *it << delim ;
+    }
+
+    for_( it, _pimpl->_kinds.begin(), _pimpl->_kinds.end() )
+    {
+      str << "kind: " << it->idStr() << delim ;
+    }
+
+    //separating delim - protection
+    str << delim; 
+
+  }
+     
 
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
index 68a3924..41b22ec 100644 (file)
@@ -173,6 +173,28 @@ namespace zypp
     
     // a forEach method consuming a functor can be added here, too
 
+    /**
+     * Reads from stream query. Attributes is sepated by delim. Query is 
+     * separated by two delim.
+     * 
+     * \param str input stream which contains query
+     * \param delim delimeter for attributes
+     * \return true if non-empty query is recovered
+     * 
+     * \see readPoolQueriesFromFile
+     */
+    bool recover( std::istream &str, char delim = '\n' );
+
+    /**
+     * Writes query to stream, As delimeter is used delim.
+     *
+     * \param str output stream for query
+     * \param delim delimeter for attributes
+     *
+     * \see writePoolQueriesToFile
+     */
+    void serialize( std::ostream &str, char delim = '\n' );
+
   public:
     class Impl;
   private:
@@ -181,6 +203,7 @@ namespace zypp
   };
 
 
+
 /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
diff --git a/zypp/PoolQueryUtil.h b/zypp/PoolQueryUtil.h
new file mode 100644 (file)
index 0000000..bb1727e
--- /dev/null
@@ -0,0 +1,59 @@
+// including fstream is not hell here because this header only included
+// by implementation file, header doesn't need include it
+// also that's why this file is not protected by IFNDEF (you get it
+// only when you explicitly need it in implementation)
+#include <fstream>
+
+#include "zypp/Pathname.h"
+#include "zypp/PoolQuery.h"
+  
+  /**
+   * sends to output iterator all queries readed from file.
+   *
+   * \code
+   *  list<PoolQuery> s;
+   *  insert_iterator<list<PoolQuery> > ii(s, s.end());
+   *  readPoolQueriesFromStream(f,ii);
+   * \endcode
+   */
+  template <class OutputIterator>
+  void readPoolQueriesFromFile(const zypp::filesystem::Pathname &file,
+      OutputIterator out )
+  {
+    bool found;
+    std::ifstream fin( file.c_str() );
+
+    if (!fin)
+      return; //TODO exception
+
+    do
+    {
+      zypp::PoolQuery q;
+      found = q.recover( fin );
+      if (found)
+        *out++ = q;
+    } while ( found );
+
+    fin.close();
+  }
+
+  /**
+   * Writes all queries from begin to end.
+   */
+
+  template <class InputIterator>
+  void writePoolQueriesToFile(const zypp::filesystem::Pathname &file,
+      InputIterator begin, InputIterator end )
+  {
+    std::ofstream fout( file.c_str(), std::ios_base::out | std::ios_base::trunc );
+
+    if (!fout)
+      return; //TODO exception
+
+    for_( it, begin, end )
+    {
+      it->serialize( fout );
+    }
+
+    fout.close();
+  }