rpm::PackageQuery: New filter "filter_from_repo_id"
This filter can be used toimplement GoalJobsSettings::set_from_repo_ids. Within the dnf5 application, this filter will be utilized to filter installed packages using the command-line option "--installed-from-repo=".
This commit is contained in:
parent
0db4bf62d4
commit
fcd19ec8d5
|
@ -822,6 +822,30 @@ public:
|
|||
void filter_repo_id(
|
||||
const std::vector<std::string> & patterns, libdnf5::sack::QueryCmp cmp_type = libdnf5::sack::QueryCmp::EQ);
|
||||
|
||||
/// Filters packages by the `id` of the repository they were installed from.
|
||||
/// This also removes any packages from the query that are not currently installed.
|
||||
///
|
||||
/// @param pattern A string the filter is matched against.
|
||||
/// @param cmp_type A comparison (match) operator, defaults to `QueryCmp::EQ`.
|
||||
/// Supported values: `EQ`, `NEQ`, `GLOB`, `NOT_GLOB`.
|
||||
/// @since 5.2.14
|
||||
//
|
||||
void filter_from_repo_id(
|
||||
const std::string & pattern, libdnf5::sack::QueryCmp cmp_type = libdnf5::sack::QueryCmp::EQ) {
|
||||
filter_from_repo_id(std::vector<std::string>{pattern}, cmp_type);
|
||||
};
|
||||
|
||||
/// Filters packages by the `id` of the repository they were installed from.
|
||||
/// This also removes any packages from the query that are not currently installed.
|
||||
///
|
||||
/// @param patterns A vector of strings the filter is matched against.
|
||||
/// @param cmp_type A comparison (match) operator, defaults to `QueryCmp::EQ`.
|
||||
/// Supported values: `EQ`, `NEQ`, `GLOB`, `NOT_GLOB`.
|
||||
/// @since 5.2.14
|
||||
//
|
||||
void filter_from_repo_id(
|
||||
const std::vector<std::string> & patterns, libdnf5::sack::QueryCmp cmp_type = libdnf5::sack::QueryCmp::EQ);
|
||||
|
||||
/// Filter packages by advisories they are included in.
|
||||
///
|
||||
/// @param advisory_query AdvisoryQuery with Advisories that contain package lists the filter is matched against.
|
||||
|
|
|
@ -1177,6 +1177,57 @@ void PackageQuery::filter_repo_id(const std::vector<std::string> & patterns, lib
|
|||
}
|
||||
}
|
||||
|
||||
void PackageQuery::filter_from_repo_id(const std::vector<std::string> & patterns, libdnf5::sack::QueryCmp cmp_type) {
|
||||
auto & pool = get_rpm_pool(p_impl->base);
|
||||
const auto * const installed_repo = pool->installed;
|
||||
if (installed_repo == nullptr) {
|
||||
(*p_impl).clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool cmp_not = (cmp_type & libdnf5::sack::QueryCmp::NOT) == libdnf5::sack::QueryCmp::NOT;
|
||||
if (cmp_not) {
|
||||
// Removal of NOT CmpType makes following comparisons easier and effective
|
||||
cmp_type = cmp_type - libdnf5::sack::QueryCmp::NOT;
|
||||
}
|
||||
|
||||
const bool cmp_glob = (cmp_type & libdnf5::sack::QueryCmp::GLOB) == libdnf5::sack::QueryCmp::GLOB;
|
||||
|
||||
std::vector<bool> cmp_globs(patterns.size());
|
||||
for (size_t i = 0; i < patterns.size(); ++i) {
|
||||
if (cmp_glob && libdnf5::utils::is_glob_pattern(patterns[i].c_str())) {
|
||||
cmp_globs[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
libdnf5::solv::SolvMap filter_result(pool.get_nsolvables());
|
||||
auto endp = end();
|
||||
for (auto itp = begin(); itp != endp; ++itp) {
|
||||
const auto pkg = *itp;
|
||||
if (pkg.is_installed()) {
|
||||
const auto from_repo = pkg.get_from_repo_id();
|
||||
for (size_t i = 0; i < patterns.size(); ++i) {
|
||||
switch (cmp_globs[i]) {
|
||||
case false:
|
||||
if ((strcmp(patterns[i].c_str(), from_repo.c_str()) != 0) == cmp_not) {
|
||||
filter_result.add_unsafe(pkg.get_id().id);
|
||||
};
|
||||
break;
|
||||
case true:
|
||||
if ((fnmatch(patterns[i].c_str(), from_repo.c_str(), 0) != 0) == cmp_not) {
|
||||
filter_result.add_unsafe(pkg.get_id().id);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jrohel): The optimization replaces the original query_result buffer. Is it OK?
|
||||
// Or we need to use a slower version "*p_impl &= filter_result;"
|
||||
p_impl->swap(filter_result);
|
||||
}
|
||||
|
||||
void PackageQuery::filter_sourcerpm(const std::vector<std::string> & patterns, libdnf5::sack::QueryCmp cmp_type) {
|
||||
bool cmp_not = (cmp_type & libdnf5::sack::QueryCmp::NOT) == libdnf5::sack::QueryCmp::NOT;
|
||||
if (cmp_not) {
|
||||
|
|
Loading…
Reference in New Issue