aboutsummaryrefslogtreecommitdiff
path: root/libbrep
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-07-04 11:27:47 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-07-05 15:22:37 +0300
commit6e90b57a442424876b1325b9209f79c8a885a479 (patch)
treebcdc8ee050c05799e17dcca12d7afc80274840d0 /libbrep
parent17d44ec2c41a5b485cecae51a07396f85a601248 (diff)
Make use of foreign package objects in build-related functionality
Diffstat (limited to 'libbrep')
-rw-r--r--libbrep/build-extra.sql15
-rw-r--r--libbrep/build-package.hxx69
-rw-r--r--libbrep/build.hxx59
-rw-r--r--libbrep/common.hxx29
-rw-r--r--libbrep/package.hxx44
5 files changed, 151 insertions, 65 deletions
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql
index 31736c8..6a222a7 100644
--- a/libbrep/build-extra.sql
+++ b/libbrep/build-extra.sql
@@ -3,11 +3,22 @@
-- file for details.
--
--- The foreign table for build_package object.
+DROP FOREIGN TABLE IF EXISTS build_package;
+
+DROP FOREIGN TABLE IF EXISTS build_repository;
+
+-- The foreign table for build_repository object.
--
--
-DROP FOREIGN TABLE IF EXISTS build_package;
+CREATE FOREIGN TABLE build_repository (
+ name TEXT NOT NULL,
+ location TEXT NOT NULL,
+ certificate_fingerprint TEXT NULL)
+SERVER package_server OPTIONS (table_name 'repository');
+-- The foreign table for build_package object.
+--
+--
CREATE FOREIGN TABLE build_package (
name TEXT NOT NULL,
version_epoch INTEGER NOT NULL,
diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx
index b0688c2..8bc703a 100644
--- a/libbrep/build-package.hxx
+++ b/libbrep/build-package.hxx
@@ -14,13 +14,39 @@
namespace brep
{
- // This is a "foreign object" that is mapped to the subset of package object
- // using PostgreSQL foreign table mechanism. Note that since we maintain the
- // two in sync by hand, we should only a have a minimal subset of "core"
- // members (ideally just the primary key) that are unlikly to disappear or
- // change.
+ // These are "foreign objects" that are mapped to subsets of the package
+ // database objects using the PostgreSQL foreign table mechanism. Note that
+ // since we maintain the pair in sync by hand, we should only have a minimal
+ // subset of "core" members (ideally just the primary key) that are unlikly
+ // to disappear or change.
//
- // The mapping is established in build-extra.sql.
+ // The mapping is established in build-extra.sql. We also explicitly mark
+ // non-primary key foreign-mapped members in the source object.
+ //
+ // Foreign object that is mapped to the subset of repository object.
+ //
+ #pragma db object table("build_repository") pointer(shared_ptr) readonly
+ class build_repository
+ {
+ public:
+ string name; // Object id (canonical name).
+ repository_location location;
+ optional<string> certificate_fingerprint;
+
+ // Database mapping.
+ //
+ #pragma db member(name) id
+
+ #pragma db member(location) \
+ set(this.location = std::move (?); \
+ assert (this.name == this.location.canonical_name ()))
+
+ private:
+ friend class odb::access;
+ build_repository () = default;
+ };
+
+ // Foreign object that is mapped to the subset of package object.
//
#pragma db object table("build_package") pointer(shared_ptr) readonly
class build_package
@@ -28,7 +54,7 @@ namespace brep
public:
package_id id;
upstream_version version;
- optional<string> internal_repository;
+ lazy_shared_ptr<build_repository> internal_repository;
// Database mapping.
//
@@ -40,8 +66,33 @@ namespace brep
build_package () = default;
};
- #pragma db view object(build_package)
- struct build_package_count
+ // 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, \
+ false))
+ struct buildable_package
+ {
+ package_id id;
+ upstream_version version;
+
+ // Database mapping.
+ //
+ #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, \
+ false))
+ struct buildable_package_count
{
size_t result;
diff --git a/libbrep/build.hxx b/libbrep/build.hxx
index 7a231bd..7f0aba6 100644
--- a/libbrep/build.hxx
+++ b/libbrep/build.hxx
@@ -57,10 +57,36 @@ namespace brep
inline bool
operator< (const build_id& x, const build_id& y)
{
- return
- x.package < y.package ? true :
- y.package < x.package ? false :
- x.configuration < y.configuration;
+ if (x.package != y.package)
+ return x.package < y.package;
+
+ if (int r = x.configuration.compare (y.configuration))
+ return r < 0;
+
+ return compare_version_lt (x.toolchain_version, y.toolchain_version, true);
+ }
+
+ // These allow comparing objects that have package, configuration and
+ // toolchain_version data members to build_id values. The idea is that this
+ // works for both query members of build id types as well as for values of
+ // the build_id type.
+ //
+ template <typename T>
+ inline auto
+ operator== (const T& x, const build_id& y)
+ -> decltype (x.package == y.package)
+ {
+ 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)
+ {
+ return x.package != y.package || x.configuration != y.configuration ||
+ compare_version_ne (x.toolchain_version, y.toolchain_version, true);
}
// build_state
@@ -267,26 +293,23 @@ namespace brep
// Build of an existing internal package.
//
- #pragma db view \
- object(build) \
- object(build_package inner: \
- build::id.package.name == build_package::id.name && \
- brep::compare_version_eq (build::id.package.version, \
- build_package::id.version, \
- true) && \
+ // 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 ())
struct package_build
{
shared_ptr<brep::build> build;
};
- #pragma db view \
- object(build) \
- object(build_package inner: \
- build::id.package.name == build_package::id.name && \
- brep::compare_version_eq (build::id.package.version, \
- build_package::id.version, \
- true) && \
+ #pragma db view \
+ object(build) \
+ object(build_package inner: \
+ brep::operator== (build::id.package, build_package::id) && \
build_package::internal_repository.is_not_null ())
struct package_build_count
{
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index 6bc5aca..56d6768 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -201,6 +201,13 @@ namespace brep
}
};
+ // repository_location
+ //
+ using bpkg::repository_location;
+
+ #pragma db map type(repository_location) as(string) \
+ to((?).string ()) from(brep::repository_location (?))
+
// Version comparison operators.
//
// They allow comparing objects that have epoch, canonical_upstream,
@@ -330,6 +337,8 @@ namespace brep
+ x.revision + "DESC";
}
+ // Package id comparison operators.
+ //
inline bool
operator< (const package_id& x, const package_id& y)
{
@@ -338,6 +347,26 @@ namespace brep
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.
+ //
+ 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)
+ {
+ return 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.name == y.name && x.version.epoch == y.version.epoch)
+ {
+ return x.name != y.name || compare_version_ne (x.version, y.version, true);
+ }
}
#endif // LIBBREP_COMMON_HXX
diff --git a/libbrep/package.hxx b/libbrep/package.hxx
index 4693a34..5a159ae 100644
--- a/libbrep/package.hxx
+++ b/libbrep/package.hxx
@@ -164,18 +164,11 @@ namespace brep
#pragma db value(requirement_alternatives) definition
- // repository_location
- //
- using bpkg::repository_location;
-
- #pragma db map type(repository_location) as(string) \
- to((?).string ()) from(brep::repository_location (?))
-
#pragma db value
class certificate
{
public:
- string fingerprint; // SHA256 fingerprint.
+ string fingerprint; // SHA256 fingerprint. Note: foreign-mapped in build.
string name; // CN component of Subject.
string organization; // O component of Subject.
string email; // email: in Subject Alternative Name.
@@ -202,8 +195,8 @@ namespace brep
explicit
repository (repository_location);
- string name; // Object id (canonical name).
- repository_location location;
+ string name; // Object id (canonical name).
+ repository_location location; // Note: foreign-mapped in build.
string display_name;
// The order in the internal repositories configuration file, starting from
@@ -224,7 +217,8 @@ namespace brep
//
repository_location cache_location;
- // Present only for internal signed repositories.
+ // Present only for internal signed repositories. Note that it is
+ // foreign-mapped in build.
//
optional<certificate_type> certificate;
@@ -342,6 +336,9 @@ namespace brep
optional<email_type> build_email;
dependencies_type dependencies;
requirements_type requirements;
+
+ // Note that it is foreign-mapped in build.
+ //
lazy_shared_ptr<repository_type> internal_repository;
// Path to the package file. Present only for internal packages.
@@ -483,31 +480,6 @@ namespace brep
{
package_id id;
};
-
- #pragma db view object(package) \
- object(repository: package::internal_repository)
- struct package_version
- {
- package_id id;
- upstream_version version;
-
- // Database mapping.
- //
- #pragma db member(version) set(this.version.init (this.id.version, (?)))
- };
-
- #pragma db view object(package) \
- object(repository: package::internal_repository)
- struct package_version_count
- {
- size_t result;
-
- operator size_t () const {return result;}
-
- // Database mapping.
- //
- #pragma db member(result) column("count(" + package::id.name + ")")
- };
}
#endif // LIBBREP_PACKAGE_HXX