From dbbc19b77dcf6ea828aabd64d7aa8cab9635aaf5 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 4 Apr 2017 20:53:00 +0300 Subject: Implement build task, result and log requests handling --- brep/.gitignore | 5 + brep/build | 155 +++++++++++++++++++++++++ brep/build.cxx | 45 ++++++++ brep/build.xml | 64 +++++++++++ brep/buildfile | 8 +- brep/common | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ brep/common.cxx | 10 ++ brep/odb.sh | 19 +++- brep/package | 338 +++--------------------------------------------------- brep/package.cxx | 2 - brep/package.xml | 2 +- brep/utility | 2 +- brep/version | 5 + 13 files changed, 664 insertions(+), 332 deletions(-) create mode 100644 brep/build create mode 100644 brep/build.cxx create mode 100644 brep/build.xml create mode 100644 brep/common create mode 100644 brep/common.cxx (limited to 'brep') diff --git a/brep/.gitignore b/brep/.gitignore index 687b168..9852519 100644 --- a/brep/.gitignore +++ b/brep/.gitignore @@ -1,3 +1,8 @@ +common-odb* + package-odb* package.sql package-extra + +build-odb* +build.sql diff --git a/brep/build b/brep/build new file mode 100644 index 0000000..3d969db --- /dev/null +++ b/brep/build @@ -0,0 +1,155 @@ +// file : brep/build -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BREP_BUILD +#define BREP_BUILD + +#include + +#include +#include + +#include + +#include +#include + +#include // Must be included last (see assert). + +// Used by the data migration entries. +// +#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 1 + +#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 1, open) + +// We have to keep these mappings at the global scope instead of inside +// the brep namespace because they need to be also effective in the +// bbot namespace from which we "borrow" types (and some of them use the mapped +// types). +// +#pragma db map type(bbot::result_status) as(std::string) \ + to(to_string (?)) \ + from(bbot::to_result_status (?)) + +namespace brep +{ + #pragma db value + struct build_id + { + package_id package; + string configuration; + + build_id () = default; + build_id (package_id p, string c) + : package (move (p)), configuration (move (c)) {} + }; + + inline bool + operator< (const build_id& x, const build_id& y) + { + return + x.package < y.package ? true : + y.package < x.package ? false : + x.configuration < y.configuration; + } + + // build_state + // + enum class build_state: std::uint8_t + { + untested, + testing, + tested + }; + + string + to_string (build_state); + + build_state + to_build_state (const string&); // May throw invalid_argument. + + inline ostream& + operator<< (ostream& os, build_state s) {return os << to_string (s);} + + #pragma db map type(build_state) as(string) \ + to(to_string (?)) \ + from(brep::to_build_state (?)) + + // result_status + // + using bbot::result_status; + + using optional_result_status = optional; + + #pragma db map type(optional_result_status) as(optional_string) \ + to((?) ? bbot::to_string (*(?)) : brep::optional_string ()) \ + from((?) \ + ? bbot::to_result_status (*(?)) \ + : brep::optional_result_status ()) + + // operation_results + // + using bbot::operation_result; + #pragma db value(operation_result) definition + + using bbot::operation_results; + + #pragma db object pointer(shared_ptr) session + class build + { + public: + using timestamp_type = brep::timestamp; + + // Create the build object with the testing state, non-existent status and + // the timestamp set to now. + // + build (string name, version, string configuration); + + build_id id; + + string& package_name; // Tracks id.package.name. + upstream_version package_version; // Original of id.package.version. + string& configuration; // Tracks id.configuration. + + build_state state; + + // Time of the last state change (the creation time initially). + // + timestamp_type timestamp; + + // Present only if the state is 'tested'. + // + optional status; + + // Note that the logs are stored as std::string/TEXT which is Ok since + // they are UTF-8 and our database is UTF-8. + // + #pragma db section(results_section) + operation_results results; + + #pragma db load(lazy) update(always) + odb::section results_section; + + // Database mapping. + // + #pragma db member(id) id column("") + + #pragma db member(package_name) transient + #pragma db member(package_version) \ + set(this.package_version.init (this.id.package.version, (?))) + #pragma db member(configuration) transient + + #pragma db member(results) id_column("") value_column("") + + build (const build&) = delete; + build& operator= (const build&) = delete; + + private: + friend class odb::access; + build () + : package_name (id.package.name), configuration (id.configuration) {} + }; +} + +#endif // BREP_BUILD diff --git a/brep/build.cxx b/brep/build.cxx new file mode 100644 index 0000000..c93c062 --- /dev/null +++ b/brep/build.cxx @@ -0,0 +1,45 @@ +// file : brep/build.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +namespace brep +{ + // build_state + // + string + to_string (build_state s) + { + switch (s) + { + case build_state::untested: return "untested"; + case build_state::testing: return "testing"; + case build_state::tested: return "tested"; + } + + return string (); // Should never reach. + } + + build_state + to_build_state (const string& s) + { + if (s == "untested") return build_state::untested; + else if (s == "testing") return build_state::testing; + else if (s == "tested") return build_state::tested; + else throw invalid_argument ("invalid build state '" + s + "'"); + } + + // build + // + build:: + build (string pnm, version pvr, string cfg) + : id (package_id (move (pnm), pvr), move (cfg)), + package_name (id.package.name), + package_version (move (pvr)), + configuration (id.configuration), + state (build_state::testing), + timestamp (timestamp_type::clock::now ()) + { + } +} diff --git a/brep/build.xml b/brep/build.xml new file mode 100644 index 0000000..5f75928 --- /dev/null +++ b/brep/build.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/brep/buildfile b/brep/buildfile index a7debc1..aeb1848 100644 --- a/brep/buildfile +++ b/brep/buildfile @@ -10,8 +10,14 @@ import int_libs = libodb%lib{odb} import int_libs += libodb-pgsql%lib{odb-pgsql} import int_libs += libbutl%lib{butl} import int_libs += libbpkg%lib{bpkg} +import int_libs += libbbot%lib{bbot} lib{brep}: \ +{hxx cxx}{ build } \ +{file }{ build.xml } \ +{hxx ixx cxx}{ build-odb } \ +{hxx cxx}{ common } \ +{hxx ixx cxx}{ common-odb } \ {hxx cxx}{ package } \ {file }{ package.xml } \ {hxx ixx cxx}{ package-odb } \ @@ -23,7 +29,7 @@ lib{brep}: \ {hxx }{ version } \ {hxx }{ wrapper-traits } \ $int_libs \ -sql{package package-extra} +sql{build package package-extra} # For pre-releases use the complete version to make sure they cannot be used # in place of another pre-release or the final version. diff --git a/brep/common b/brep/common new file mode 100644 index 0000000..52f225c --- /dev/null +++ b/brep/common @@ -0,0 +1,341 @@ +// file : brep/common -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BREP_COMMON +#define BREP_COMMON + +#include +#include +#include // static_assert + +#include +#include + +// The uint16_t value range is not fully covered by SMALLINT PostgreSQL type +// to which uint16_t is mapped by default. +// +#pragma db value(uint16_t) type("INTEGER") + +namespace brep +{ + // Use an image type to map bpkg::version to the database since there + // is no way to modify individual components directly. + // + #pragma db value + struct _version + { + uint16_t epoch; + string canonical_upstream; + string canonical_release; + uint16_t revision; + string upstream; + optional release; + }; +} + +#include + +namespace brep +{ + using optional_version = optional; + using _optional_version = optional<_version>; +} + +// Prevent assert() macro expansion in get/set expressions. This should +// appear after all #include directives since the assert() macro is +// redefined in each inclusion. +// +#ifdef ODB_COMPILER +# undef assert +# define assert assert +void assert (int); +#endif + +// We have to keep these mappings at the global scope instead of inside +// the brep namespace because they need to be also effective in the +// bpkg namespace from which we "borrow" types (and some of them use version). +// +#pragma db map type(bpkg::version) as(brep::_version) \ + to(brep::_version{(?).epoch, \ + (?).canonical_upstream, \ + (?).canonical_release, \ + (?).revision, \ + (?).upstream, \ + (?).release}) \ + from(bpkg::version ((?).epoch, \ + std::move ((?).upstream), \ + std::move ((?).release), \ + (?).revision)) + +#pragma db map type(brep::optional_version) as(brep::_optional_version) \ + to((?) \ + ? brep::_version{(?)->epoch, \ + (?)->canonical_upstream, \ + (?)->canonical_release, \ + (?)->revision, \ + (?)->upstream, \ + (?)->release} \ + : brep::_optional_version ()) \ + from((?) \ + ? bpkg::version ((?)->epoch, \ + std::move ((?)->upstream), \ + std::move ((?)->release), \ + (?)->revision) \ + : brep::optional_version ()) + +namespace brep +{ + // path + // + #pragma db map type(path) as(string) to((?).string ()) from(brep::path (?)) + + using optional_path = optional; + using optional_string = optional; + + #pragma db map type(optional_path) as(brep::optional_string) \ + to((?) ? (?)->string () : brep::optional_string ()) \ + from((?) ? brep::path (*(?)) : brep::optional_path ()) + + #pragma db map type(dir_path) as(string) \ + to((?).string ()) from(brep::dir_path (?)) + + // Ensure that timestamp can be represented in nonoseconds without loss of + // accuracy, so the following ODB mapping is adequate. + // + static_assert( + std::ratio_greater_equal::value, + "The following timestamp ODB mapping is invalid"); + + // As it pointed out in butl/timestamp we will overflow in year 2262, but + // by that time some larger basic type will be available for mapping. + // + #pragma db map type(timestamp) as(uint64_t) \ + to(std::chrono::duration_cast ( \ + (?).time_since_epoch ()).count ()) \ + from(brep::timestamp ( \ + std::chrono::duration_cast ( \ + std::chrono::nanoseconds (?)))) + + // version + // + using bpkg::version; + + #pragma db value + struct canonical_version + { + uint16_t epoch; + string canonical_upstream; + string canonical_release; + uint16_t revision; + + bool + empty () const noexcept + { + // Note that an empty canonical_upstream doesn't denote an empty + // canonical_version. Remeber, that canonical_upstream doesn't include + // rightmost digit-only zero components? So non-empty version("0") has + // an empty canonical_upstream. + // + return epoch == 0 && canonical_upstream.empty () && + canonical_release.empty () && revision == 0; + } + + // Change collation to ensure the proper comparison of the "absent" release + // with a specified one. + // + // The default collation for UTF8-encoded TEXT columns in PostgreSQL is + // UCA-compliant. This makes the statement 'a' < '~' to be false, which + // in turn makes the statement 2.1.alpha < 2.1 to be false as well. + // + // Unicode Collation Algorithm (UCA): http://unicode.org/reports/tr10/ + // + #pragma db member(canonical_release) options("COLLATE \"C\"") + }; + + #pragma db value transient + struct upstream_version: version + { + #pragma db member(upstream_) virtual(string) \ + get(this.upstream) \ + set(this = brep::version (0, std::move (?), std::string (), 0)) + + #pragma db member(release_) virtual(optional_string) \ + get(this.release) \ + set(this = brep::version ( \ + 0, std::move (this.upstream), std::move (?), 0)) + + upstream_version () = default; + upstream_version (version v): version (move (v)) {} + upstream_version& + operator= (version v) {version& b (*this); b = v; return *this;} + + void + init (const canonical_version& cv, const upstream_version& uv) + { + *this = version (cv.epoch, uv.upstream, uv.release, cv.revision); + assert (cv.canonical_upstream == canonical_upstream && + cv.canonical_release == canonical_release); + } + }; + + // Wildcard version. Satisfies any dependency constraint and is represented + // as 0+0 (which is also the "stub version"; since a real version is always + // greater than the stub version, we reuse it to signify a special case). + // + extern const version wildcard_version; + + #pragma db value + struct package_id + { + string name; + canonical_version version; + + package_id () = default; + package_id (string n, const brep::version& v) + : name (move (n)), + version { + v.epoch, v.canonical_upstream, v.canonical_release, v.revision} + { + } + }; + + // Version comparison operators. + // + // They allow comparing objects that have epoch, canonical_upstream, + // canonical_release, and revision data members. The idea is that this + // works for both query members of types version and canonical_version + // as well as for comparing canonical_version to version. + // + template + inline auto + compare_version_eq (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + // Since we don't quite know what T1 and T2 are (and where the resulting + // expression will run), let's not push our luck with something like + // (!revision || x.revision == y.revision). + // + auto r (x.epoch == y.epoch && + x.canonical_upstream == y.canonical_upstream && + x.canonical_release == y.canonical_release); + + return revision + ? r && x.revision == y.revision + : r; + } + + template + inline auto + compare_version_ne (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + auto r (x.epoch != y.epoch || + x.canonical_upstream != y.canonical_upstream || + x.canonical_release != y.canonical_release); + + return revision + ? r || x.revision != y.revision + : r; + } + + template + inline auto + compare_version_lt (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + auto r ( + 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.canonical_release < y.canonical_release)); + + return revision + ? r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release == y.canonical_release && x.revision < y.revision) + : r; + } + + template + inline auto + compare_version_le (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + auto r ( + x.epoch < y.epoch || + (x.epoch == y.epoch && x.canonical_upstream < y.canonical_upstream)); + + return revision + ? r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release < y.canonical_release) || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release == y.canonical_release && x.revision <= y.revision) + : r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release <= y.canonical_release); + } + + template + inline auto + compare_version_gt (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + auto r ( + 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.canonical_release > y.canonical_release)); + + return revision + ? r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release == y.canonical_release && x.revision > y.revision) + : r; + } + + template + inline auto + compare_version_ge (const T1& x, const T2& y, bool revision) + -> decltype (x.epoch == y.epoch) + { + auto r ( + x.epoch > y.epoch || + (x.epoch == y.epoch && x.canonical_upstream > y.canonical_upstream)); + + return revision + ? r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release > y.canonical_release) || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release == y.canonical_release && x.revision >= y.revision) + : r || + (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && + x.canonical_release >= y.canonical_release); + } + + template + inline auto + order_by_version_desc (const T& x) -> //decltype ("ORDER BY" + x.epoch) + decltype (x.epoch == 0) + { + return "ORDER BY" + + x.epoch + "DESC," + + x.canonical_upstream + "DESC," + + x.canonical_release + "DESC," + + x.revision + "DESC"; + } + + inline bool + operator< (const package_id& x, const package_id& y) + { + if (int r = x.name.compare (y.name)) + return r < 0; + + return compare_version_lt (x.version, y.version, true); + } +} + +#endif // BREP_COMMON diff --git a/brep/common.cxx b/brep/common.cxx new file mode 100644 index 0000000..4847977 --- /dev/null +++ b/brep/common.cxx @@ -0,0 +1,10 @@ +// file : brep/common.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +namespace brep +{ + const version wildcard_version (0, "0", nullopt, 0); +} diff --git a/brep/odb.sh b/brep/odb.sh index 3f8cef2..5e16f45 100755 --- a/brep/odb.sh +++ b/brep/odb.sh @@ -9,10 +9,17 @@ lib="\ -I$HOME/work/odb/libodb-default \ -I$HOME/work/odb/libodb" -$odb $lib -d pgsql --std c++11 --generate-query --generate-schema \ - --schema-format sql --schema-format embedded \ +$odb $lib -d pgsql --std c++11 --generate-query \ --odb-epilogue '#include ' \ --hxx-prologue '#include ' \ + -I .. -I ../../libbpkg -I ../../libbutl \ + --hxx-suffix "" --include-with-brackets \ + --include-prefix brep --guard-prefix BREP \ + common + +$odb $lib -d pgsql --std c++11 --generate-query --generate-schema \ + --schema-format sql --schema-format embedded --schema-name package \ + --generate-prepared --odb-epilogue '#include ' \ --hxx-prologue '#include ' \ -I .. -I ../../libbpkg -I ../../libbutl \ --hxx-suffix "" --include-with-brackets \ @@ -20,3 +27,11 @@ $odb $lib -d pgsql --std c++11 --generate-query --generate-schema \ package xxd -i package-extra + +$odb $lib -d pgsql --std c++11 --generate-query --generate-schema \ + --schema-format sql --schema-format embedded --schema-name build \ + --generate-prepared --odb-epilogue '#include ' \ + -I .. -I ../../libbbot -I ../../libbpkg -I ../../libbutl \ + --hxx-suffix "" --include-with-brackets \ + --include-prefix brep --guard-prefix BREP \ + build diff --git a/brep/package b/brep/package index 13429d1..d50aa9f 100644 --- a/brep/package +++ b/brep/package @@ -6,94 +6,21 @@ #define BREP_PACKAGE #include -#include #include -#include // static_assert #include -#include // database #include #include #include -// Used by the data migration entries. -// -#define LIBBREP_SCHEMA_VERSION_BASE 3 - -#pragma db model version(LIBBREP_SCHEMA_VERSION_BASE, 3, closed) +#include // Must be included last (see assert). -// The uint16_t value range is not fully covered by SMALLINT PostgreSQL type -// to which uint16_t is mapped by default. +// Used by the data migration entries. // -#pragma db value(uint16_t) type("INTEGER") - -namespace brep -{ - // Use an image type to map bpkg::version to the database since there - // is no way to modify individual components directly. - // - #pragma db value - struct _version - { - uint16_t epoch; - string canonical_upstream; - string canonical_release; - uint16_t revision; - string upstream; - optional release; - }; -} - -#include - -namespace brep -{ - using optional_version = optional; - using _optional_version = optional<_version>; -} +#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 3 -// Prevent assert() macro expansion in get/set expressions. This should -// appear after all #include directives since the assert() macro is -// redefined in each inclusion. -// -#ifdef ODB_COMPILER -# undef assert -# define assert assert -void assert (int); -#endif - -// We have to keep these mappings at the global scope instead of inside -// the brep namespace because they need to be also effective in the -// bpkg namespace from which we "borrow" types (and some of them use version). -// -#pragma db map type(bpkg::version) as(brep::_version) \ - to(brep::_version{(?).epoch, \ - (?).canonical_upstream, \ - (?).canonical_release, \ - (?).revision, \ - (?).upstream, \ - (?).release}) \ - from(bpkg::version ((?).epoch, \ - std::move ((?).upstream), \ - std::move ((?).release), \ - (?).revision)) - -#pragma db map type(brep::optional_version) as(brep::_optional_version) \ - to((?) \ - ? brep::_version{(?)->epoch, \ - (?)->canonical_upstream, \ - (?)->canonical_release, \ - (?)->revision, \ - (?)->upstream, \ - (?)->release} \ - : brep::_optional_version ()) \ - from((?) \ - ? bpkg::version ((?)->epoch, \ - std::move ((?)->upstream), \ - std::move ((?)->release), \ - (?)->revision) \ - : brep::optional_version ()) +#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 3, closed) namespace brep { @@ -110,106 +37,6 @@ namespace brep class repository; class package; - // path - // - #pragma db map type(path) as(string) to((?).string ()) from(brep::path (?)) - - using optional_path = optional; - using optional_string = optional; - - #pragma db map type(optional_path) as(brep::optional_string) \ - to((?) ? (?)->string () : brep::optional_string ()) \ - from((?) ? brep::path (*(?)) : brep::optional_path ()) - - #pragma db map type(dir_path) as(string) \ - to((?).string ()) from(brep::dir_path (?)) - - // Ensure that timestamp can be represented in nonoseconds without loss of - // accuracy, so the following ODB mapping is adequate. - // - static_assert( - std::ratio_greater_equal::value, - "The following timestamp ODB mapping is invalid"); - - // As it pointed out in butl/timestamp we will overflow in year 2262, but - // by that time some larger basic type will be available for mapping. - // - #pragma db map type(timestamp) as(uint64_t) \ - to(std::chrono::duration_cast ( \ - (?).time_since_epoch ()).count ()) \ - from(brep::timestamp ( \ - std::chrono::duration_cast ( \ - std::chrono::nanoseconds (?)))) - - // version - // - using bpkg::version; - - #pragma db value - struct canonical_version - { - uint16_t epoch; - string canonical_upstream; - string canonical_release; - uint16_t revision; - - bool - empty () const noexcept - { - // Note that an empty canonical_upstream doesn't denote an empty - // canonical_version. Remeber, that canonical_upstream doesn't include - // rightmost digit-only zero components? So non-empty version("0") has - // an empty canonical_upstream. - // - return epoch == 0 && canonical_upstream.empty () && - canonical_release.empty () && revision == 0; - } - - // Change collation to ensure the proper comparison of the "absent" release - // with a specified one. - // - // The default collation for UTF8-encoded TEXT columns in PostgreSQL is - // UCA-compliant. This makes the statement 'a' < '~' to be false, which - // in turn makes the statement 2.1.alpha < 2.1 to be false as well. - // - // Unicode Collation Algorithm (UCA): http://unicode.org/reports/tr10/ - // - #pragma db member(canonical_release) options("COLLATE \"C\"") - }; - - #pragma db value transient - struct upstream_version: version - { - #pragma db member(upstream_) virtual(string) \ - get(this.upstream) \ - set(this = brep::version (0, std::move (?), std::string (), 0)) - - #pragma db member(release_) virtual(optional_string) \ - get(this.release) \ - set(this = brep::version ( \ - 0, std::move (this.upstream), std::move (?), 0)) - - upstream_version () = default; - upstream_version (version v): version (move (v)) {} - upstream_version& - operator= (version v) {version& b (*this); b = v; return *this;} - - void - init (const canonical_version& cv, const upstream_version& uv) - { - *this = version (cv.epoch, uv.upstream, uv.release, cv.revision); - assert (cv.canonical_upstream == canonical_upstream && - cv.canonical_release == canonical_release); - } - }; - - // Wildcard version. Satisfies any dependency constraint and is represented - // as 0+0 (which is also the "stub version"; since a real version is always - // greater than the stub version, we reuse it to signify a special case). - // - extern const version wildcard_version; - // priority // using bpkg::priority; @@ -244,21 +71,6 @@ namespace brep #pragma db value(dependency_constraint) definition - #pragma db value - struct package_id - { - string name; - canonical_version version; - - package_id () = default; - package_id (string n, const brep::version& v) - : name (move (n)), - version { - v.epoch, v.canonical_upstream, v.canonical_release, v.revision} - { - } - }; - // Notes: // // 1. Will the package be always resolvable? What if it is in @@ -670,141 +482,17 @@ namespace brep package_id id; }; - // Version comparison operators. - // - // They allow comparing objects that have epoch, canonical_upstream, - // canonical_release, and revision data members. The idea is that this - // works for both query members of types version and canonical_version - // as well as for comparing canonical_version to version. - // - template - inline auto - compare_version_eq (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) - { - // Since we don't quite know what T1 and T2 are (and where the resulting - // expression will run), let's not push our luck with something like - // (!revision || x.revision == y.revision). - // - auto r (x.epoch == y.epoch && - x.canonical_upstream == y.canonical_upstream && - x.canonical_release == y.canonical_release); - - return revision - ? r && x.revision == y.revision - : r; - } - - template - inline auto - compare_version_ne (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) - { - auto r (x.epoch != y.epoch || - x.canonical_upstream != y.canonical_upstream || - x.canonical_release != y.canonical_release); - - return revision - ? r || x.revision != y.revision - : r; - } - - template - inline auto - compare_version_lt (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) - { - auto r ( - 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.canonical_release < y.canonical_release)); - - return revision - ? r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release == y.canonical_release && x.revision < y.revision) - : r; - } - - template - inline auto - compare_version_le (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) - { - auto r ( - x.epoch < y.epoch || - (x.epoch == y.epoch && x.canonical_upstream < y.canonical_upstream)); - - return revision - ? r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release < y.canonical_release) || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release == y.canonical_release && x.revision <= y.revision) - : r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release <= y.canonical_release); - } - - template - inline auto - compare_version_gt (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) - { - auto r ( - 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.canonical_release > y.canonical_release)); - - return revision - ? r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release == y.canonical_release && x.revision > y.revision) - : r; - } - - template - inline auto - compare_version_ge (const T1& x, const T2& y, bool revision) - -> decltype (x.epoch == y.epoch) + #pragma db view object(package) + struct package_version { - auto r ( - x.epoch > y.epoch || - (x.epoch == y.epoch && x.canonical_upstream > y.canonical_upstream)); - - return revision - ? r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release > y.canonical_release) || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release == y.canonical_release && x.revision >= y.revision) - : r || - (x.epoch == y.epoch && x.canonical_upstream == y.canonical_upstream && - x.canonical_release >= y.canonical_release); - } - - template - inline auto - order_by_version_desc (const T& x) -> //decltype ("ORDER BY" + x.epoch) - decltype (x.epoch == 0) - { - return "ORDER BY" - + x.epoch + "DESC," - + x.canonical_upstream + "DESC," - + x.canonical_release + "DESC," - + x.revision + "DESC"; - } - - inline bool - operator< (const package_id& x, const package_id& y) - { - if (int r = x.name.compare (y.name)) - return r < 0; + package_id id; + upstream_version version; - return compare_version_lt (x.version, y.version, true); - } + // Database mapping. + // + #pragma db member(id) column("") + #pragma db member(version) set(this.version.init (this.id.version, (?))) + }; } #endif // BREP_PACKAGE diff --git a/brep/package.cxx b/brep/package.cxx index eacfabe..eaf1029 100644 --- a/brep/package.cxx +++ b/brep/package.cxx @@ -13,8 +13,6 @@ using namespace odb::core; namespace brep { - const version wildcard_version (0, "0", nullopt, 0); - // dependency // string dependency:: diff --git a/brep/package.xml b/brep/package.xml index 69f1a6a..39494ce 100644 --- a/brep/package.xml +++ b/brep/package.xml @@ -1,4 +1,4 @@ - + diff --git a/brep/utility b/brep/utility index 631af7f..b359fc6 100644 --- a/brep/utility +++ b/brep/utility @@ -27,6 +27,6 @@ namespace brep // // using butl::reverse_iterate; -}; +} #endif // BREP_UTILITY diff --git a/brep/version b/brep/version index f648b5e..e1db981 100644 --- a/brep/version +++ b/brep/version @@ -6,6 +6,7 @@ #include // LIBBUTL_VERSION #include // LIBBPKG_VERSION +#include // LIBBBOT_VERSION // Version format is AABBCCDD where // @@ -44,4 +45,8 @@ # error incompatible libbpkg version #endif +#if LIBBBOT_VERSION != 49901 +# error incompatible libbbot version +#endif + #endif // BREP_VERSION -- cgit v1.1