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 )
{
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 )
{
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 )
{
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"));
+ }
+
+
///////////////////////////////////////////////////////////////////
//
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
* \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.
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
*/
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:
_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";
}
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
{
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())
{
}
}
- 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 );
else
{
sqlcmd += "like";
+ s = regex2sql( s );
}
sqlite3_command cmd( _con, sqlcmd + " :name;");
if (wild & 1)
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,
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 );
}
//////////////////////////////////////////////////////////////////////////////
/**
* 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,
/**
* 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;