From 70c1cdfd8f34472761fe5ec97f0713990c1b4f5b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 5 Sep 2018 21:23:41 +0300 Subject: Add multi-tenancy support --- libbrep/build-extra.sql | 8 +++- libbrep/build-package.hxx | 46 ++++++++++++-------- libbrep/build.cxx | 7 ++- libbrep/build.hxx | 63 ++++++++++++++------------- libbrep/build.xml | 6 +++ libbrep/common.hxx | 91 +++++++++++++++++++++++++++++++++++---- libbrep/package-extra.sql | 57 +++++++++++++++--------- libbrep/package.cxx | 70 ++++++++++++++++-------------- libbrep/package.hxx | 40 +++++++++++------ libbrep/package.xml | 107 ++++++++++++++++++++++++++++++++++++---------- libbrep/types.hxx | 2 + 11 files changed, 347 insertions(+), 150 deletions(-) (limited to 'libbrep') 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 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 afp, optional 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 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 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 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 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 @@ + @@ -26,6 +27,7 @@ + @@ -39,6 +41,7 @@
+ @@ -54,6 +57,7 @@ + @@ -65,6 +69,7 @@ + @@ -78,6 +83,7 @@ + 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 + 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 + 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 + 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 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 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 fr, optional sh, shared_ptr 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 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 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, @@ -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 @@
- + + @@ -22,56 +23,72 @@ - + +
- + + - + + - + + - + + - + + - + + - + +
- + + - + + - + + - + + - + + - + + - + +
+ @@ -99,12 +116,14 @@ - + + + @@ -112,9 +131,11 @@ - + + - + + @@ -122,6 +143,7 @@
+ @@ -130,12 +152,14 @@ + + @@ -144,6 +168,7 @@ + @@ -155,6 +180,7 @@
+ @@ -164,12 +190,14 @@ + + @@ -178,6 +206,7 @@ + @@ -186,6 +215,7 @@
+ @@ -194,12 +224,14 @@ + + @@ -208,6 +240,7 @@ + @@ -219,6 +252,7 @@
+ @@ -229,12 +263,14 @@ + + @@ -243,6 +279,7 @@ + @@ -254,6 +291,7 @@
+ @@ -276,18 +314,21 @@ + + + @@ -296,6 +337,7 @@ + @@ -303,12 +345,14 @@ + + @@ -318,6 +362,7 @@
+ @@ -328,12 +373,14 @@ + + @@ -342,6 +389,7 @@ + @@ -353,6 +401,7 @@
+ @@ -362,12 +411,14 @@ + + @@ -376,6 +427,7 @@ + @@ -384,6 +436,7 @@
+ @@ -395,12 +448,14 @@ + + @@ -409,6 +464,7 @@ + @@ -420,20 +476,24 @@
+ - + + + + @@ -442,6 +502,7 @@ + @@ -452,9 +513,11 @@ - + + - + +
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; using dir_paths = std::vector; + using butl::path_cast; + // // using butl::system_clock; -- cgit v1.1