From ba93b336890205933a57fae958c0ec6be5932ac7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 2 Oct 2015 09:50:20 +0200 Subject: Simplify version comparison --- brep/package | 68 +++++++++++++++++++++++++++-------------- brep/package-version-search.cxx | 4 +-- brep/package.cxx | 10 +++--- 3 files changed, 52 insertions(+), 30 deletions(-) (limited to 'brep') diff --git a/brep/package b/brep/package index 6ca0c12..6cd87e9 100644 --- a/brep/package +++ b/brep/package @@ -68,6 +68,30 @@ namespace brep // to TEXT as a comma-separated list. // + // Version comparison operators. + // + template + inline auto + operator< (const T1& x, const T2& y) -> decltype (x.epoch < y.epoch) + { + return x.epoch < y.epoch || + (x.epoch == y.epoch && + x.canonical_upstream < y.canonical_upstream) || + (x.epoch == y.epoch && + x.canonical_upstream == y.canonical_upstream && + x.revision < y.revision); + } + + template + inline auto + order_by_version_desc (const T& x) -> decltype (x.epoch == 0) + { + return "ORDER BY" + + x.epoch + "DESC," + + x.canonical_upstream + "DESC," + + x.revision + "DESC"; + } + // Forward declarations. // class repository; @@ -109,9 +133,16 @@ namespace brep struct package_version_id { std::string package; - std::uint16_t epoch; - std::string canonical_upstream; - std::uint16_t revision; + + #pragma db value + struct version_type + { + std::uint16_t epoch; + std::string canonical_upstream; + std::uint16_t revision; + }; + + version_type version; // Database mapping. // @@ -126,15 +157,7 @@ namespace brep if (r != 0) return r < 0; - if (x.epoch != y.epoch) - return x.epoch < y.epoch; - - r = x.canonical_upstream.compare (y.canonical_upstream); - - if (r != 0) - return r < 0; - - return x.revision < y.revision; + return x.version < y.version; } using priority = bpkg::priority; @@ -458,10 +481,9 @@ namespace brep package_version () = default; }; - #pragma db view object(package_version) \ - query((?) + "ORDER BY" + package_version::id.data.epoch + "DESC," + \ - package_version::id.data.canonical_upstream + "DESC," + \ - package_version::id.data.revision + "DESC LIMIT 1") + #pragma db view object(package_version) \ + query((?) + order_by_version_desc (package_version::id.data.version) + \ + "LIMIT 1") struct max_package_version { using version_type = brep::version; @@ -486,13 +508,7 @@ namespace brep #pragma db view object(package_version = version) \ object(package_version = v: \ version::id.data.package == v::id.data.package && \ - (version::id.data.epoch < v::id.data.epoch || \ - (version::id.data.epoch == v::id.data.epoch && \ - (version::id.data.canonical_upstream < \ - v::id.data.canonical_upstream || \ - (version::id.data.canonical_upstream == \ - v::id.data.canonical_upstream && \ - version::id.data.revision < v::id.data.revision))))) \ + version::id.data.version < v::id.data.version) \ object(package inner: version::id.data.package == package::name && \ version::internal_repository.is_not_null () && \ v::id.data.package.is_null ()) @@ -521,6 +537,12 @@ namespace brep }; } +namespace odb +{ + using ::brep::operator<; + using ::brep::order_by_version_desc; +} + // Nested container emulation support for ODB. // // Note that the outer index in the inner container should strictly diff --git a/brep/package-version-search.cxx b/brep/package-version-search.cxx index 166f116..2774a16 100644 --- a/brep/package-version-search.cxx +++ b/brep/package-version-search.cxx @@ -149,9 +149,7 @@ namespace brep db_->query ( (query::id.data.package == name && query::internal_repository.is_not_null ()) + - "ORDER BY" + query::id.data.epoch + "DESC," + - query::id.data.canonical_upstream + "DESC," + - query::id.data.revision + "DESC " + + order_by_version_desc (query::id.data.version) + "OFFSET" + to_string (pr.page () * rop) + "LIMIT" + to_string (rop))); diff --git a/brep/package.cxx b/brep/package.cxx index b0c1115..46953f4 100644 --- a/brep/package.cxx +++ b/brep/package.cxx @@ -98,9 +98,10 @@ namespace brep void package_version:: _id (_id_type&& v, database& db) { + const auto& dv (v.data.version); package = lazy_shared_ptr (db, v.data.package); - version = version_type (v.data.epoch, move (v.upstream), v.data.revision); - assert (version.canonical_upstream == v.data.canonical_upstream); + version = version_type (dv.epoch, move (v.upstream), dv.revision); + assert (version.canonical_upstream == dv.canonical_upstream); } // max_package_version @@ -108,8 +109,9 @@ namespace brep void max_package_version:: _id (package_version::_id_type&& v) { - version = version_type (v.data.epoch, move (v.upstream), v.data.revision); - assert (version.canonical_upstream == v.data.canonical_upstream); + const auto& dv (v.data.version); + version = version_type (dv.epoch, move (v.upstream), dv.revision); + assert (version.canonical_upstream == dv.canonical_upstream); } // repository -- cgit v1.1