sqlite3_command_ptr _cmd_attr_tstr;
sqlite3_command_ptr _cmd_attr_num;
sqlite3_command_ptr _cmd_disk_usage;
+ sqlite3_command_ptr _cmd_shared_id;
Impl( const Pathname &dbdir)
: _dbdir(dbdir)
_con.open((dbdir + "zypp.db").asString().c_str());
_con.executenonquery("PRAGMA cache_size=8000;");
+ _cmd_shared_id.reset( new sqlite3_command( _con, "select shared_id from resolvables where id=:rid;") );
+
_cmd_attr_tstr.reset( new sqlite3_command( _con, "select a.text, l.name from text_attributes a,types l,types t where a.weak_resolvable_id=:rid and a.lang_id=l.id and a.attr_id=t.id and l.class=:lclass and t.class=:tclass and t.name=:tname;") );
_cmd_attr_num.reset( new sqlite3_command( _con, "select a.value from numeric_attributes a,types t where a.weak_resolvable_id=:rid and a.attr_id=t.id and t.class=:tclass and t.name=:tname;"));
_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%"
+ // FIXME: take care of ".*" and "."
+ 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->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
return ptr;
}
-
+
void query( const data::RecordId &id,
ProcessResolvable fnc )
{
- sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
- //con.executenonquery("PRAGMA cache_size=8000;");
- con.executenonquery("BEGIN;");
- sqlite3_command cmd( con, "select " + _fields + " from resolvables where id=:id;");
+ sqlite3_command cmd( _con, "select " + _fields + " from resolvables where id=:id;");
cmd.bind(":id", id);
sqlite3_reader reader = cmd.executereader();
while(reader.read())
{
fnc( id, fromRow(reader) );
}
- con.executenonquery("COMMIT;");
}
void query( const std::string &s,
ProcessResolvable fnc )
- {
-
- sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
- //con.executenonquery("PRAGMA cache_size=8000;");
- con.executenonquery("BEGIN;");
- sqlite3_command cmd( con, "select " + _fields + " from resolvables where name like '%:name%';");
- cmd.bind(":name", s);
+ {
+
+ sqlite3_command cmd( _con, "select " + _fields + " from resolvables where name like :name;");
+ cmd.bind( ":name", regex2sql( s ) );
sqlite3_reader reader = cmd.executereader();
while(reader.read())
{
fnc( reader.getint64(0), fromRow(reader) );
}
- con.executenonquery("COMMIT;");
}
{
return ( queryNumericAttributeInternal( _con, record_id, klass, name, default_value) > 0 );
}
-
+
int queryNumericAttribute( const data::RecordId &record_id,
const std::string &klass,
const std::string &name,
du.add(entry);
}
}
-
+
+ std::string queryRepositoryAlias( const data::RecordId &repo_id )
+ {
+ std::string alias;
+ sqlite3_command cmd( _con, "select alias from repositories where id=:id;" );
+ cmd.bind( ":id", repo_id );
+ sqlite3_reader reader = cmd.executereader();
+ while( reader.read() )
+ {
+ alias = reader.getstring( 0 );
+ break;
+ }
+ return alias;
+ }
+
+ data::RecordId queryRepositoryId( const std::string &repo_alias )
+ {
+ long long id = 0;
+ sqlite3_command cmd( _con, "select id from repositories where alias=:alias;" );
+ cmd.bind( ":alias", repo_alias );
+ sqlite3_reader reader = cmd.executereader();
+ while( reader.read() )
+ {
+ id = reader.getint64(0);
+ break;
+ }
+ return id;
+ }
+
+ void iterateResolvablesByKindsAndStringsAndRepos( const std::vector<zypp::Resolvable::Kind> & kinds,
+ const std::vector<std::string> &strings, int flags, const std::vector<std::string> repos, ProcessResolvable fnc )
+ {
+ std::string sqlcmd( "SELECT " + _fields + " FROM resolvables" );
+
+ std::vector<std::string>::const_iterator it_s;
+ for (it_s = strings.begin(); it_s != strings.end(); ++it_s)
+ {
+ std::string s( *it_s );
+
+ if (it_s == strings.begin())
+ sqlcmd += " WHERE (";
+ else
+ sqlcmd += " AND ";
+
+//FIXME: Implement MATCH_RESSUMM and MATCH_RESDESC
+
+ sqlcmd += " name ";
+ if ((flags & MATCH_WILDCARDS) == 0)
+ {
+ sqlcmd += "=";
+ }
+ else
+ {
+ sqlcmd += "like";
+ s = regex2sql( s );
+ }
+ if (flags & MATCH_LEADING)
+ s += "%";
+ if (flags & MATCH_TRAILING)
+ s = string("%") + s;
+
+ sqlcmd += " '";
+ sqlcmd += s;
+ sqlcmd += "'";
+ }
+
+ if (it_s != strings.begin())
+ {
+ sqlcmd += ")";
+ }
+
+ std::vector<zypp::Resolvable::Kind>::const_iterator it_k;
+ if (!kinds.empty())
+ {
+ if (it_s == strings.begin())
+ sqlcmd += " WHERE";
+ else
+ sqlcmd += " AND";
+
+ for (it_k = kinds.begin(); it_k != kinds.end(); ++it_k)
+ {
+ if (it_k == kinds.begin())
+ sqlcmd += " kind IN (";
+ else
+ sqlcmd += ", ";
+
+ char idbuf[16];
+ snprintf( idbuf, 15, "%d", (int)(_type_cache.idForKind( *it_k )) );
+ sqlcmd += idbuf;
+ }
+
+ if (it_k != kinds.begin())
+ {
+ sqlcmd += ")";
+ }
+ }
+
+ std::vector<std::string>::const_iterator it_r;
+ if (!repos.empty())
+ {
+ if (it_s == strings.begin()
+ && it_k == kinds.begin())
+ sqlcmd += " WHERE";
+ else
+ sqlcmd += " AND";
+
+ for (it_r = repos.begin(); it_r != repos.end(); ++it_r)
+ {
+ if (it_r == repos.begin())
+ sqlcmd += " (";
+ else
+ sqlcmd += " OR ";
+
+ sqlcmd += "repository_id = ";
+ char idbuf[16];
+ snprintf( idbuf, 15, "%ld", (long)(queryRepositoryId( *it_r )) );
+ sqlcmd += idbuf;
+ }
+
+ if (it_r != repos.begin())
+ {
+ sqlcmd += ")";
+ }
+ }
+
+MIL << "sqlcmd " << sqlcmd << endl;
+ sqlite3_command cmd( _con, sqlcmd );
+ sqlite3_reader reader = cmd.executereader();
+ while(reader.read())
+ {
+ fnc( reader.getint64(0), fromRow(reader) );
+ }
+ }
+
private:
int queryNumericAttributeInternal( sqlite3_connection &con,
sqlite3_reader reader = _cmd_attr_num->executereader();
if ( reader.read() )
return reader.getint(0);
+ else
+ {
+ reader.close();
+ sqlite3_reader idreader = _cmd_shared_id->executereader();
+ if ( idreader.read() )
+ {
+ _cmd_shared_id->bind(":rid", record_id);
+ data::RecordId sid = idreader.getint(0);
+ idreader.close();
+ return queryNumericAttributeInternal(con, sid, klass, name, default_value);
+ }
+ }
return default_value;
}
-
+
TranslatedText queryTranslatedStringAttributeInternal( sqlite3_connection &con,
const data::RecordId &record_id,
const std::string &klass,
TranslatedText result;
sqlite3_reader reader = _cmd_attr_tstr->executereader();
-
+
int c = 0;
while(reader.read())
{
if ( c>0 )
return result;
-
+ else
+ {
+ reader.close();
+ _cmd_shared_id->bind(":rid", record_id);
+ sqlite3_reader idreader = _cmd_shared_id->executereader();
+ if ( idreader.read() )
+ {
+ data::RecordId sid = idreader.getint(0);
+ idreader.close();
+ return queryTranslatedStringAttributeInternal(con, sid, klass, name, default_value);
+ }
+ }
+
return default_value;
}
_cmd_attr_str->bind(":tname", name);
sqlite3_reader reader = _cmd_attr_str->executereader();
-
+
if ( reader.read() )
return reader.getstring(0);
-
+ else
+ {
+ reader.close();
+ _cmd_shared_id->bind(":rid", record_id);
+ sqlite3_reader idreader = _cmd_shared_id->executereader();
+ if ( idreader.read() )
+ {
+ data::RecordId sid = idreader.getint(0);
+ idreader.close();
+ return queryStringAttributeTranslationInternal( con, sid, locale, klass, name, default_value );
+ }
+ }
+
return default_value;
}
};
//////////////////////////////////////////////////////////////////////////////
ResolvableQuery::ResolvableQuery( const Pathname &dbdir)
- : _pimpl(new Impl(dbdir))
+ : _pimpl(/*new Impl(dbdir)*/)
{
//MIL << "Creating Resolvable query" << endl;
}
_pimpl->queryDiskUsage(record_id, du);
}
+std::string ResolvableQuery::queryRepositoryAlias( const data::RecordId &repo_id )
+{
+ return _pimpl->queryRepositoryAlias( repo_id );
+}
+
+void ResolvableQuery::iterateResolvablesByKindsAndStringsAndRepos( const std::vector<zypp::Resolvable::Kind> & kinds,
+ const std::vector<std::string> &strings, int flags, const std::vector<std::string> &repos, ProcessResolvable fnc )
+{
+ _pimpl->iterateResolvablesByKindsAndStringsAndRepos( kinds, strings, flags, repos, fnc );
+}
//////////////////////////////////////////////////////////////////////////////
} } // namespace zypp::cache