From c7e76c23b49c423f352b283c7afba248b4ce77e9 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 16 Jan 2023 13:14:36 +0300 Subject: Add find_available_all() --- bpkg/package-query.cxx | 90 +++++++++++++++++++++++++++++++++++++++++++++----- bpkg/package-query.hxx | 19 +++++++++-- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/bpkg/package-query.cxx b/bpkg/package-query.cxx index 8d7b652..66cb7f0 100644 --- a/bpkg/package-query.cxx +++ b/bpkg/package-query.cxx @@ -311,11 +311,13 @@ namespace bpkg } // Sort the available package fragments in the package version descending - // order and suppress duplicate packages. + // order and suppress duplicate packages and, optionally, older package + // revisions. // static void sort_dedup (vector, - lazy_shared_ptr>>& pfs) + lazy_shared_ptr>>& pfs, + bool suppress_older_revisions = false) { sort (pfs.begin (), pfs.end (), [] (const auto& x, const auto& y) @@ -323,12 +325,14 @@ namespace bpkg return x.first->version > y.first->version; }); - pfs.erase (unique (pfs.begin(), pfs.end(), - [] (const auto& x, const auto& y) - { - return x.first->version == y.first->version; - }), - pfs.end ()); + pfs.erase ( + unique (pfs.begin(), pfs.end(), + [suppress_older_revisions] (const auto& x, const auto& y) + { + return x.first->version.compare (y.first->version, + suppress_older_revisions) == 0; + }), + pfs.end ()); } vector, @@ -546,6 +550,76 @@ namespace bpkg return make_pair (find_available (options, db, sp), nullptr); } + vector, + lazy_shared_ptr>> + find_available_all (const linked_databases& dbs, + const package_name& name, + bool suppress_older_revisions) + { + // Collect all the databases linked explicitly and implicitly to the + // specified databases, recursively. + // + // Note that this is a superset of the database cluster, since we descend + // into the database links regardless of their types (see + // cluster_configs() for details). + // + linked_databases all_dbs; + all_dbs.reserve (dbs.size ()); + + auto add = [&all_dbs] (database& db, const auto& add) + { + if (find (all_dbs.begin (), all_dbs.end (), db) != all_dbs.end ()) + return; + + all_dbs.push_back (db); + + { + const linked_configs& cs (db.explicit_links ()); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (i->db, add); + } + + { + const linked_databases& cs (db.implicit_links ()); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (*i, add); + } + }; + + for (database& db: dbs) + add (db, add); + + // Collect all the available packages from all the collected databases. + // + vector, + lazy_shared_ptr>> r; + + for (database& db: all_dbs) + { + for (shared_ptr ap: + pointer_result ( + query_available (db, name, nullopt /* version_constraint */))) + { + // An available package should come from at least one fetched + // repository fragment. + // + assert (!ap->locations.empty ()); + + // All repository fragments the package comes from are equally good, so + // we pick the first one. + // + r.emplace_back (move (ap), ap->locations[0].repository_fragment); + } + } + + // Sort the result in the package version descending order and suppress + // duplicates and, if requested, older package revisions. + // + sort_dedup (r, suppress_older_revisions); + + return r; + } + pair, lazy_shared_ptr> make_available_fragment (const common_options& options, diff --git a/bpkg/package-query.hxx b/bpkg/package-query.hxx index ebe92ac..1919058 100644 --- a/bpkg/package-query.hxx +++ b/bpkg/package-query.hxx @@ -75,8 +75,8 @@ namespace bpkg // Try to find packages that optionally satisfy the specified version // constraint in multiple databases, suppressing duplicates. Return the list // of packages and repository fragments in which each was found in the - // package version descending or empty list if none were found. Note that a - // stub satisfies any constraint. + // package version descending order or empty list if none were found. Note + // that a stub satisfies any constraint. // // Note that we return (loaded) lazy_shared_ptr in order to also convey // the database to which it belongs. @@ -173,6 +173,21 @@ namespace bpkg database&, const shared_ptr&); + // Try to find packages in multiple databases, traversing the explicitly and + // implicitly linked databases recursively and suppressing duplicates and, + // optionally, older package revisions. Return the list of packages and + // repository fragments in which each was found in the package version + // descending order or empty list if none were found. + // + // Note that we return (loaded) lazy_shared_ptr in order to also convey + // the database to which it belongs. + // + vector, + lazy_shared_ptr>> + find_available_all (const linked_databases&, + const package_name&, + bool suppress_older_revisions = true); + // Create a transient (or fake, if you prefer) available_package object // corresponding to the specified selected object. Note that the package // locations list is left empty and that the returned repository fragment -- cgit v1.1