libdnf/SOURCES/0003-Add-2-query-filters.patch

340 lines
12 KiB
Diff

From b36464f01ffadab9ca49eed1a06ab480626b28c2 Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 16 Dec 2019 10:10:51 +0100
Subject: [PATCH 1/2] Add new query filter upgrades_by_priority
It returns upgrades only from repository with the lowest priority.
---
libdnf/hy-types.h | 3 +-
libdnf/sack/query.cpp | 60 ++++++++++++++++++++++++++++++++++
python/hawkey/hawkeymodule.cpp | 1 +
python/hawkey/query-py.cpp | 5 ++-
4 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
index b34988d89..380a0d5cc 100644
--- a/libdnf/hy-types.h
+++ b/libdnf/hy-types.h
@@ -97,7 +97,8 @@ enum _hy_key_name_e {
* @brief Use for strings of whole NEVRA (missing epoch is handled as epoch 0)
* Allowed compare types - only HY_EQ or HY_NEQ
*/
- HY_PKG_NEVRA_STRICT = 36
+ HY_PKG_NEVRA_STRICT = 36,
+ HY_PKG_UPGRADES_BY_PRIORITY = 37,
};
enum _hy_comparison_type_e {
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index eea0ce1b1..ecfd3110f 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -148,6 +148,13 @@ NameArchSolvableComparator(const Solvable * first, const Solvable * second)
return first->arch < second->arch;
}
+static bool
+NamePrioritySolvableKey(const Solvable * first, const Solvable * second)
+{
+ if (first->name != second->name)
+ return first->name < second->name;
+ return first->repo->priority > second->repo->priority;
+}
static bool
match_type_num(int keyname) {
@@ -158,6 +165,7 @@ match_type_num(int keyname) {
case HY_PKG_LATEST_PER_ARCH:
case HY_PKG_UPGRADABLE:
case HY_PKG_UPGRADES:
+ case HY_PKG_UPGRADES_BY_PRIORITY:
case HY_PKG_DOWNGRADABLE:
case HY_PKG_DOWNGRADES:
return true;
@@ -690,6 +698,7 @@ class Query::Impl {
void filterAdvisory(const Filter & f, Map *m, int keyname);
void filterLatest(const Filter & f, Map *m);
void filterUpdown(const Filter & f, Map *m);
+ void filterUpdownByPriority(const Filter & f, Map *m);
void filterUpdownAble(const Filter &f, Map *m);
void filterDataiterator(const Filter & f, Map *m);
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
@@ -1732,6 +1741,54 @@ Query::Impl::filterUpdown(const Filter & f, Map *m)
}
}
+void
+Query::Impl::filterUpdownByPriority(const Filter & f, Map *m)
+{
+ Pool *pool = dnf_sack_get_pool(sack);
+ auto resultPset = result.get();
+
+ dnf_sack_make_provides_ready(sack);
+ auto repoInstalled = pool->installed;
+ if (!repoInstalled) {
+ return;
+ }
+
+ for (auto match_in : f.getMatches()) {
+ if (match_in.num == 0)
+ continue;
+ std::vector<Solvable *> upgradeCandidates;
+ upgradeCandidates.reserve(resultPset->size());
+ Id id = -1;
+ while ((id = resultPset->next(id)) != -1) {
+ Solvable *candidate = pool_id2solvable(pool, id);
+ if (candidate->repo == repoInstalled)
+ continue;
+ upgradeCandidates.push_back(candidate);
+ }
+ if (upgradeCandidates.empty()) {
+ continue;
+ }
+ std::sort(upgradeCandidates.begin(), upgradeCandidates.end(), NamePrioritySolvableKey);
+ Id name = 0;
+ int priority = 0;
+ for (auto * candidate: upgradeCandidates) {
+ if (name != candidate->name) {
+ name = candidate->name;
+ priority = candidate->repo->priority;
+ id = pool_solvable2id(pool, candidate);
+ if (what_upgrades(pool, id) > 0) {
+ MAPSET(m, id);
+ }
+ } else if (priority == candidate->repo->priority) {
+ id = pool_solvable2id(pool, candidate);
+ if (what_upgrades(pool, id) > 0) {
+ MAPSET(m, id);
+ }
+ }
+ }
+ }
+}
+
void
Query::Impl::filterUpdownAble(const Filter &f, Map *m)
{
@@ -1949,6 +2006,9 @@ Query::Impl::apply()
case HY_PKG_UPGRADES:
filterUpdown(f, &m);
break;
+ case HY_PKG_UPGRADES_BY_PRIORITY:
+ filterUpdownByPriority(f, &m);
+ break;
default:
filterDataiterator(f, &m);
}
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
index 0f05f46c2..4351e96e1 100644
--- a/python/hawkey/hawkeymodule.cpp
+++ b/python/hawkey/hawkeymodule.cpp
@@ -281,6 +281,7 @@ PYCOMP_MOD_INIT(_hawkey)
PyModule_AddIntConstant(m, "PKG_SUPPLEMENTS", HY_PKG_SUPPLEMENTS);
PyModule_AddIntConstant(m, "PKG_UPGRADABLE", HY_PKG_UPGRADABLE);
PyModule_AddIntConstant(m, "PKG_UPGRADES", HY_PKG_UPGRADES);
+ PyModule_AddIntConstant(m, "PKG_UPGRADES_BY_PRIORITY", HY_PKG_UPGRADES_BY_PRIORITY);
PyModule_AddIntConstant(m, "PKG_URL", HY_PKG_URL);
PyModule_AddIntConstant(m, "PKG_VERSION", HY_PKG_VERSION);
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index 116ffa1b0..286e306d3 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -89,6 +89,7 @@ static const int keyname_int_matches[] = {
HY_PKG_SUPPLEMENTS,
HY_PKG_UPGRADABLE,
HY_PKG_UPGRADES,
+ HY_PKG_UPGRADES_BY_PRIORITY,
HY_PKG_URL,
HY_PKG_VERSION
};
@@ -128,6 +129,7 @@ static const char * const keyname_char_matches[] = {
"supplements",
"upgradable",
"upgrades",
+ "upgrades_by_priority",
"url",
"version",
NULL
@@ -273,7 +275,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
keyname == HY_PKG_LATEST_PER_ARCH ||
keyname == HY_PKG_LATEST ||
keyname == HY_PKG_UPGRADABLE ||
- keyname == HY_PKG_UPGRADES) {
+ keyname == HY_PKG_UPGRADES ||
+ keyname == HY_PKG_UPGRADES_BY_PRIORITY) {
int val;
if (!PyInt_Check(match) || cmp_type != HY_EQ) {
From 4b83ae692f90d0d3cbc377c7f93bdb7e99e477ef Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Mon, 16 Dec 2019 18:34:37 +0100
Subject: [PATCH 2/2] Add new query filter obsoletes_by_priority
---
libdnf/hy-types.h | 1 +
libdnf/sack/query.cpp | 65 ++++++++++++++++++++++++++++++++++
python/hawkey/hawkeymodule.cpp | 1 +
python/hawkey/query-py.cpp | 5 ++-
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/libdnf/hy-types.h b/libdnf/hy-types.h
index 380a0d5cc..e96459c25 100644
--- a/libdnf/hy-types.h
+++ b/libdnf/hy-types.h
@@ -99,6 +99,7 @@ enum _hy_key_name_e {
*/
HY_PKG_NEVRA_STRICT = 36,
HY_PKG_UPGRADES_BY_PRIORITY = 37,
+ HY_PKG_OBSOLETES_BY_PRIORITY = 38,
};
enum _hy_comparison_type_e {
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
index ecfd3110f..6e9e4715f 100644
--- a/libdnf/sack/query.cpp
+++ b/libdnf/sack/query.cpp
@@ -179,6 +179,7 @@ match_type_pkg(int keyname) {
switch (keyname) {
case HY_PKG:
case HY_PKG_OBSOLETES:
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
return true;
default:
return false;
@@ -692,6 +693,7 @@ class Query::Impl {
void filterArch(const Filter & f, Map *m);
void filterSourcerpm(const Filter & f, Map *m);
void filterObsoletes(const Filter & f, Map *m);
+ void filterObsoletesByPriority(const Filter & f, Map *m);
void filterProvidesReldep(const Filter & f, Map *m);
void filterReponame(const Filter & f, Map *m);
void filterLocation(const Filter & f, Map *m);
@@ -702,6 +704,7 @@ class Query::Impl {
void filterUpdownAble(const Filter &f, Map *m);
void filterDataiterator(const Filter & f, Map *m);
int filterUnneededOrSafeToRemove(const Swdb &swdb, bool debug_solver, bool safeToRemove);
+ void obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides);
bool isGlob(const std::vector<const char *> &matches) const;
};
@@ -1469,6 +1472,65 @@ Query::Impl::filterObsoletes(const Filter & f, Map *m)
}
}
+void
+Query::Impl::obsoletesByPriority(Pool * pool, Solvable * candidate, Map * m, const Map * target, int obsprovides)
+{
+ if (!candidate->repo)
+ return;
+ for (Id *r_id = candidate->repo->idarraydata + candidate->obsoletes; *r_id; ++r_id) {
+ Id r, rr;
+ FOR_PROVIDES(r, rr, *r_id) {
+ if (!MAPTST(target, r))
+ continue;
+ assert(r != SYSTEMSOLVABLE);
+ Solvable *so = pool_id2solvable(pool, r);
+ if (!obsprovides && !pool_match_nevr(pool, so, *r_id))
+ continue; /* only matching pkg names */
+ MAPSET(m, pool_solvable2id(pool, candidate));
+ break;
+ }
+ }
+}
+
+void
+Query::Impl::filterObsoletesByPriority(const Filter & f, Map *m)
+{
+ Pool *pool = dnf_sack_get_pool(sack);
+ int obsprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES);
+ Map *target;
+ auto resultPset = result.get();
+
+ assert(f.getMatchType() == _HY_PKG);
+ assert(f.getMatches().size() == 1);
+ target = dnf_packageset_get_map(f.getMatches()[0].pset);
+ dnf_sack_make_provides_ready(sack);
+ std::vector<Solvable *> obsoleteCandidates;
+ obsoleteCandidates.reserve(resultPset->size());
+ Id id = -1;
+ while ((id = resultPset->next(id)) != -1) {
+ Solvable *candidate = pool_id2solvable(pool, id);
+ obsoleteCandidates.push_back(candidate);
+ }
+ if (obsoleteCandidates.empty()) {
+ return;
+ }
+ std::sort(obsoleteCandidates.begin(), obsoleteCandidates.end(), NamePrioritySolvableKey);
+ Id name = 0;
+ int priority = 0;
+ for (auto * candidate: obsoleteCandidates) {
+ if (candidate->repo == pool->installed) {
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ }
+ if (name != candidate->name) {
+ name = candidate->name;
+ priority = candidate->repo->priority;
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ } else if (priority == candidate->repo->priority) {
+ obsoletesByPriority(pool, candidate, m, target, obsprovides);
+ }
+ }
+}
+
void
Query::Impl::filterProvidesReldep(const Filter & f, Map *m)
{
@@ -1969,6 +2031,9 @@ Query::Impl::apply()
filterObsoletes(f, &m);
}
break;
+ case HY_PKG_OBSOLETES_BY_PRIORITY:
+ filterObsoletesByPriority(f, &m);
+ break;
case HY_PKG_PROVIDES:
assert(f.getMatchType() == _HY_RELDEP);
filterProvidesReldep(f, &m);
diff --git a/python/hawkey/hawkeymodule.cpp b/python/hawkey/hawkeymodule.cpp
index 4351e96e1..82d05e2cb 100644
--- a/python/hawkey/hawkeymodule.cpp
+++ b/python/hawkey/hawkeymodule.cpp
@@ -270,6 +270,7 @@ PYCOMP_MOD_INIT(_hawkey)
PyModule_AddIntConstant(m, "PKG_NEVRA", HY_PKG_NEVRA);
PyModule_AddIntConstant(m, "PKG_NEVRA_STRICT", HY_PKG_NEVRA_STRICT);
PyModule_AddIntConstant(m, "PKG_OBSOLETES", HY_PKG_OBSOLETES);
+ PyModule_AddIntConstant(m, "PKG_OBSOLETES_BY_PRIORITY", HY_PKG_OBSOLETES_BY_PRIORITY);
PyModule_AddIntConstant(m, "PKG_PROVIDES", HY_PKG_PROVIDES);
PyModule_AddIntConstant(m, "PKG_RECOMMENDS", HY_PKG_RECOMMENDS);
PyModule_AddIntConstant(m, "PKG_RELEASE", HY_PKG_RELEASE);
diff --git a/python/hawkey/query-py.cpp b/python/hawkey/query-py.cpp
index 286e306d3..9178a6d0c 100644
--- a/python/hawkey/query-py.cpp
+++ b/python/hawkey/query-py.cpp
@@ -78,6 +78,7 @@ static const int keyname_int_matches[] = {
HY_PKG_NEVRA,
HY_PKG_NEVRA_STRICT,
HY_PKG_OBSOLETES,
+ HY_PKG_OBSOLETES_BY_PRIORITY,
HY_PKG_PROVIDES,
HY_PKG_RECOMMENDS,
HY_PKG_RELEASE,
@@ -118,6 +119,7 @@ static const char * const keyname_char_matches[] = {
"nevra",
"nevra_strict",
"obsoletes",
+ "obsoletes_by_priority",
"provides",
"recommends",
"release",
@@ -342,7 +344,8 @@ filter_add(HyQuery query, key_t keyname, int cmp_type, PyObject *match)
// match is a sequence now:
switch (keyname) {
case HY_PKG:
- case HY_PKG_OBSOLETES: {
+ case HY_PKG_OBSOLETES:
+ case HY_PKG_OBSOLETES_BY_PRIORITY: {
// It could be a sequence of packages or reldep/strings. Lets try packages first.
auto pset = pyseq_to_packageset(match, query->getSack());
if (!pset) {