diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2018-09-05 21:23:41 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2018-09-08 17:44:57 +0300 |
commit | 70c1cdfd8f34472761fe5ec97f0713990c1b4f5b (patch) | |
tree | f2e631c10563bcc0cde07e4359c11b800a188d86 /libbrep | |
parent | 3be834183ae36c321e4b560dce9a63cee846e63d (diff) |
Add multi-tenancy support
Diffstat (limited to 'libbrep')
-rw-r--r-- | libbrep/build-extra.sql | 8 | ||||
-rw-r--r-- | libbrep/build-package.hxx | 46 | ||||
-rw-r--r-- | libbrep/build.cxx | 7 | ||||
-rw-r--r-- | libbrep/build.hxx | 63 | ||||
-rw-r--r-- | libbrep/build.xml | 6 | ||||
-rw-r--r-- | libbrep/common.hxx | 91 | ||||
-rw-r--r-- | libbrep/package-extra.sql | 57 | ||||
-rw-r--r-- | libbrep/package.cxx | 70 | ||||
-rw-r--r-- | libbrep/package.hxx | 40 | ||||
-rw-r--r-- | libbrep/package.xml | 107 | ||||
-rw-r--r-- | libbrep/types.hxx | 2 |
11 files changed, 347 insertions, 150 deletions
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql index e0aa92a..cc43239 100644 --- a/libbrep/build-extra.sql +++ b/libbrep/build-extra.sql @@ -13,7 +13,8 @@ DROP FOREIGN TABLE IF EXISTS build_repository; -- -- CREATE FOREIGN TABLE build_repository ( - name TEXT NOT NULL, + tenant TEXT NOT NULL, + canonical_name TEXT NOT NULL, location_url TEXT NOT NULL, location_type TEXT NOT NULL, certificate_fingerprint TEXT NULL) @@ -23,6 +24,7 @@ SERVER package_server OPTIONS (table_name 'repository'); -- -- CREATE FOREIGN TABLE build_package ( + tenant TEXT NOT NULL, name CITEXT NOT NULL, version_epoch INTEGER NOT NULL, version_canonical_upstream TEXT NOT NULL, @@ -30,7 +32,8 @@ CREATE FOREIGN TABLE build_package ( version_revision INTEGER NOT NULL, version_upstream TEXT NOT NULL, version_release TEXT NULL, - internal_repository TEXT NULL) + internal_repository_tenant TEXT NULL, + internal_repository_canonical_name TEXT NULL) SERVER package_server OPTIONS (table_name 'package'); -- The foreign table for the build_package object constraints member (that is @@ -38,6 +41,7 @@ SERVER package_server OPTIONS (table_name 'package'); -- -- CREATE FOREIGN TABLE build_package_constraints ( + tenant TEXT NOT NULL, name CITEXT NOT NULL, version_epoch INTEGER NOT NULL, version_canonical_upstream TEXT NOT NULL, diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx index ca65dbf..0fed500 100644 --- a/libbrep/build-package.hxx +++ b/libbrep/build-package.hxx @@ -29,21 +29,25 @@ namespace brep class build_repository { public: - string name; // Object id (canonical name). + repository_id id; + + const string& canonical_name; // Tracks id.canonical_name. repository_location location; optional<string> certificate_fingerprint; // Database mapping. // - #pragma db member(name) id + #pragma db member(id) id column("") - #pragma db member(location) \ - set(this.location = std::move (?); \ - assert (this.name == this.location.canonical_name ())) + #pragma db member(canonical_name) transient + + #pragma db member(location) \ + set(this.location = std::move (?); \ + assert (this.canonical_name == this.location.canonical_name ())) private: friend class odb::access; - build_repository () = default; + build_repository (): canonical_name (id.canonical_name) {} }; // "Foreign" value type that is mapped to a subset of the build_constraint @@ -85,12 +89,16 @@ namespace brep // Packages that can potentially be built (internal non-stub). // - #pragma db view \ - object(build_package) \ - object(build_repository inner: \ - build_package::internal_repository == build_repository::name && \ - brep::compare_version_ne (build_package::id.version, \ - brep::wildcard_version, \ + // Note that ADL can't find the equal operator, so we use the function call + // notation. + // + #pragma db view \ + object(build_package) \ + object(build_repository inner: \ + brep::operator== (build_package::internal_repository, \ + build_repository::id) && \ + brep::compare_version_ne (build_package::id.version, \ + brep::wildcard_version, \ false)) struct buildable_package { @@ -102,12 +110,13 @@ namespace brep #pragma db member(version) set(this.version.init (this.id.version, (?))) }; - #pragma db view \ - object(build_package) \ - object(build_repository inner: \ - build_package::internal_repository == build_repository::name && \ - brep::compare_version_ne (build_package::id.version, \ - brep::wildcard_version, \ + #pragma db view \ + object(build_package) \ + object(build_repository inner: \ + brep::operator== (build_package::internal_repository, \ + build_repository::id) && \ + brep::compare_version_ne (build_package::id.version, \ + brep::wildcard_version, \ false)) struct buildable_package_count { @@ -128,6 +137,7 @@ namespace brep table("build_package_constraints" = "c") \ object(build_package = package inner: \ "c.exclusion AND " \ + "c.tenant = " + package::id.tenant + "AND" + \ "c.name = " + package::id.name + "AND" + \ "c.version_epoch = " + package::id.version.epoch + "AND" + \ "c.version_canonical_upstream = " + \ diff --git a/libbrep/build.cxx b/libbrep/build.cxx index 6ed711c..c4b32d0 100644 --- a/libbrep/build.cxx +++ b/libbrep/build.cxx @@ -55,13 +55,16 @@ namespace brep // build // build:: - build (package_name_type pnm, version pvr, + build (string tnt, + package_name_type pnm, + version pvr, string cfg, string tnm, version tvr, optional<string> afp, optional<string> ach, string mnm, string msm, butl::target_triplet trg) - : id (package_id (move (pnm), pvr), move (cfg), tvr), + : id (package_id (move (tnt), move (pnm), pvr), move (cfg), tvr), + tenant (id.package.tenant), package_name (id.package.name), package_version (move (pvr)), configuration (id.configuration), diff --git a/libbrep/build.hxx b/libbrep/build.hxx index c72269c..d3c2051 100644 --- a/libbrep/build.hxx +++ b/libbrep/build.hxx @@ -74,19 +74,25 @@ namespace brep template <typename T> inline auto operator== (const T& x, const build_id& y) - -> decltype (x.package == y.package) + -> decltype (x.package == y.package && + x.configuration == y.configuration && + x.toolchain_version.epoch == y.toolchain_version.epoch) { - return x.package == y.package && x.configuration == y.configuration && - compare_version_eq (x.toolchain_version, y.toolchain_version, true); + return x.package == y.package && + x.configuration == y.configuration && + compare_version_eq (x.toolchain_version, y.toolchain_version, true); } template <typename T> inline auto operator!= (const T& x, const build_id& y) - -> decltype (x.package == y.package) + -> decltype (x.package == y.package && + x.configuration == y.configuration && + x.toolchain_version.epoch == y.toolchain_version.epoch) { - return x.package != y.package || x.configuration != y.configuration || - compare_version_ne (x.toolchain_version, y.toolchain_version, true); + return x.package != y.package || + x.configuration != y.configuration || + compare_version_ne (x.toolchain_version, y.toolchain_version, true); } // build_state @@ -167,7 +173,9 @@ namespace brep // Create the build object with the building state, non-existent status, // the timestamp set to now and the force state set to unforced. // - build (package_name_type, version, + build (string tenant, + package_name_type, + version, string configuration, string toolchain_name, version toolchain_version, optional<string> agent_fingerprint, @@ -177,6 +185,7 @@ namespace brep build_id id; + string& tenant; // Tracks id.package.tenant. package_name_type& package_name; // Tracks id.package.name. upstream_version package_version; // Original of id.package.version. string& configuration; // Tracks id.configuration. @@ -215,6 +224,7 @@ namespace brep // #pragma db member(id) id column("") + #pragma db member(tenant) transient #pragma db member(package_name) transient #pragma db member(package_version) \ set(this.package_version.init (this.id.package.version, (?))) @@ -232,20 +242,13 @@ namespace brep private: friend class odb::access; - build () - : package_name (id.package.name), configuration (id.configuration) {} - }; - - #pragma db view object(build) - struct build_count - { - size_t result; - operator size_t () const {return result;} - - // Database mapping. - // - #pragma db member(result) column("count(" + build::package_name + ")") + build () + : tenant (id.package.tenant), + package_name (id.package.name), + configuration (id.configuration) + { + } }; #pragma db view object(build) query(distinct) @@ -290,21 +293,21 @@ namespace brep // Note that ADL can't find the equal operator, so we use the function call // notation. // - #pragma db view \ - object(build) \ - object(build_package inner: \ - brep::operator== (build::id.package, build_package::id) && \ - build_package::internal_repository.is_not_null ()) + #pragma db view \ + object(build) \ + object(build_package inner: \ + brep::operator== (build::id.package, build_package::id) && \ + build_package::internal_repository.canonical_name.is_not_null ()) struct package_build { shared_ptr<brep::build> build; }; - #pragma db view \ - object(build) \ - object(build_package inner: \ - brep::operator== (build::id.package, build_package::id) && \ - build_package::internal_repository.is_not_null ()) + #pragma db view \ + object(build) \ + object(build_package inner: \ + brep::operator== (build::id.package, build_package::id) && \ + build_package::internal_repository.canonical_name.is_not_null ()) struct package_build_count { size_t result; diff --git a/libbrep/build.xml b/libbrep/build.xml index 0fd4154..0116374 100644 --- a/libbrep/build.xml +++ b/libbrep/build.xml @@ -1,6 +1,7 @@ <changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="build" version="1"> <model version="4"> <table name="build" kind="object"> + <column name="package_tenant" type="TEXT" null="false"/> <column name="package_name" type="CITEXT" null="false"/> <column name="package_version_epoch" type="INTEGER" null="false"/> <column name="package_version_canonical_upstream" type="TEXT" null="false"/> @@ -26,6 +27,7 @@ <column name="machine_summary" type="TEXT" null="false"/> <column name="target" type="TEXT" null="false"/> <primary-key> + <column name="package_tenant"/> <column name="package_name"/> <column name="package_version_epoch"/> <column name="package_version_canonical_upstream"/> @@ -39,6 +41,7 @@ </primary-key> </table> <table name="build_results" kind="container"> + <column name="package_tenant" type="TEXT" null="false"/> <column name="package_name" type="CITEXT" null="false"/> <column name="package_version_epoch" type="INTEGER" null="false"/> <column name="package_version_canonical_upstream" type="TEXT" null="false"/> @@ -54,6 +57,7 @@ <column name="status" type="TEXT" null="false"/> <column name="log" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="package_tenant"/> <column name="package_name"/> <column name="package_version_epoch"/> <column name="package_version_canonical_upstream"/> @@ -65,6 +69,7 @@ <column name="toolchain_version_canonical_release"/> <column name="toolchain_version_revision"/> <references table="build"> + <column name="package_tenant"/> <column name="package_name"/> <column name="package_version_epoch"/> <column name="package_version_canonical_upstream"/> @@ -78,6 +83,7 @@ </references> </foreign-key> <index name="build_results_object_id_i"> + <column name="package_tenant"/> <column name="package_name"/> <column name="package_version_epoch"/> <column name="package_version_canonical_upstream"/> diff --git a/libbrep/common.hxx b/libbrep/common.hxx index 0163ca0..b9adee8 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -203,12 +203,14 @@ namespace brep #pragma db value struct package_id { + string tenant; package_name name; canonical_version version; package_id () = default; - package_id (package_name n, const brep::version& v) - : name (move (n)), + package_id (string t, package_name n, const brep::version& v) + : tenant (move (t)), + name (move (n)), version { v.epoch, v.canonical_upstream, v.canonical_release, v.revision} { @@ -252,6 +254,19 @@ namespace brep : (?).type ()}) \ from(brep::repository_location (std::move ((?).url), (?).type)) + // repository_id + // + #pragma db value + struct repository_id + { + string tenant; + string canonical_name; + + repository_id () = default; + repository_id (string t, string n) + : tenant (move (t)), canonical_name (move (n)) {} + }; + // Version comparison operators. // // They allow comparing objects that have epoch, canonical_upstream, @@ -381,35 +396,93 @@ namespace brep + x.revision + "DESC"; } + template <typename T> + inline auto + order_by_version ( + const T& x, + bool first = true) -> //decltype ("ORDER BY" + x.epoch) + decltype (x.epoch == 0) + { + return (first ? "ORDER BY" : ", ") + + x.epoch + "," + + x.canonical_upstream + "," + + x.canonical_release + "," + + x.revision; + } + // Package id comparison operators. // inline bool operator< (const package_id& x, const package_id& y) { + if (int r = x.tenant.compare (y.tenant)) + return r < 0; + if (int r = x.name.compare (y.name)) return r < 0; return compare_version_lt (x.version, y.version, true); } - // They allow comparing objects that have 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. + // 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. + // + template <typename T1, typename T2> + inline auto + operator== (const T1& x, const T2& y) + -> decltype (x.tenant == y.tenant && + x.name == y.name && + x.version.epoch == y.version.epoch) + { + return x.tenant == y.tenant && + x.name == y.name && + compare_version_eq (x.version, y.version, true); + } + + template <typename T1, typename T2> + inline auto + operator!= (const T1& x, const T2& y) + -> decltype (x.tenant == y.tenant && + x.name == y.name && + x.version.epoch == y.version.epoch) + { + return x.tenant != y.tenant || + x.name != y.name || + compare_version_ne (x.version, y.version, true); + } + + // Repository id comparison operators. + // + inline bool + operator< (const repository_id& x, const repository_id& y) + { + if (int r = x.tenant.compare (y.tenant)) + return r < 0; + + 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. // template <typename T1, typename T2> inline auto operator== (const T1& x, const T2& y) - -> decltype (x.name == y.name && x.version.epoch == y.version.epoch) + -> decltype (x.tenant == y.tenant && x.canonical_name == y.canonical_name) { - return x.name == y.name && compare_version_eq (x.version, y.version, true); + return x.tenant == y.tenant && x.canonical_name == y.canonical_name; } template <typename T1, typename T2> inline auto operator!= (const T1& x, const T2& y) - -> decltype (x.name == y.name && x.version.epoch == y.version.epoch) + -> decltype (x.tenant == y.tenant && x.canonical_name == y.canonical_name) { - return x.name != y.name || compare_version_ne (x.version, y.version, true); + return x.tenant != y.tenant || x.canonical_name != y.canonical_name; } } diff --git a/libbrep/package-extra.sql b/libbrep/package-extra.sql index bd5a27b..d9930aa 100644 --- a/libbrep/package-extra.sql +++ b/libbrep/package-extra.sql @@ -17,10 +17,15 @@ -- -- DROP FUNCTION IF EXISTS to_tsvector(IN document weighted_text); -- -DROP FUNCTION IF EXISTS search_packages(IN query tsquery, INOUT name CITEXT); -DROP FUNCTION IF EXISTS search_latest_packages(IN query tsquery); -DROP FUNCTION IF EXISTS latest_package(INOUT name CITEXT); -DROP FUNCTION IF EXISTS latest_packages(); +DROP FUNCTION IF EXISTS search_packages(IN query tsquery, + IN tenant TEXT, + IN name CITEXT); + +DROP FUNCTION IF EXISTS search_latest_packages(IN query tsquery, + IN tenant TEXT); + +DROP FUNCTION IF EXISTS latest_package(IN tenant TEXT, IN name CITEXT); +DROP FUNCTION IF EXISTS latest_packages(IN tenant TEXT); DROP TYPE IF EXISTS weighted_text CASCADE; CREATE TYPE weighted_text AS (a TEXT, b TEXT, c TEXT, d TEXT); @@ -28,12 +33,14 @@ CREATE TYPE weighted_text AS (a TEXT, b TEXT, c TEXT, d TEXT); -- Return the latest versions of internal packages as a set of package rows. -- CREATE FUNCTION -latest_packages() +latest_packages(IN tenant TEXT) RETURNS SETOF package AS $$ SELECT p1.* FROM package p1 LEFT JOIN package p2 ON ( - p1.internal_repository IS NOT NULL AND p1.name = p2.name AND - p2.internal_repository IS NOT NULL AND + p1.internal_repository_canonical_name IS NOT NULL AND + p1.tenant = p2.tenant AND + p1.name = p2.name AND + p2.internal_repository_canonical_name IS NOT NULL AND (p1.version_epoch < p2.version_epoch OR p1.version_epoch = p2.version_epoch AND (p1.version_canonical_upstream < p2.version_canonical_upstream OR @@ -42,23 +49,26 @@ RETURNS SETOF package AS $$ p1.version_canonical_release = p2.version_canonical_release AND p1.version_revision < p2.version_revision)))) WHERE - p1.internal_repository IS NOT NULL AND p2.name IS NULL; + p1.tenant = latest_packages.tenant AND + p1.internal_repository_canonical_name IS NOT NULL AND + p2.name IS NULL; $$ LANGUAGE SQL STABLE; --- Find the latest version of an internal package having the specified name. --- Return a single row containing the package id, empty row set if the package --- not found. +-- Find the latest version of an internal package having the specified tenant +-- and name. Return a single row containing the package id, empty row set if +-- the package not found. -- CREATE FUNCTION -latest_package(INOUT name CITEXT, +latest_package(INOUT tenant TEXT, + INOUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, OUT version_canonical_release TEXT, OUT version_revision INTEGER) RETURNS SETOF record AS $$ - SELECT name, version_epoch, version_canonical_upstream, + SELECT tenant, name, version_epoch, version_canonical_upstream, version_canonical_release, version_revision - FROM latest_packages() + FROM latest_packages(latest_package.tenant) WHERE name = latest_package.name; $$ LANGUAGE SQL STABLE; @@ -69,6 +79,7 @@ $$ LANGUAGE SQL STABLE; -- CREATE FUNCTION search_latest_packages(IN query tsquery, + INOUT tenant TEXT, OUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, @@ -76,23 +87,25 @@ search_latest_packages(IN query tsquery, OUT version_revision INTEGER, OUT rank real) RETURNS SETOF record AS $$ - SELECT name, version_epoch, version_canonical_upstream, + SELECT tenant, name, version_epoch, version_canonical_upstream, version_canonical_release, version_revision, CASE WHEN query IS NULL THEN 0 -- Weight mapping: D C B A ELSE ts_rank_cd('{0.05, 0.2, 0.9, 1.0}', search_index, query) END AS rank - FROM latest_packages() + FROM latest_packages(search_latest_packages.tenant) WHERE query IS NULL OR search_index @@ query; $$ LANGUAGE SQL STABLE; --- Search for packages matching the search query and having the specified name. --- Return a set of rows containing the package id and search rank. If query --- is NULL, then match all packages and return 0 rank for all rows. +-- Search for packages matching the search query and having the specified +-- tenant and name. Return a set of rows containing the package id and search +-- rank. If query is NULL, then match all packages and return 0 rank for all +-- rows. -- CREATE FUNCTION search_packages(IN query tsquery, + INOUT tenant TEXT, INOUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, @@ -100,7 +113,7 @@ search_packages(IN query tsquery, OUT version_revision INTEGER, OUT rank real) RETURNS SETOF record AS $$ - SELECT name, version_epoch, version_canonical_upstream, + SELECT tenant, name, version_epoch, version_canonical_upstream, version_canonical_release, version_revision, CASE WHEN query IS NULL THEN 0 @@ -109,7 +122,9 @@ RETURNS SETOF record AS $$ END AS rank FROM package WHERE - internal_repository IS NOT NULL AND name = search_packages.name AND + tenant = search_packages.tenant AND + name = search_packages.name AND + internal_repository_canonical_name IS NOT NULL AND (query IS NULL OR search_index @@ query); $$ LANGUAGE SQL STABLE; diff --git a/libbrep/package.cxx b/libbrep/package.cxx index 6d4550d..41dd4e2 100644 --- a/libbrep/package.cxx +++ b/libbrep/package.cxx @@ -64,32 +64,32 @@ namespace brep optional<string> fr, optional<string> sh, shared_ptr<repository_type> rp) - : id (move (nm), vr), - version (move (vr)), - project (move (pn)), - priority (move (pr)), - summary (move (sm)), - license_alternatives (move (la)), - tags (move (tg)), - description (move (ds)), - changes (move (ch)), - url (move (ur)), - doc_url (move (du)), - src_url (move (su)), - package_url (move (pu)), - email (move (em)), - package_email (move (pe)), - build_email (move (be)), - dependencies (move (dp)), - requirements (move (rq)), - build_constraints ( - version.compare (wildcard_version, true) != 0 - ? move (bc) - : build_constraints_type ()), - internal_repository (move (rp)), - location (move (lc)), - fragment (move (fr)), - sha256sum (move (sh)) + : id (rp->tenant, move (nm), vr), + name (id.name), + version (move (vr)), + project (move (pn)), + priority (move (pr)), + summary (move (sm)), + license_alternatives (move (la)), + tags (move (tg)), + description (move (ds)), + changes (move (ch)), + url (move (ur)), + doc_url (move (du)), + src_url (move (su)), + package_url (move (pu)), + email (move (em)), + package_email (move (pe)), + build_email (move (be)), + dependencies (move (dp)), + requirements (move (rq)), + build_constraints (version.compare (wildcard_version, true) != 0 + ? move (bc) + : build_constraints_type ()), + internal_repository (move (rp)), + location (move (lc)), + fragment (move (fr)), + sha256sum (move (sh)) { assert (internal_repository->internal); } @@ -98,7 +98,8 @@ namespace brep package (package_name nm, version_type vr, shared_ptr<repository_type> rp) - : id (move (nm), vr), + : id (rp->tenant, move (nm), vr), + name (id.name), version (move (vr)) { assert (!rp->internal); @@ -121,7 +122,7 @@ namespace brep // Probably drop-box would be better as also tells what are // the available internal repositories. // - string k (project.string () + " " + id.name.string () + " " + + string k (project.string () + " " + name.string () + " " + version.string () + " " + version.string (true)); // Add tags to keywords. @@ -151,12 +152,15 @@ namespace brep // repository // repository:: - repository (repository_location l, + repository (string t, + repository_location l, string d, repository_location h, optional<certificate_type> c, uint16_t r) - : name (l.canonical_name ()), + : id (move (t), l.canonical_name ()), + tenant (id.tenant), + canonical_name (id.canonical_name), location (move (l)), display_name (move (d)), priority (r), @@ -167,8 +171,10 @@ namespace brep } repository:: - repository (repository_location l) - : name (l.canonical_name ()), + repository (string t, repository_location l) + : id (move (t), l.canonical_name ()), + tenant (id.tenant), + canonical_name (id.canonical_name), location (move (l)), priority (0), internal (false) diff --git a/libbrep/package.hxx b/libbrep/package.hxx index 3d281b0..4dbde29 100644 --- a/libbrep/package.hxx +++ b/libbrep/package.hxx @@ -171,6 +171,8 @@ namespace brep #pragma db value(build_constraint) definition + // certificate + // #pragma db value class certificate { @@ -191,7 +193,8 @@ namespace brep // Create internal repository. // - repository (repository_location, + repository (string tenant, + repository_location, string display_name, repository_location cache_location, optional<certificate_type>, @@ -200,9 +203,12 @@ namespace brep // Create external repository. // explicit - repository (repository_location); + repository (string tenant, repository_location); + + repository_id id; - string name; // Object id (canonical name). + const string& tenant; // Tracks id.tenant. + const string& canonical_name; // Tracks id.canonical_name. repository_location location; // Note: foreign-mapped in build. string display_name; @@ -243,21 +249,24 @@ namespace brep // Database mapping. // - #pragma db member(name) id + #pragma db member(id) id column("") - #pragma db member(location) \ - set(this.location = std::move (?); \ - assert (this.name == this.location.canonical_name ())) + #pragma db member(tenant) transient + #pragma db member(canonical_name) transient - #pragma db member(complements) id_column("repository") \ - value_column("complement") value_not_null + #pragma db member(location) \ + set(this.location = std::move (?); \ + assert (this.canonical_name == this.location.canonical_name ())) - #pragma db member(prerequisites) id_column("repository") \ - value_column("prerequisite") value_not_null + #pragma db member(complements) id_column("repository_") \ + value_column("complement_") value_not_null + + #pragma db member(prerequisites) id_column("repository_") \ + value_column("prerequisite_") value_not_null private: friend class odb::access; - repository () = default; + repository (): tenant (id.tenant), canonical_name (id.canonical_name) {} }; // The 'to' expression calls the PostgreSQL to_tsvector(weighted_text) @@ -336,6 +345,8 @@ namespace brep // Manifest data. // package_id id; + + const package_name& name; // Tracks id.name. upstream_version version; // Matches the package name if the project name is not specified in @@ -384,6 +395,7 @@ namespace brep // Database mapping. // #pragma db member(id) id column("") + #pragma db member(name) transient #pragma db member(version) set(this.version.init (this.id.version, (?))) // license @@ -453,7 +465,7 @@ namespace brep // other_repositories // #pragma db member(other_repositories) \ - id_column("") value_column("repository") value_not_null + id_column("") value_column("repository_") value_not_null // search_index // @@ -464,7 +476,7 @@ namespace brep private: friend class odb::access; - package () = default; + package (): name (id.name) {} // Save keywords, summary, description, and changes to weighted_text // a, b, c, d members, respectively. So a word found in keywords will diff --git a/libbrep/package.xml b/libbrep/package.xml index 55baae9..7b74349 100644 --- a/libbrep/package.xml +++ b/libbrep/package.xml @@ -1,7 +1,8 @@ <changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="package" version="1"> <model version="7"> <table name="repository" kind="object"> - <column name="name" type="TEXT" null="false"/> + <column name="tenant" type="TEXT" null="false"/> + <column name="canonical_name" type="TEXT" null="false"/> <column name="location_url" type="TEXT" null="false"/> <column name="location_type" type="TEXT" null="false"/> <column name="display_name" type="TEXT" null="false"/> @@ -22,56 +23,72 @@ <column name="repositories_timestamp" type="BIGINT" null="false"/> <column name="internal" type="BOOLEAN" null="false"/> <primary-key> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </primary-key> </table> <table name="repository_complements" kind="container"> - <column name="repository" type="TEXT" null="false"/> + <column name="repository_tenant" type="TEXT" null="false"/> + <column name="repository_canonical_name" type="TEXT" null="false"/> <column name="index" type="BIGINT" null="false"/> - <column name="complement" type="TEXT" null="false"/> + <column name="complement_tenant" type="TEXT" null="false"/> + <column name="complement_canonical_name" type="TEXT" null="false"/> <foreign-key name="repository_fk" on-delete="CASCADE"> - <column name="repository"/> + <column name="repository_tenant"/> + <column name="repository_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> <index name="repository_complements_repository_i"> - <column name="repository"/> + <column name="repository_tenant"/> + <column name="repository_canonical_name"/> </index> <index name="repository_complements_index_i"> <column name="index"/> </index> <foreign-key name="complement_fk" deferrable="DEFERRED"> - <column name="complement"/> + <column name="complement_tenant"/> + <column name="complement_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> </table> <table name="repository_prerequisites" kind="container"> - <column name="repository" type="TEXT" null="false"/> + <column name="repository_tenant" type="TEXT" null="false"/> + <column name="repository_canonical_name" type="TEXT" null="false"/> <column name="index" type="BIGINT" null="false"/> - <column name="prerequisite" type="TEXT" null="false"/> + <column name="prerequisite_tenant" type="TEXT" null="false"/> + <column name="prerequisite_canonical_name" type="TEXT" null="false"/> <foreign-key name="repository_fk" on-delete="CASCADE"> - <column name="repository"/> + <column name="repository_tenant"/> + <column name="repository_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> <index name="repository_prerequisites_repository_i"> - <column name="repository"/> + <column name="repository_tenant"/> + <column name="repository_canonical_name"/> </index> <index name="repository_prerequisites_index_i"> <column name="index"/> </index> <foreign-key name="prerequisite_fk" deferrable="DEFERRED"> - <column name="prerequisite"/> + <column name="prerequisite_tenant"/> + <column name="prerequisite_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> </table> <table name="package" kind="object"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -99,12 +116,14 @@ <column name="package_email_comment" type="TEXT" null="true"/> <column name="build_email" type="TEXT" null="true"/> <column name="build_email_comment" type="TEXT" null="true"/> - <column name="internal_repository" type="TEXT" null="true"/> + <column name="internal_repository_tenant" type="TEXT" null="true"/> + <column name="internal_repository_canonical_name" type="TEXT" null="true"/> <column name="location" type="TEXT" null="true"/> <column name="fragment" type="TEXT" null="true"/> <column name="sha256sum" type="TEXT" null="true"/> <column name="search_index" type="tsvector" null="true"/> <primary-key> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -112,9 +131,11 @@ <column name="version_revision"/> </primary-key> <foreign-key name="internal_repository_fk" deferrable="DEFERRED"> - <column name="internal_repository"/> + <column name="internal_repository_tenant"/> + <column name="internal_repository_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> <index name="package_search_index_i" method="GIN"> @@ -122,6 +143,7 @@ </index> </table> <table name="package_license_alternatives" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -130,12 +152,14 @@ <column name="index" type="BIGINT" null="false"/> <column name="comment" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -144,6 +168,7 @@ </references> </foreign-key> <index name="package_license_alternatives_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -155,6 +180,7 @@ </index> </table> <table name="package_licenses" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -164,12 +190,14 @@ <column name="index" type="BIGINT" null="false"/> <column name="license" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -178,6 +206,7 @@ </references> </foreign-key> <index name="package_licenses_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -186,6 +215,7 @@ </index> </table> <table name="package_tags" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -194,12 +224,14 @@ <column name="index" type="BIGINT" null="false"/> <column name="tag" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -208,6 +240,7 @@ </references> </foreign-key> <index name="package_tags_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -219,6 +252,7 @@ </index> </table> <table name="package_dependencies" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -229,12 +263,14 @@ <column name="buildtime" type="BOOLEAN" null="false"/> <column name="comment" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -243,6 +279,7 @@ </references> </foreign-key> <index name="package_dependencies_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -254,6 +291,7 @@ </index> </table> <table name="package_dependency_alternatives" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -276,18 +314,21 @@ <column name="dep_max_version_release" type="TEXT" null="true"/> <column name="dep_min_open" type="BOOLEAN" null="true"/> <column name="dep_max_open" type="BOOLEAN" null="true"/> + <column name="dep_package_tenant" type="TEXT" null="true"/> <column name="dep_package_name" type="CITEXT" null="true"/> <column name="dep_package_version_epoch" type="INTEGER" null="true"/> <column name="dep_package_version_canonical_upstream" type="TEXT" null="true"/> <column name="dep_package_version_canonical_release" type="TEXT" null="true" options="COLLATE "C""/> <column name="dep_package_version_revision" type="INTEGER" null="true"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -296,6 +337,7 @@ </references> </foreign-key> <index name="package_dependency_alternatives_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -303,12 +345,14 @@ <column name="version_revision"/> </index> <foreign-key name="dep_package_fk" deferrable="DEFERRED"> + <column name="dep_package_tenant"/> <column name="dep_package_name"/> <column name="dep_package_version_epoch"/> <column name="dep_package_version_canonical_upstream"/> <column name="dep_package_version_canonical_release"/> <column name="dep_package_version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -318,6 +362,7 @@ </foreign-key> </table> <table name="package_requirements" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -328,12 +373,14 @@ <column name="buildtime" type="BOOLEAN" null="false"/> <column name="comment" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -342,6 +389,7 @@ </references> </foreign-key> <index name="package_requirements_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -353,6 +401,7 @@ </index> </table> <table name="package_requirement_alternatives" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -362,12 +411,14 @@ <column name="index" type="BIGINT" null="false"/> <column name="id" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -376,6 +427,7 @@ </references> </foreign-key> <index name="package_requirement_alternatives_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -384,6 +436,7 @@ </index> </table> <table name="package_build_constraints" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> @@ -395,12 +448,14 @@ <column name="target" type="TEXT" null="true"/> <column name="comment" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -409,6 +464,7 @@ </references> </foreign-key> <index name="package_build_constraints_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -420,20 +476,24 @@ </index> </table> <table name="package_other_repositories" kind="container"> + <column name="tenant" type="TEXT" null="false"/> <column name="name" type="CITEXT" null="false"/> <column name="version_epoch" type="INTEGER" null="false"/> <column name="version_canonical_upstream" type="TEXT" null="false"/> <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE "C""/> <column name="version_revision" type="INTEGER" null="false"/> <column name="index" type="BIGINT" null="false"/> - <column name="repository" type="TEXT" null="false"/> + <column name="repository_tenant" type="TEXT" null="false"/> + <column name="repository_canonical_name" type="TEXT" null="false"/> <foreign-key name="object_id_fk" on-delete="CASCADE"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> <column name="version_canonical_release"/> <column name="version_revision"/> <references table="package"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -442,6 +502,7 @@ </references> </foreign-key> <index name="package_other_repositories_object_id_i"> + <column name="tenant"/> <column name="name"/> <column name="version_epoch"/> <column name="version_canonical_upstream"/> @@ -452,9 +513,11 @@ <column name="index"/> </index> <foreign-key name="repository_fk" deferrable="DEFERRED"> - <column name="repository"/> + <column name="repository_tenant"/> + <column name="repository_canonical_name"/> <references table="repository"> - <column name="name"/> + <column name="tenant"/> + <column name="canonical_name"/> </references> </foreign-key> </table> diff --git a/libbrep/types.hxx b/libbrep/types.hxx index 13d3d09..7c7b6ec 100644 --- a/libbrep/types.hxx +++ b/libbrep/types.hxx @@ -87,6 +87,8 @@ namespace brep using paths = std::vector<path>; using dir_paths = std::vector<dir_path>; + using butl::path_cast; + // <libbutl/timestamp.mxx> // using butl::system_clock; |