diff options
Diffstat (limited to 'libbrep/common.hxx')
-rw-r--r-- | libbrep/common.hxx | 301 |
1 files changed, 254 insertions, 47 deletions
diff --git a/libbrep/common.hxx b/libbrep/common.hxx index 158690e..1433c8c 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -127,6 +127,20 @@ namespace brep std::chrono::duration_cast<brep::timestamp::duration> ( \ std::chrono::nanoseconds (?)))) + using optional_timestamp = optional<timestamp>; + using optional_uint64 = optional<uint64_t>; + + #pragma db map type(optional_timestamp) as(brep::optional_uint64) \ + to((?) \ + ? std::chrono::duration_cast<std::chrono::nanoseconds> ( \ + (?)->time_since_epoch ()).count () \ + : brep::optional_uint64 ()) \ + from((?) \ + ? brep::timestamp ( \ + std::chrono::duration_cast<brep::timestamp::duration> ( \ + std::chrono::nanoseconds (*(?)))) \ + : brep::optional_timestamp ()) + // version // using bpkg::version; @@ -312,6 +326,19 @@ namespace brep : tenant (move (t)), canonical_name (move (n)) {} }; + // public_key_id + // + #pragma db value + struct public_key_id + { + string tenant; + string fingerprint; + + public_key_id () = default; + public_key_id (string t, string f) + : tenant (move (t)), fingerprint (move (f)) {} + }; + // build_class_expr // using bpkg::build_class_expr; @@ -333,30 +360,61 @@ namespace brep #pragma db value(build_constraint) definition - // build_package_config + // build_auxiliaries + // + using bpkg::build_auxiliary; + using build_auxiliaries = vector<build_auxiliary>; + + #pragma db value(build_auxiliary) definition + + // build_toolchain + // + #pragma db value + struct build_toolchain + { + string name; + brep::version version; + }; + + // email // - using build_package_config = bpkg::build_package_config; + using bpkg::email; - #pragma db value(build_package_config) definition + #pragma db value(email) definition + #pragma db member(email::value) virtual(string) before access(this) column("") + + // build_package_config_template + // + using bpkg::build_package_config_template; // 1 for the default configuration which is always present. // - using build_package_configs = small_vector<build_package_config, 1>; + template <typename K> + using build_package_configs_template = + small_vector<build_package_config_template<K>, 1>; // Return the address of the configuration object with the specified name, // if present, and NULL otherwise. // - build_package_config* - find (const string& name, build_package_configs&); + template <typename K> + inline build_package_config_template<K>* + find (const string& name, build_package_configs_template<K>& cs) + { + auto i (find_if (cs.begin (), cs.end (), + [&name] (const build_package_config_template<K>& c) + {return c.name == name;})); + + return i != cs.end () ? &*i : nullptr; + } // Note that ODB doesn't support containers of value types which contain // containers. Thus, we will persist/load - // package_build_config::{builds,constraint} via the separate nested - // containers using the adapter classes. + // build_package_config_template<K>::{builds,constraint,auxiliaries,bot_keys} + // via the separate nested containers using the adapter classes. // - #pragma db member(build_package_config::builds) transient - #pragma db member(build_package_config::constraints) transient + // build_package_config_template<K>::builds + // using build_class_expr_key = odb::nested_key<build_class_exprs>; using build_class_exprs_map = std::map<build_class_expr_key, build_class_expr>; @@ -364,24 +422,27 @@ namespace brep #pragma db member(build_class_expr_key::outer) column("config_index") #pragma db member(build_class_expr_key::inner) column("index") - // Adapter for build_package_config::builds. + // Adapter for build_package_config_template<K>::builds. + // + // Note: 1 as for build_package_configs_template. // - class build_package_config_builds: - public small_vector<build_class_exprs, 1> // 1 as for build_package_configs. + class build_package_config_builds: public small_vector<build_class_exprs, 1> { public: build_package_config_builds () = default; + template <typename K> explicit - build_package_config_builds (const build_package_configs& cs) + build_package_config_builds (const build_package_configs_template<K>& cs) { reserve (cs.size ()); - for (const build_package_config& c: cs) + for (const build_package_config_template<K>& c: cs) push_back (c.builds); } + template <typename K> void - to_configs (build_package_configs& cs) && + to_configs (build_package_configs_template<K>& cs) && { // Note that the empty trailing entries will be missing (see ODB's // nested-container.hxx for details). @@ -394,6 +455,8 @@ namespace brep } }; + // build_package_config_template<K>::constraints + // using build_constraint_key = odb::nested_key<build_constraints>; using build_constraints_map = std::map<build_constraint_key, build_constraint>; @@ -401,24 +464,29 @@ namespace brep #pragma db member(build_constraint_key::outer) column("config_index") #pragma db member(build_constraint_key::inner) column("index") - // Adapter for build_package_config::constraints. + // Adapter for build_package_config_template<K>::constraints. + // + // Note: 1 as for build_package_configs_template. // class build_package_config_constraints: - public small_vector<build_constraints, 1> // 1 as for build_package_configs. + public small_vector<build_constraints, 1> { public: build_package_config_constraints () = default; + template <typename K> explicit - build_package_config_constraints (const build_package_configs& cs) + build_package_config_constraints ( + const build_package_configs_template<K>& cs) { reserve (cs.size ()); - for (const build_package_config& c: cs) + for (const build_package_config_template<K>& c: cs) push_back (c.constraints); } + template <typename K> void - to_configs (build_package_configs& cs) && + to_configs (build_package_configs_template<K>& cs) && { // Note that the empty trailing entries will be missing (see ODB's // nested-container.hxx for details). @@ -431,6 +499,84 @@ namespace brep } }; + // build_package_config_template<K>::auxiliaries + // + using build_auxiliary_key = odb::nested_key<build_auxiliaries>; + using build_auxiliaries_map = std::map<build_auxiliary_key, build_auxiliary>; + + #pragma db value(build_auxiliary_key) + #pragma db member(build_auxiliary_key::outer) column("config_index") + #pragma db member(build_auxiliary_key::inner) column("index") + + // Adapter for build_package_config_template<K>::auxiliaries. + // + // Note: 1 as for build_package_configs_template. + // + class build_package_config_auxiliaries: + public small_vector<build_auxiliaries, 1> + { + public: + build_package_config_auxiliaries () = default; + + template <typename K> + explicit + build_package_config_auxiliaries ( + const build_package_configs_template<K>& cs) + { + reserve (cs.size ()); + for (const build_package_config_template<K>& c: cs) + push_back (c.auxiliaries); + } + + template <typename K> + void + to_configs (build_package_configs_template<K>& cs) && + { + // Note that the empty trailing entries will be missing (see ODB's + // nested-container.hxx for details). + // + assert (size () <= cs.size ()); + + auto i (cs.begin ()); + for (build_auxiliaries& bas: *this) + i++->auxiliaries = move (bas); + } + }; + + // build_package_config_template<K>::bot_keys + // + // Adapter for build_package_config_template<K>::bot_keys. + // + // Note: 1 as for build_package_configs_template. + // + template <typename K> + class build_package_config_bot_keys: public small_vector<vector<K>, 1> + { + public: + build_package_config_bot_keys () = default; + + explicit + build_package_config_bot_keys (const build_package_configs_template<K>& cs) + { + this->reserve (cs.size ()); + for (const build_package_config_template<K>& c: cs) + this->push_back (c.bot_keys); + } + + void + to_configs (build_package_configs_template<K>& cs) && + { + // Note that the empty trailing entries will be missing (see ODB's + // nested-container.hxx for details). + // + assert (this->size () <= cs.size ()); + + auto i (cs.begin ()); + for (vector<K>& bks: *this) + i++->bot_keys = move (bks); + } + }; + // The primary reason why a package is unbuildable by the build bot // controller service. // @@ -510,15 +656,30 @@ namespace brep #pragma db member(requirement_key::middle) column("alternative_index") #pragma db member(requirement_key::inner) column("index") + // Third-party service state which may optionally be associated with a + // tenant (see also mod/tenant-service.hxx for background). + // + #pragma db value + struct tenant_service + { + string id; + string type; + optional<string> data; + + tenant_service () = default; + + tenant_service (string i, string t, optional<string> d = nullopt) + : id (move (i)), type (move (t)), data (move (d)) {} + }; + // 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. - // Note, though, that the object revisions should be comparable (both - // optional, numeric, etc), so to compare version to query member or - // canonical_version you may need to explicitly convert the version object - // to canonical_version. + // Compare 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. Note, though, that the + // object revisions should be comparable (both optional, numeric, etc), so + // to compare version to query member or canonical_version you may need to + // explicitly convert the version object to canonical_version. // template <typename T1, typename T2> inline auto @@ -670,10 +831,9 @@ namespace brep return compare_version_lt (x.version, y.version, true); } - // They allow comparing objects that have tenant, name, and version data - // members. The idea is that this works for both query members of package id - // types (in particular in join conditions) as well as for values of - // package_id type. + // Compare objects that have tenant, name, and version data members. The + // idea is that this works for both query members of package id types (in + // particular in join conditions) as well as for values of package_id type. // template <typename T1, typename T2> inline auto @@ -700,6 +860,27 @@ namespace brep } // Allow comparing the query members with the query parameters bound by + // reference to variables of the canonical version type (in particular in + // the prepared queries). + // + // Note that it is not operator==() since the query template parameter type + // can not be deduced from the function parameter types and needs to be + // specified explicitly. + // + template <typename T, typename V> + inline auto + equal (const V& x, const canonical_version& y) + -> decltype (x.epoch == odb::query<T>::_ref (y.epoch)) + { + using query = odb::query<T>; + + return x.epoch == query::_ref (y.epoch) && + x.canonical_upstream == query::_ref (y.canonical_upstream) && + x.canonical_release == query::_ref (y.canonical_release) && + x.revision == query::_ref (y.revision); + } + + // Allow comparing the query members with the query parameters bound by // reference to variables of the package id type (in particular in the // prepared queries). // @@ -710,21 +891,15 @@ namespace brep template <typename T, typename ID> inline auto equal (const ID& x, const package_id& y) - -> decltype (x.tenant == odb::query<T>::_ref (y.tenant) && - x.name == odb::query<T>::_ref (y.name) && + -> decltype (x.tenant == odb::query<T>::_ref (y.tenant) && + x.name == odb::query<T>::_ref (y.name) && x.version.epoch == odb::query<T>::_ref (y.version.epoch)) { using query = odb::query<T>; - const auto& qv (x.version); - const canonical_version& v (y.version); - - return x.tenant == query::_ref (y.tenant) && - x.name == query::_ref (y.name) && - qv.epoch == query::_ref (v.epoch) && - qv.canonical_upstream == query::_ref (v.canonical_upstream) && - qv.canonical_release == query::_ref (v.canonical_release) && - qv.revision == query::_ref (v.revision); + return x.tenant == query::_ref (y.tenant) && + x.name == query::_ref (y.name) && + equal<T> (x.version, y.version); } // Repository id comparison operators. @@ -738,10 +913,10 @@ namespace brep return x.canonical_name.compare (y.canonical_name) < 0; } - // They allow comparing objects that have tenant and canonical_name data - // members. The idea is that this works for both query members of repository - // id types (in particular in join conditions) as well as for values of - // repository_id type. + // Compare objects that have tenant and canonical_name data members. The + // idea is that this works for both query members of repository id types (in + // particular in join conditions) as well as for values of repository_id + // type. // template <typename T1, typename T2> inline auto @@ -758,6 +933,38 @@ namespace brep { return x.tenant != y.tenant || x.canonical_name != y.canonical_name; } + + // Public key id comparison operators. + // + inline bool + operator< (const public_key_id& x, const public_key_id& y) + { + if (int r = x.tenant.compare (y.tenant)) + return r < 0; + + return x.fingerprint.compare (y.fingerprint) < 0; + } + + // Compare objects that have tenant and fingerprint data members. The idea + // is that this works for both query members of public key id types (in + // particular in join conditions) as well as for values of public_key_id + // type. + // + template <typename T1, typename T2> + inline auto + operator== (const T1& x, const T2& y) + -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint) + { + return x.tenant == y.tenant && x.fingerprint == y.fingerprint; + } + + template <typename T1, typename T2> + inline auto + operator!= (const T1& x, const T2& y) + -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint) + { + return x.tenant != y.tenant || x.fingerprint != y.fingerprint; + } } #endif // LIBBREP_COMMON_HXX |