aboutsummaryrefslogtreecommitdiff
path: root/libbrep
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-09-05 21:23:41 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-09-08 17:44:57 +0300
commit70c1cdfd8f34472761fe5ec97f0713990c1b4f5b (patch)
treef2e631c10563bcc0cde07e4359c11b800a188d86 /libbrep
parent3be834183ae36c321e4b560dce9a63cee846e63d (diff)
Add multi-tenancy support
Diffstat (limited to 'libbrep')
-rw-r--r--libbrep/build-extra.sql8
-rw-r--r--libbrep/build-package.hxx46
-rw-r--r--libbrep/build.cxx7
-rw-r--r--libbrep/build.hxx63
-rw-r--r--libbrep/build.xml6
-rw-r--r--libbrep/common.hxx91
-rw-r--r--libbrep/package-extra.sql57
-rw-r--r--libbrep/package.cxx70
-rw-r--r--libbrep/package.hxx40
-rw-r--r--libbrep/package.xml107
-rw-r--r--libbrep/types.hxx2
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 &quot;C&quot;"/>
<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 &quot;C&quot;"/>
<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;