- add reverse lookup for CacheTypes
authorKlaus Kaempf <kkaempf@suse.de>
Fri, 17 Aug 2007 09:44:37 +0000 (09:44 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Fri, 17 Aug 2007 09:44:37 +0000 (09:44 +0000)
- fill kind and repository from 'resolvables' select
- implement interateResolvablesByKind
- rename queryByName to iterateResolvablesByName

zypp/cache/CacheTypes.cc
zypp/cache/CacheTypes.h
zypp/cache/ResolvableQuery.cc
zypp/cache/ResolvableQuery.h

index 30be871..3fbeb48 100644 (file)
@@ -93,6 +93,17 @@ namespace zypp
       return rel;
     
     }
+
+    data::RecordId CacheTypes::idForRelation( const Rel &rel )
+    {
+      std::map<data::RecordId, Rel>::const_iterator it;
+      for ( it = _rel_cache.begin(); it != _rel_cache.end(); ++it )
+      {
+        if ( rel == it->second )
+         return it->first;
+      }
+      ZYPP_THROW(Exception("Inconsistent Rel"));   
+    }
     
     Resolvable::Kind CacheTypes::kindFor( const data::RecordId &id )
     {
@@ -105,6 +116,17 @@ namespace zypp
       
       return kind;
     }
+
+    data::RecordId CacheTypes::idForKind( const Resolvable::Kind & kind )
+    {
+      std::map<data::RecordId, Resolvable::Kind>::const_iterator it;
+      for ( it = _kind_cache.begin(); it != _kind_cache.end(); ++it )
+      {
+        if ( kind == it->second )
+         return it->first;
+      }
+      ZYPP_THROW(Exception("Inconsistent Kind"));   
+    }
     
     Dep CacheTypes::deptypeFor( const data::RecordId &id )
     {
@@ -117,6 +139,17 @@ namespace zypp
         ZYPP_THROW(Exception("Inconsistent deptype"));
       }
     }
+
+    data::RecordId CacheTypes::idForDeptype( const Dep & dep )
+    {
+      std::map<data::RecordId, string>::const_iterator it;
+      for ( it = _deptype_cache.begin(); it != _deptype_cache.end(); ++it )
+      {
+        if ( dep.asString() == it->second )
+         return it->first;
+      }
+      ZYPP_THROW(Exception("Inconsistent deptype"));   
+    }
     
     Arch CacheTypes::archFor( const data::RecordId &id )
     {
@@ -131,6 +164,18 @@ namespace zypp
       return arch;
     }
 
+    data::RecordId CacheTypes::idForArch( const Arch & arch )
+    {
+      std::map<data::RecordId, Arch>::const_iterator it;
+      for ( it = _arch_cache.begin(); it != _arch_cache.end(); ++it )
+      {
+        if ( arch == it->second )
+         return it->first;
+      }
+      ZYPP_THROW(Exception("Inconsistent Arch"));   
+    }
+
+
 
     ///////////////////////////////////////////////////////////////////
     //
index 36dc27d..7158789 100644 (file)
@@ -67,6 +67,15 @@ namespace zypp
       Rel relationFor( const data::RecordId &id );
       
       /**
+       * Cache record id for Relation
+       *
+       * \param rel relation
+       *
+       * \throws Exception if the Relation is not valid
+       */
+      data::RecordId idForRelation( const Rel &rel );
+      
+      /**
        * Kind for a cache record id.
        *
        * \param id The id you got in a cache query
@@ -74,6 +83,15 @@ namespace zypp
        * \throws Exception if the id is not a valid type
        */
       Resolvable::Kind kindFor( const data::RecordId &id );
+
+      /**
+       * Cache record id for Kind
+       *
+       * \param kind Kind
+       *
+       * \throws Exception if the Kind is not valid
+       */
+      data::RecordId idForKind( const Resolvable::Kind & kind );
       
       /**
        * Dependency type for a cache record id.
@@ -85,6 +103,15 @@ namespace zypp
       Dep deptypeFor( const data::RecordId &id );
       
       /**
+       * Cache record id for Dep type
+       *
+       * \param dep Dep
+       *
+       * \throws Exception if the Dep is not valid
+       */
+      data::RecordId idForDeptype( const Dep & dep );
+      
+      /**
        * Architecture for a cache record id.
        *
        * \param id The id you got in a cache query
@@ -93,6 +120,15 @@ namespace zypp
        */
       Arch archFor( const data::RecordId &id );
       
+      /**
+       * Cache record id for Arch
+       *
+       * \param arch Arch
+       *
+       * \throws Exception if the Arch is not valid
+       */
+      data::RecordId idForArch( const Arch & arch );
+      
     public:
 
     private:
index 75da55f..96db1ff 100644 (file)
@@ -43,6 +43,7 @@ struct ResolvableQuery::Impl
     _cmd_disk_usage.reset( new sqlite3_command( _con, "select d.name,du.size,du.files from resolvable_disk_usage du,dir_names d where du.resolvable_id=:rid and du.dir_name_id=d.id;"));
     
     MIL << "Creating Resolvable query impl" << endl;
+    //         0   1     2        3        4      5     6     7               8             9             10          11            12
     _fields = "id, name, version, release, epoch, arch, kind, installed_size, archive_size, install_only, build_time, install_time, repository_id";
   }
 
@@ -51,13 +52,32 @@ struct ResolvableQuery::Impl
       MIL << "Destroying Resolvable query impl" << endl;
   }
 
+  //
+  // convert regex ? and * operators to sql _ and % respectively
+  //  example: regex2sql( "*foo?bar*" ) => "%foo_bar%"
+  std::string regex2sql( const std::string & s)
+  {
+    std::string sql( s );
+    string::iterator it;
+    for (it = sql.begin(); it != sql.end(); ++it)
+    {
+      if (*it == '*') *it = '%';
+      else if (*it == '?') *it = '_';
+    }
+    return sql;
+  }
+
   data::ResObject_Ptr fromRow( sqlite3_reader &reader )
   {
     data::ResObject_Ptr ptr (new data::ResObject);
 
+    // see _fields definition above for the getXXX() numbers
+
     ptr->name = reader.getstring(1);
     ptr->edition = Edition( reader.getstring(2), reader.getstring(3), reader.getint(4));
     ptr->arch = _type_cache.archFor(reader.getint(5));
+    ptr->kind = _type_cache.kindFor( reader.getint(6) );
+    ptr->repository = reader.getint( 12 );
 
     // TODO get the rest of the data
 
@@ -83,7 +103,7 @@ struct ResolvableQuery::Impl
   {  
     
     sqlite3_command cmd( _con, "select " + _fields + " from resolvables where name like :name;");
-    cmd.bind(":name", string("%") + s + "%");
+    cmd.bind( ":name", regex2sql( s ) );
     sqlite3_reader reader = cmd.executereader();
     while(reader.read())
     {
@@ -91,7 +111,7 @@ struct ResolvableQuery::Impl
     }
   }
 
-  void queryByName( const std::string &name, int wild, ProcessResolvable fnc  )
+  void iterateResolvablesByName( const std::string &name, int wild, ProcessResolvable fnc  )
   {
     std::string sqlcmd = "select " + _fields + " from resolvables where name ";
     std::string s( name );
@@ -102,6 +122,7 @@ struct ResolvableQuery::Impl
     else
     {
       sqlcmd += "like";
+      s = regex2sql( s );
     }
     sqlite3_command cmd( _con, sqlcmd + " :name;");
     if (wild & 1)
@@ -190,6 +211,20 @@ struct ResolvableQuery::Impl
     return alias;
   }
   
+  void iterateResolvablesByKind( zypp::Resolvable::Kind kind, ProcessResolvable fnc )
+  {
+    sqlite3_command cmd( _con, "select " + _fields + " from resolvables where kind=:kind;");
+    data::RecordId kind_id = _type_cache.idForKind( kind );
+    cmd.bind(":kind", kind_id);
+    sqlite3_reader reader = cmd.executereader();
+    while(reader.read())
+    {
+      fnc( reader.getint64(0), fromRow(reader) );
+    }
+  }
+  
+
+
 private:
 
   int queryNumericAttributeInternal( sqlite3_connection &con,
@@ -365,9 +400,14 @@ std::string ResolvableQuery::queryRepositoryAlias( const data::RecordId &repo_id
   return _pimpl->queryRepositoryAlias( repo_id );
 }
 
-void ResolvableQuery::queryByName( const std::string &name, int wild, ProcessResolvable fnc  )
+void ResolvableQuery::iterateResolvablesByKind( zypp::Resolvable::Kind kind, ProcessResolvable fnc )
+{
+  return _pimpl->iterateResolvablesByKind( kind, fnc );
+}
+
+void ResolvableQuery::iterateResolvablesByName( const std::string &name, int wild, ProcessResolvable fnc  )
 {
-  _pimpl->queryByName( name, wild, fnc );
+  _pimpl->iterateResolvablesByName( name, wild, fnc );
 }
 
 //////////////////////////////////////////////////////////////////////////////
index eaf92db..891ed26 100644 (file)
@@ -72,7 +72,7 @@ namespace zypp
 
       /**
       * Query by matching text
-      * \param text text to match
+      * \param text text to match, wildcard operators like * and ? are allowed
       * \param fnc callback to send the data to. (Will be called once per result)
       */
       void query( const std::string &text,
@@ -228,13 +228,25 @@ namespace zypp
 
       /**
       * Query by matching name
-      * \param name name to match
-      * \param wild 0 = no wild, 1 = trailing wild, 2 = leading wild, 3 = trailing & leading wild
+      * \param name name to match, wildcard operators like * and ? are allowed if 'wild' param != 0
+      * \param wild append wildcard operators ?: 0 = no, 1 = trailing wild, 2 = leading wild, 3 = trailing & leading wild, 4 = name contains wildcards
       * \param fnc callback to send the data to. (Will be called once per result)
+      *
+      * Examples:
+      *   iterateByName( "kernel", 0, cb ) => look for resovables matching "kernel" exactly
+      *   iterateByName( "kernel", 1, cb ) => look for resovables starting with "kernel" (wildcard operator will be appendend)
+      *   iterateByName( "devel", 2, cb ) => look for resovables ending in "devel" (wildcard operator will be prependend)
+      *   iterateByName( "foo??", 1, cb ) => look for resovables starting with "foo" and at least 5 characters
+      *   iterateByName( "fo*o", 4, cb ) => look for resovables matching "fo*o"
       */
-      void queryByName( const std::string &name, int wild,
+      void iterateResolvablesByName( const std::string &name, int wild,
                   ProcessResolvable fnc  );
 
+      /**
+       * \short Iterate resolvables by Kind
+       */
+      void iterateResolvablesByKind( zypp::Resolvable::Kind kind, ProcessResolvable fnc );
+
     private:
       /** Implementation. */
       class Impl;