aboutsummaryrefslogtreecommitdiff
path: root/libbrep
diff options
context:
space:
mode:
Diffstat (limited to 'libbrep')
-rw-r--r--libbrep/build-extra.sql108
-rw-r--r--libbrep/build-package.hxx182
-rw-r--r--libbrep/build.cxx140
-rw-r--r--libbrep/build.hxx121
-rw-r--r--libbrep/build.xml85
-rw-r--r--libbrep/common.cxx10
-rw-r--r--libbrep/common.hxx301
-rwxr-xr-xlibbrep/odb.sh13
-rw-r--r--libbrep/package.cxx88
-rw-r--r--libbrep/package.hxx272
-rw-r--r--libbrep/package.xml278
-rw-r--r--libbrep/version.hxx.in4
12 files changed, 1429 insertions, 173 deletions
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql
index 7331ab1..9e51a51 100644
--- a/libbrep/build-extra.sql
+++ b/libbrep/build-extra.sql
@@ -6,12 +6,20 @@
-- package-extra.sql file for details.
--
+DROP FOREIGN TABLE IF EXISTS build_package_config_bot_keys;
+
+DROP FOREIGN TABLE IF EXISTS build_package_config_auxiliaries;
+
DROP FOREIGN TABLE IF EXISTS build_package_config_constraints;
DROP FOREIGN TABLE IF EXISTS build_package_config_builds;
DROP FOREIGN TABLE IF EXISTS build_package_configs;
+DROP FOREIGN TABLE IF EXISTS build_package_bot_keys;
+
+DROP FOREIGN TABLE IF EXISTS build_package_auxiliaries;
+
DROP FOREIGN TABLE IF EXISTS build_package_constraints;
DROP FOREIGN TABLE IF EXISTS build_package_builds;
@@ -26,6 +34,8 @@ DROP FOREIGN TABLE IF EXISTS build_package_requirements;
DROP FOREIGN TABLE IF EXISTS build_package;
+DROP FOREIGN TABLE IF EXISTS build_public_key;
+
DROP FOREIGN TABLE IF EXISTS build_repository;
DROP FOREIGN TABLE IF EXISTS build_tenant;
@@ -36,7 +46,18 @@ CREATE FOREIGN TABLE build_tenant (
id TEXT NOT NULL,
private BOOLEAN NOT NULL,
interactive TEXT NULL,
- archived BOOLEAN NOT NULL)
+ archived BOOLEAN NOT NULL,
+ service_id TEXT NULL,
+ service_type TEXT NULL,
+ service_data TEXT NULL,
+ queued_timestamp BIGINT NULL,
+ toolchain_name TEXT OPTIONS (column_name 'build_toolchain_name') NULL,
+ toolchain_version_epoch INTEGER OPTIONS (column_name 'build_toolchain_version_epoch') NULL,
+ toolchain_version_canonical_upstream TEXT OPTIONS (column_name 'build_toolchain_version_canonical_upstream') NULL,
+ toolchain_version_canonical_release TEXT OPTIONS (column_name 'build_toolchain_version_canonical_release') NULL,
+ toolchain_version_revision INTEGER OPTIONS (column_name 'build_toolchain_version_revision') NULL,
+ toolchain_version_upstream TEXT OPTIONS (column_name 'build_toolchain_version_upstream') NULL,
+ toolchain_version_release TEXT OPTIONS (column_name 'build_toolchain_version_release') NULL)
SERVER package_server OPTIONS (table_name 'tenant');
-- The foreign table for build_repository object.
@@ -49,6 +70,14 @@ CREATE FOREIGN TABLE build_repository (
certificate_fingerprint TEXT NULL)
SERVER package_server OPTIONS (table_name 'repository');
+-- The foreign table for build_public_key object.
+--
+CREATE FOREIGN TABLE build_public_key (
+ tenant TEXT NOT NULL,
+ fingerprint TEXT NOT NULL,
+ "data" TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'public_key');
+
-- The foreign table for build_package object.
--
CREATE FOREIGN TABLE build_package (
@@ -60,9 +89,17 @@ CREATE FOREIGN TABLE build_package (
version_revision INTEGER NOT NULL,
version_upstream TEXT NOT NULL,
version_release TEXT NULL,
+ project CITEXT NOT NULL,
+ build_email TEXT NULL,
+ build_email_comment TEXT NULL,
+ build_warning_email TEXT NULL,
+ build_warning_email_comment TEXT NULL,
+ build_error_email TEXT NULL,
+ build_error_email_comment TEXT NULL,
internal_repository_tenant TEXT NULL,
internal_repository_canonical_name TEXT NULL,
- buildable BOOLEAN NOT NULL)
+ buildable BOOLEAN NOT NULL,
+ custom_bot BOOLEAN NULL)
SERVER package_server OPTIONS (table_name 'package');
-- The foreign tables for the build_package object requirements member (that
@@ -140,6 +177,7 @@ CREATE FOREIGN TABLE build_package_tests (
test_package_version_revision INTEGER NULL,
test_type TEXT NOT NULL,
test_buildtime BOOLEAN NOT NULL,
+ test_enable TEXT NULL,
test_reflect TEXT NULL)
SERVER package_server OPTIONS (table_name 'package_tests');
@@ -175,6 +213,37 @@ CREATE FOREIGN TABLE build_package_constraints (
comment TEXT NOT NULL)
SERVER package_server OPTIONS (table_name 'package_build_constraints');
+-- The foreign table for the build_package object auxiliaries member (that is
+-- of a container type).
+--
+CREATE FOREIGN TABLE build_package_auxiliaries (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ index BIGINT NOT NULL,
+ environment_name TEXT NOT NULL,
+ config TEXT NOT NULL,
+ comment TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_auxiliaries');
+
+-- The foreign table for the build_package object bot_keys member (that is
+-- of a container type).
+--
+CREATE FOREIGN TABLE build_package_bot_keys (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ index BIGINT NOT NULL,
+ key_tenant TEXT NOT NULL,
+ key_fingerprint TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_bot_keys');
+
-- The foreign tables for the build_package object configs member (that is a
-- container of values containing containers.
--
@@ -188,7 +257,13 @@ CREATE FOREIGN TABLE build_package_configs (
index BIGINT NOT NULL,
config_name TEXT NOT NULL,
config_arguments TEXT NULL,
- config_comment TEXT NOT NULL)
+ config_comment TEXT NOT NULL,
+ config_email TEXT NULL,
+ config_email_comment TEXT NULL,
+ config_warning_email TEXT NULL,
+ config_warning_email_comment TEXT NULL,
+ config_error_email TEXT NULL,
+ config_error_email_comment TEXT NULL)
SERVER package_server OPTIONS (table_name 'package_build_configs');
CREATE FOREIGN TABLE build_package_config_builds (
@@ -218,3 +293,30 @@ CREATE FOREIGN TABLE build_package_config_constraints (
target TEXT NULL,
comment TEXT NOT NULL)
SERVER package_server OPTIONS (table_name 'package_build_config_constraints');
+
+CREATE FOREIGN TABLE build_package_config_auxiliaries (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ config_index BIGINT NOT NULL,
+ index BIGINT NOT NULL,
+ environment_name TEXT NOT NULL,
+ config TEXT NOT NULL,
+ comment TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_config_auxiliaries');
+
+CREATE FOREIGN TABLE build_package_config_bot_keys (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ config_index BIGINT NOT NULL,
+ index BIGINT NOT NULL,
+ key_tenant TEXT NOT NULL,
+ key_fingerprint TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_config_bot_keys');
diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx
index 6ca8702..9a9c277 100644
--- a/libbrep/build-package.hxx
+++ b/libbrep/build-package.hxx
@@ -5,6 +5,7 @@
#define LIBBREP_BUILD_PACKAGE_HXX
#include <odb/core.hxx>
+#include <odb/section.hxx>
#include <odb/nested-container.hxx>
#include <libbrep/types.hxx>
@@ -22,9 +23,11 @@ namespace brep
//
// 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 a subset of the tenant object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_tenant") pointer(shared_ptr)
class build_tenant
{
@@ -34,6 +37,9 @@ namespace brep
bool private_;
optional<string> interactive;
bool archived;
+ optional<tenant_service> service;
+ optional<timestamp> queued_timestamp;
+ optional<build_toolchain> toolchain;
// Database mapping.
//
@@ -46,6 +52,8 @@ namespace brep
// Foreign object that is mapped to a subset of the repository object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_repository") pointer(shared_ptr) readonly
class build_repository
{
@@ -71,6 +79,54 @@ namespace brep
build_repository (): canonical_name (id.canonical_name) {}
};
+ // Foreign object that is mapped to a subset of the public key object.
+ //
+ // Note: table created manually thus assign table name explicitly.
+ //
+ #pragma db object table("build_public_key") pointer(shared_ptr) readonly
+ class build_public_key: public string
+ {
+ public:
+ public_key_id id;
+
+ // Database mapping.
+ //
+ #pragma db member(id) id column("")
+
+ #pragma db member(data) virtual(string) access(this)
+
+ private:
+ friend class odb::access;
+ build_public_key () = default;
+ };
+
+ // build_package_config
+ //
+ using build_package_config =
+ build_package_config_template<lazy_shared_ptr<build_public_key>>;
+
+ using build_package_configs =
+ build_package_configs_template<lazy_shared_ptr<build_public_key>>;
+
+ #pragma db value(build_package_config) definition
+
+ #pragma db member(build_package_config::builds) transient
+ #pragma db member(build_package_config::constraints) transient
+ #pragma db member(build_package_config::auxiliaries) transient
+ #pragma db member(build_package_config::bot_keys) transient
+
+ // build_package_bot_keys
+ //
+ using build_package_bot_keys = vector<lazy_shared_ptr<build_public_key>>;
+ using build_package_bot_key_key = odb::nested_key<build_package_bot_keys>;
+
+ using build_package_bot_keys_map =
+ std::map<build_package_bot_key_key, lazy_shared_ptr<build_public_key>>;
+
+ #pragma db value(build_package_bot_key_key)
+ #pragma db member(build_package_bot_key_key::outer) column("config_index")
+ #pragma db member(build_package_bot_key_key::inner) column("index")
+
// Forward declarations.
//
class build_package;
@@ -97,11 +153,14 @@ namespace brep
{
test_dependency_type type;
bool buildtime;
+ optional<string> enable;
optional<string> reflect;
};
// Foreign object that is mapped to a subset of the package object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_package") pointer(shared_ptr) readonly session
class build_package
{
@@ -111,21 +170,42 @@ namespace brep
package_id id;
upstream_version version;
+ package_name project;
+
+ optional<email> build_email;
+ optional<email> build_warning_email;
+ optional<email> build_error_email;
+
// Mapped to the package object requirements and tests members using the
// PostgreSQL foreign table mechanism.
//
requirements_type requirements;
small_vector<build_test_dependency, 1> tests;
+ odb::section requirements_tests_section;
+
lazy_shared_ptr<build_repository> internal_repository;
bool buildable;
+ optional<bool> custom_bot;
- // Mapped to the package object builds, build_constraints, and
- // build_configs members using the PostgreSQL foreign table mechanism.
+ // Mapped to the package object builds, build_constraints,
+ // build_auxiliaries, bot_keys, and build_configs members using the
+ // PostgreSQL foreign table mechanism.
//
- build_class_exprs builds;
- build_constraints constraints;
- build_package_configs configs;
+ build_class_exprs builds;
+ build_constraints constraints;
+ build_auxiliaries auxiliaries;
+ build_package_bot_keys bot_keys;
+ build_package_configs configs;
+
+ // Group the builds/constraints, auxiliaries, and bot_keys members of this
+ // object together with their respective nested configs entries into the
+ // separate sections for an explicit load. Note that the configs top-level
+ // members are loaded implicitly.
+ //
+ odb::section constraints_section;
+ odb::section auxiliaries_section;
+ odb::section bot_keys_section;
bool
internal () const noexcept {return internal_repository != nullptr;}
@@ -143,7 +223,8 @@ namespace brep
// Container of the requirement_alternatives values.
//
- #pragma db member(requirements) id_column("") value_column("")
+ #pragma db member(requirements) id_column("") value_column("") \
+ section(requirements_tests_section)
// Container of the requirement_alternative values.
//
@@ -152,7 +233,8 @@ namespace brep
after(requirements) \
get(odb::nested_get (this.requirements)) \
set(odb::nested_set (this.requirements, std::move (?))) \
- id_column("") key_column("") value_column("")
+ id_column("") key_column("") value_column("") \
+ section(requirements_tests_section)
// Container of the requirement (string) values.
//
@@ -161,19 +243,35 @@ namespace brep
after(requirement_alternatives) \
get(odb::nested2_get (this.requirements)) \
set(odb::nested2_set (this.requirements, std::move (?))) \
- id_column("") key_column("") value_column("id")
+ id_column("") key_column("") value_column("id") \
+ section(requirements_tests_section)
+
+ // tests
+ //
+ #pragma db member(tests) id_column("") value_column("test_") \
+ section(requirements_tests_section)
- // tests, builds, and constraints
+ #pragma db member(requirements_tests_section) load(lazy) update(always)
+
+ // builds, constraints, auxiliaries, and bot_keys
//
- #pragma db member(tests) id_column("") value_column("test_")
- #pragma db member(builds) id_column("") value_column("")
- #pragma db member(constraints) id_column("") value_column("")
+ #pragma db member(builds) id_column("") value_column("") \
+ section(constraints_section)
+
+ #pragma db member(constraints) id_column("") value_column("") \
+ section(constraints_section)
+
+ #pragma db member(auxiliaries) id_column("") value_column("") \
+ section(auxiliaries_section)
+
+ #pragma db member(bot_keys) id_column("") value_column("key_") \
+ section(bot_keys_section)
// configs
//
- // Note that build_package_config::{builds,constraints} are
- // persisted/loaded via the separate nested containers (see commons.hxx
- // for details).
+ // Note that build_package_config::{builds,constraints,auxiliaries,bot_keys}
+ // are persisted/loaded via the separate nested containers (see
+ // commons.hxx for details).
//
#pragma db member(configs) id_column("") value_column("config_")
@@ -185,7 +283,8 @@ namespace brep
set(brep::build_package_config_builds bs; \
odb::nested_set (bs, std::move (?)); \
move (bs).to_configs (this.configs)) \
- id_column("") key_column("") value_column("")
+ id_column("") key_column("") value_column("") \
+ section(constraints_section)
#pragma db member(config_constraints) \
virtual(build_constraints_map) \
@@ -195,13 +294,53 @@ namespace brep
set(brep::build_package_config_constraints cs; \
odb::nested_set (cs, std::move (?)); \
move (cs).to_configs (this.configs)) \
- id_column("") key_column("") value_column("")
+ id_column("") key_column("") value_column("") \
+ section(constraints_section)
+
+ #pragma db member(config_auxiliaries) \
+ virtual(build_auxiliaries_map) \
+ after(config_constraints) \
+ get(odb::nested_get ( \
+ brep::build_package_config_auxiliaries (this.configs))) \
+ set(brep::build_package_config_auxiliaries as; \
+ odb::nested_set (as, std::move (?)); \
+ move (as).to_configs (this.configs)) \
+ id_column("") key_column("") value_column("") \
+ section(auxiliaries_section)
+
+ #pragma db member(config_bot_keys) \
+ virtual(build_package_bot_keys_map) \
+ after(config_auxiliaries) \
+ get(odb::nested_get ( \
+ brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::build_public_key>> (this.configs))) \
+ set(brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::build_public_key>> bks; \
+ odb::nested_set (bks, std::move (?)); \
+ move (bks).to_configs (this.configs)) \
+ id_column("") key_column("") value_column("key_") \
+ section(bot_keys_section)
+
+ #pragma db member(constraints_section) load(lazy) update(always)
+ #pragma db member(auxiliaries_section) load(lazy) update(always)
+ #pragma db member(bot_keys_section) load(lazy) update(always)
private:
friend class odb::access;
build_package () = default;
};
+ #pragma db view object(build_package)
+ struct build_package_version
+ {
+ package_id id;
+ upstream_version version;
+
+ // Database mapping.
+ //
+ #pragma db member(version) set(this.version.init (this.id.version, (?)))
+ };
+
// Packages that can potentially be built.
//
// Note that ADL can't find the equal operator, so we use the function call
@@ -216,14 +355,13 @@ namespace brep
object(build_tenant: build_package::id.tenant == build_tenant::id)
struct buildable_package
{
- package_id id;
- upstream_version version;
+ shared_ptr<build_package> package;
bool archived; // True if the tenant the package belongs to is archived.
- // Database mapping.
+ // Present if the tenant the package belongs to is interactive.
//
- #pragma db member(version) set(this.version.init (this.id.version, (?)))
+ optional<string> interactive;
};
#pragma db view \
diff --git a/libbrep/build.cxx b/libbrep/build.cxx
index c8a2cd1..13f0818 100644
--- a/libbrep/build.cxx
+++ b/libbrep/build.cxx
@@ -12,6 +12,7 @@ namespace brep
{
switch (s)
{
+ case build_state::queued: return "queued";
case build_state::building: return "building";
case build_state::built: return "built";
}
@@ -22,7 +23,8 @@ namespace brep
build_state
to_build_state (const string& s)
{
- if (s == "building") return build_state::building;
+ if (s == "queued") return build_state::queued;
+ else if (s == "building") return build_state::building;
else if (s == "built") return build_state::built;
else throw invalid_argument ("invalid build state '" + s + '\'');
}
@@ -63,7 +65,8 @@ namespace brep
string tnm, version tvr,
optional<string> inr,
optional<string> afp, optional<string> ach,
- string mnm, string msm,
+ build_machine mcn,
+ vector<build_machine> ams,
string ccs,
string mcs)
: id (package_id (move (tnt), move (pnm), pvr),
@@ -84,13 +87,142 @@ namespace brep
timestamp (timestamp_type::clock::now ()),
force (force_state::unforced),
agent_fingerprint (move (afp)), agent_challenge (move (ach)),
- machine (move (mnm)),
- machine_summary (move (msm)),
+ machine (move (mcn)),
+ auxiliary_machines (move (ams)),
controller_checksum (move (ccs)),
machine_checksum (move (mcs))
{
}
+ build::
+ build (string tnt,
+ package_name_type pnm,
+ version pvr,
+ target_triplet trg,
+ string tcf,
+ string pcf,
+ string tnm, version tvr)
+ : id (package_id (move (tnt), move (pnm), pvr),
+ move (trg),
+ move (tcf),
+ move (pcf),
+ move (tnm), tvr),
+ tenant (id.package.tenant),
+ package_name (id.package.name),
+ package_version (move (pvr)),
+ target (id.target),
+ target_config_name (id.target_config_name),
+ package_config_name (id.package_config_name),
+ toolchain_name (id.toolchain_name),
+ toolchain_version (move (tvr)),
+ state (build_state::queued),
+ timestamp (timestamp_type::clock::now ()),
+ force (force_state::unforced)
+ {
+ }
+
+ build::
+ build (string tnt,
+ package_name_type pnm,
+ version pvr,
+ target_triplet trg,
+ string tcf,
+ string pcf,
+ string tnm, version tvr,
+ result_status rst,
+ operation_results ors,
+ build_machine mcn,
+ vector<build_machine> ams)
+ : id (package_id (move (tnt), move (pnm), pvr),
+ move (trg),
+ move (tcf),
+ move (pcf),
+ move (tnm), tvr),
+ tenant (id.package.tenant),
+ package_name (id.package.name),
+ package_version (move (pvr)),
+ target (id.target),
+ target_config_name (id.target_config_name),
+ package_config_name (id.package_config_name),
+ toolchain_name (id.toolchain_name),
+ toolchain_version (move (tvr)),
+ state (build_state::built),
+ timestamp (timestamp_type::clock::now ()),
+ force (force_state::unforced),
+ status (rst),
+ soft_timestamp (timestamp),
+ hard_timestamp (timestamp),
+ machine (move (mcn)),
+ auxiliary_machines (move (ams)),
+ results (move (ors))
+ {
+ }
+
+ build::
+ build (build&& b)
+ : id (move (b.id)),
+ tenant (id.package.tenant),
+ package_name (id.package.name),
+ package_version (move (b.package_version)),
+ target (id.target),
+ target_config_name (id.target_config_name),
+ package_config_name (id.package_config_name),
+ toolchain_name (id.toolchain_name),
+ toolchain_version (move (b.toolchain_version)),
+ state (b.state),
+ interactive (move (b.interactive)),
+ timestamp (b.timestamp),
+ force (b.force),
+ status (b.status),
+ soft_timestamp (b.soft_timestamp),
+ hard_timestamp (b.hard_timestamp),
+ agent_fingerprint (move (b.agent_fingerprint)),
+ agent_challenge (move (b.agent_challenge)),
+ machine (move (b.machine)),
+ auxiliary_machines (move (b.auxiliary_machines)),
+ auxiliary_machines_section (move (b.auxiliary_machines_section)),
+ results (move (b.results)),
+ results_section (move (b.results_section)),
+ controller_checksum (move (b.controller_checksum)),
+ machine_checksum (move (b.machine_checksum)),
+ agent_checksum (move (b.agent_checksum)),
+ worker_checksum (move (b.worker_checksum)),
+ dependency_checksum (move (b.dependency_checksum))
+ {
+ }
+
+ build& build::
+ operator= (build&& b)
+ {
+ if (this != &b)
+ {
+ id = move (b.id);
+ package_version = move (b.package_version);
+ toolchain_version = move (b.toolchain_version);
+ state = b.state;
+ interactive = move (b.interactive);
+ timestamp = b.timestamp;
+ force = b.force;
+ status = b.status;
+ soft_timestamp = b.soft_timestamp;
+ hard_timestamp = b.hard_timestamp;
+ agent_fingerprint = move (b.agent_fingerprint);
+ agent_challenge = move (b.agent_challenge);
+ machine = move (b.machine);
+ auxiliary_machines = move (b.auxiliary_machines);
+ auxiliary_machines_section = move (b.auxiliary_machines_section);
+ results = move (b.results);
+ results_section = move (b.results_section);
+ controller_checksum = move (b.controller_checksum);
+ machine_checksum = move (b.machine_checksum);
+ agent_checksum = move (b.agent_checksum);
+ worker_checksum = move (b.worker_checksum);
+ dependency_checksum = move (b.dependency_checksum);
+ }
+
+ return *this;
+ }
+
// build_delay
//
build_delay::
diff --git a/libbrep/build.hxx b/libbrep/build.hxx
index eaceebc..af49c03 100644
--- a/libbrep/build.hxx
+++ b/libbrep/build.hxx
@@ -28,7 +28,7 @@
//
#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 20
-#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 20, closed)
+#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 27, closed)
// We have to keep these mappings at the global scope instead of inside the
// brep namespace because they need to be also effective in the bbot namespace
@@ -127,10 +127,51 @@ namespace brep
compare_version_ne (x.toolchain_version, y.toolchain_version, true);
}
+ // Allow comparing the query members with the query parameters bound by
+ // reference to variables of the build id type (in particular in the
+ // prepared queries).
+ //
+ // Note that it is not operator==() since the query template parameter type
+ // can not be deduced from the function parameter types and needs to be
+ // specified explicitly.
+ //
+ template <typename T, typename ID>
+ inline auto
+ equal (const ID& x, const build_id& y, bool toolchain_version = true)
+ -> decltype (x.package.tenant == odb::query<T>::_ref (y.package.tenant) &&
+ x.package.name == odb::query<T>::_ref (y.package.name) &&
+ x.package.version.epoch ==
+ odb::query<T>::_ref (y.package.version.epoch) &&
+ x.target_config_name ==
+ odb::query<T>::_ref (y.target_config_name) &&
+ x.toolchain_name == odb::query<T>::_ref (y.toolchain_name) &&
+ x.toolchain_version.epoch ==
+ odb::query<T>::_ref (y.toolchain_version.epoch))
+ {
+ using query = odb::query<T>;
+
+ query r (equal<T> (x.package, y.package) &&
+ x.target == query::_ref (y.target) &&
+ x.target_config_name == query::_ref (y.target_config_name) &&
+ x.package_config_name == query::_ref (y.package_config_name) &&
+ x.toolchain_name == query::_ref (y.toolchain_name));
+
+ if (toolchain_version)
+ r = r && equal<T> (x.toolchain_version, y.toolchain_version);
+
+ return r;
+ }
+
// build_state
//
+ // The queued build state is semantically equivalent to a non-existent
+ // build. It is only used for those tenants, which have a third-party
+ // service associated that requires the `queued` notifications (see
+ // mod/tenant-service.hxx for background).
+ //
enum class build_state: std::uint8_t
{
+ queued,
building,
built
};
@@ -189,6 +230,13 @@ namespace brep
using bbot::operation_results;
+ #pragma db value
+ struct build_machine
+ {
+ string name;
+ string summary;
+ };
+
#pragma db object pointer(shared_ptr) session
class build
{
@@ -208,10 +256,43 @@ namespace brep
optional<string> interactive,
optional<string> agent_fingerprint,
optional<string> agent_challenge,
- string machine, string machine_summary,
+ build_machine,
+ vector<build_machine> auxiliary_machines,
string controller_checksum,
string machine_checksum);
+ // Create the build object with the queued state.
+ //
+ build (string tenant,
+ package_name_type, version,
+ target_triplet,
+ string target_config_name,
+ string package_config_name,
+ string toolchain_name, version toolchain_version);
+
+ // Create the build object with the built state, the specified status and
+ // operation results, all the timestamps set to now, and the force state
+ // set to unforced.
+ //
+ build (string tenant,
+ package_name_type, version,
+ target_triplet,
+ string target_config_name,
+ string package_config_name,
+ string toolchain_name, version toolchain_version,
+ result_status,
+ operation_results,
+ build_machine,
+ vector<build_machine> auxiliary_machines = {});
+
+ // Move-only type.
+ //
+ build (build&&);
+ build& operator= (build&&);
+
+ build (const build&) = delete;
+ build& operator= (const build&) = delete;
+
build_id id;
string& tenant; // Tracks id.package.tenant.
@@ -267,8 +348,9 @@ namespace brep
optional<string> agent_fingerprint;
optional<string> agent_challenge;
- string machine;
- string machine_summary;
+ build_machine machine;
+ vector<build_machine> auxiliary_machines;
+ odb::section auxiliary_machines_section;
// Note that the logs are stored as std::string/TEXT which is Ok since
// they are UTF-8 and our database is UTF-8.
@@ -310,14 +392,24 @@ namespace brep
//
#pragma db member(timestamp) index
+ #pragma db member(machine) transient
+
+ #pragma db member(machine_name) virtual(std::string) \
+ access(machine.name) column("machine")
+
+ #pragma db member(machine_summary) virtual(std::string) \
+ access(machine.summary)
+
+ #pragma db member(auxiliary_machines) id_column("") value_column("") \
+ section(auxiliary_machines_section)
+
+ #pragma db member(auxiliary_machines_section) load(lazy) update(always)
+
#pragma db member(results) id_column("") value_column("") \
section(results_section)
#pragma db member(results_section) load(lazy) update(always)
- build (const build&) = delete;
- build& operator= (const build&) = delete;
-
private:
friend class odb::access;
@@ -377,7 +469,7 @@ namespace brep
canonical_version version_;
};
- // Build of an existing buildable package.
+ // Builds of existing buildable packages.
//
#pragma db view \
object(build) \
@@ -408,6 +500,19 @@ namespace brep
#pragma db member(result) column("count(" + build::id.package.name + ")")
};
+ // Ids of existing buildable package builds.
+ //
+ #pragma db view object(build) \
+ object(build_package inner: \
+ brep::operator== (build::id.package, build_package::id) && \
+ build_package::buildable)
+ struct package_build_id
+ {
+ build_id id;
+
+ operator build_id& () {return id;}
+ };
+
// Used to track the package build delays since the last build or, if not
// present, since the first opportunity to build the package.
//
diff --git a/libbrep/build.xml b/libbrep/build.xml
index d1969f1..1eba85a 100644
--- a/libbrep/build.xml
+++ b/libbrep/build.xml
@@ -1,4 +1,89 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="build" version="1">
+ <changeset version="27"/>
+
+ <changeset version="26"/>
+
+ <changeset version="25">
+ <add-table name="build_auxiliary_machines" 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"/>
+ <column name="package_version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="package_version_revision" type="INTEGER" null="false"/>
+ <column name="target" type="TEXT" null="false"/>
+ <column name="target_config_name" type="TEXT" null="false"/>
+ <column name="package_config_name" type="TEXT" null="false"/>
+ <column name="toolchain_name" type="TEXT" null="false"/>
+ <column name="toolchain_version_epoch" type="INTEGER" null="false"/>
+ <column name="toolchain_version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="toolchain_version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="toolchain_version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="name" type="TEXT" null="false"/>
+ <column name="summary" 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"/>
+ <column name="package_version_canonical_release"/>
+ <column name="package_version_revision"/>
+ <column name="target"/>
+ <column name="target_config_name"/>
+ <column name="package_config_name"/>
+ <column name="toolchain_name"/>
+ <column name="toolchain_version_epoch"/>
+ <column name="toolchain_version_canonical_upstream"/>
+ <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"/>
+ <column name="package_version_canonical_release"/>
+ <column name="package_version_revision"/>
+ <column name="target"/>
+ <column name="target_config_name"/>
+ <column name="package_config_name"/>
+ <column name="toolchain_name"/>
+ <column name="toolchain_version_epoch"/>
+ <column name="toolchain_version_canonical_upstream"/>
+ <column name="toolchain_version_canonical_release"/>
+ <column name="toolchain_version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="build_auxiliary_machines_object_id_i">
+ <column name="package_tenant"/>
+ <column name="package_name"/>
+ <column name="package_version_epoch"/>
+ <column name="package_version_canonical_upstream"/>
+ <column name="package_version_canonical_release"/>
+ <column name="package_version_revision"/>
+ <column name="target"/>
+ <column name="target_config_name"/>
+ <column name="package_config_name"/>
+ <column name="toolchain_name"/>
+ <column name="toolchain_version_epoch"/>
+ <column name="toolchain_version_canonical_upstream"/>
+ <column name="toolchain_version_canonical_release"/>
+ <column name="toolchain_version_revision"/>
+ </index>
+ <index name="build_auxiliary_machines_index_i">
+ <column name="index"/>
+ </index>
+ </add-table>
+ </changeset>
+
+ <changeset version="24"/>
+
+ <changeset version="23"/>
+
+ <changeset version="22"/>
+
+ <changeset version="21"/>
+
<model version="20">
<table name="build" kind="object">
<column name="package_tenant" type="TEXT" null="false"/>
diff --git a/libbrep/common.cxx b/libbrep/common.cxx
index c97a346..4f729a3 100644
--- a/libbrep/common.cxx
+++ b/libbrep/common.cxx
@@ -32,14 +32,4 @@ namespace brep
else if (r == "unbuildable") return unbuildable_reason::unbuildable;
else throw invalid_argument ("invalid unbuildable reason '" + r + '\'');
}
-
- build_package_config*
- find (const string& name, build_package_configs& cs)
- {
- auto i (find_if (cs.begin (), cs.end (),
- [&name] (const build_package_config& c)
- {return c.name == name;}));
-
- return i != cs.end () ? &*i : nullptr;
- }
}
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index 158690e..1433c8c 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -127,6 +127,20 @@ namespace brep
std::chrono::duration_cast<brep::timestamp::duration> ( \
std::chrono::nanoseconds (?))))
+ using optional_timestamp = optional<timestamp>;
+ using optional_uint64 = optional<uint64_t>;
+
+ #pragma db map type(optional_timestamp) as(brep::optional_uint64) \
+ to((?) \
+ ? std::chrono::duration_cast<std::chrono::nanoseconds> ( \
+ (?)->time_since_epoch ()).count () \
+ : brep::optional_uint64 ()) \
+ from((?) \
+ ? brep::timestamp ( \
+ std::chrono::duration_cast<brep::timestamp::duration> ( \
+ std::chrono::nanoseconds (*(?)))) \
+ : brep::optional_timestamp ())
+
// version
//
using bpkg::version;
@@ -312,6 +326,19 @@ namespace brep
: tenant (move (t)), canonical_name (move (n)) {}
};
+ // public_key_id
+ //
+ #pragma db value
+ struct public_key_id
+ {
+ string tenant;
+ string fingerprint;
+
+ public_key_id () = default;
+ public_key_id (string t, string f)
+ : tenant (move (t)), fingerprint (move (f)) {}
+ };
+
// build_class_expr
//
using bpkg::build_class_expr;
@@ -333,30 +360,61 @@ namespace brep
#pragma db value(build_constraint) definition
- // build_package_config
+ // build_auxiliaries
+ //
+ using bpkg::build_auxiliary;
+ using build_auxiliaries = vector<build_auxiliary>;
+
+ #pragma db value(build_auxiliary) definition
+
+ // build_toolchain
+ //
+ #pragma db value
+ struct build_toolchain
+ {
+ string name;
+ brep::version version;
+ };
+
+ // email
//
- using build_package_config = bpkg::build_package_config;
+ using bpkg::email;
- #pragma db value(build_package_config) definition
+ #pragma db value(email) definition
+ #pragma db member(email::value) virtual(string) before access(this) column("")
+
+ // build_package_config_template
+ //
+ using bpkg::build_package_config_template;
// 1 for the default configuration which is always present.
//
- using build_package_configs = small_vector<build_package_config, 1>;
+ template <typename K>
+ using build_package_configs_template =
+ small_vector<build_package_config_template<K>, 1>;
// Return the address of the configuration object with the specified name,
// if present, and NULL otherwise.
//
- build_package_config*
- find (const string& name, build_package_configs&);
+ template <typename K>
+ inline build_package_config_template<K>*
+ find (const string& name, build_package_configs_template<K>& cs)
+ {
+ auto i (find_if (cs.begin (), cs.end (),
+ [&name] (const build_package_config_template<K>& c)
+ {return c.name == name;}));
+
+ return i != cs.end () ? &*i : nullptr;
+ }
// Note that ODB doesn't support containers of value types which contain
// containers. Thus, we will persist/load
- // package_build_config::{builds,constraint} via the separate nested
- // containers using the adapter classes.
+ // build_package_config_template<K>::{builds,constraint,auxiliaries,bot_keys}
+ // via the separate nested containers using the adapter classes.
//
- #pragma db member(build_package_config::builds) transient
- #pragma db member(build_package_config::constraints) transient
+ // build_package_config_template<K>::builds
+ //
using build_class_expr_key = odb::nested_key<build_class_exprs>;
using build_class_exprs_map = std::map<build_class_expr_key, build_class_expr>;
@@ -364,24 +422,27 @@ namespace brep
#pragma db member(build_class_expr_key::outer) column("config_index")
#pragma db member(build_class_expr_key::inner) column("index")
- // Adapter for build_package_config::builds.
+ // Adapter for build_package_config_template<K>::builds.
+ //
+ // Note: 1 as for build_package_configs_template.
//
- class build_package_config_builds:
- public small_vector<build_class_exprs, 1> // 1 as for build_package_configs.
+ class build_package_config_builds: public small_vector<build_class_exprs, 1>
{
public:
build_package_config_builds () = default;
+ template <typename K>
explicit
- build_package_config_builds (const build_package_configs& cs)
+ build_package_config_builds (const build_package_configs_template<K>& cs)
{
reserve (cs.size ());
- for (const build_package_config& c: cs)
+ for (const build_package_config_template<K>& c: cs)
push_back (c.builds);
}
+ template <typename K>
void
- to_configs (build_package_configs& cs) &&
+ to_configs (build_package_configs_template<K>& cs) &&
{
// Note that the empty trailing entries will be missing (see ODB's
// nested-container.hxx for details).
@@ -394,6 +455,8 @@ namespace brep
}
};
+ // build_package_config_template<K>::constraints
+ //
using build_constraint_key = odb::nested_key<build_constraints>;
using build_constraints_map = std::map<build_constraint_key, build_constraint>;
@@ -401,24 +464,29 @@ namespace brep
#pragma db member(build_constraint_key::outer) column("config_index")
#pragma db member(build_constraint_key::inner) column("index")
- // Adapter for build_package_config::constraints.
+ // Adapter for build_package_config_template<K>::constraints.
+ //
+ // Note: 1 as for build_package_configs_template.
//
class build_package_config_constraints:
- public small_vector<build_constraints, 1> // 1 as for build_package_configs.
+ public small_vector<build_constraints, 1>
{
public:
build_package_config_constraints () = default;
+ template <typename K>
explicit
- build_package_config_constraints (const build_package_configs& cs)
+ build_package_config_constraints (
+ const build_package_configs_template<K>& cs)
{
reserve (cs.size ());
- for (const build_package_config& c: cs)
+ for (const build_package_config_template<K>& c: cs)
push_back (c.constraints);
}
+ template <typename K>
void
- to_configs (build_package_configs& cs) &&
+ to_configs (build_package_configs_template<K>& cs) &&
{
// Note that the empty trailing entries will be missing (see ODB's
// nested-container.hxx for details).
@@ -431,6 +499,84 @@ namespace brep
}
};
+ // build_package_config_template<K>::auxiliaries
+ //
+ using build_auxiliary_key = odb::nested_key<build_auxiliaries>;
+ using build_auxiliaries_map = std::map<build_auxiliary_key, build_auxiliary>;
+
+ #pragma db value(build_auxiliary_key)
+ #pragma db member(build_auxiliary_key::outer) column("config_index")
+ #pragma db member(build_auxiliary_key::inner) column("index")
+
+ // Adapter for build_package_config_template<K>::auxiliaries.
+ //
+ // Note: 1 as for build_package_configs_template.
+ //
+ class build_package_config_auxiliaries:
+ public small_vector<build_auxiliaries, 1>
+ {
+ public:
+ build_package_config_auxiliaries () = default;
+
+ template <typename K>
+ explicit
+ build_package_config_auxiliaries (
+ const build_package_configs_template<K>& cs)
+ {
+ reserve (cs.size ());
+ for (const build_package_config_template<K>& c: cs)
+ push_back (c.auxiliaries);
+ }
+
+ template <typename K>
+ void
+ to_configs (build_package_configs_template<K>& cs) &&
+ {
+ // Note that the empty trailing entries will be missing (see ODB's
+ // nested-container.hxx for details).
+ //
+ assert (size () <= cs.size ());
+
+ auto i (cs.begin ());
+ for (build_auxiliaries& bas: *this)
+ i++->auxiliaries = move (bas);
+ }
+ };
+
+ // build_package_config_template<K>::bot_keys
+ //
+ // Adapter for build_package_config_template<K>::bot_keys.
+ //
+ // Note: 1 as for build_package_configs_template.
+ //
+ template <typename K>
+ class build_package_config_bot_keys: public small_vector<vector<K>, 1>
+ {
+ public:
+ build_package_config_bot_keys () = default;
+
+ explicit
+ build_package_config_bot_keys (const build_package_configs_template<K>& cs)
+ {
+ this->reserve (cs.size ());
+ for (const build_package_config_template<K>& c: cs)
+ this->push_back (c.bot_keys);
+ }
+
+ void
+ to_configs (build_package_configs_template<K>& cs) &&
+ {
+ // Note that the empty trailing entries will be missing (see ODB's
+ // nested-container.hxx for details).
+ //
+ assert (this->size () <= cs.size ());
+
+ auto i (cs.begin ());
+ for (vector<K>& bks: *this)
+ i++->bot_keys = move (bks);
+ }
+ };
+
// The primary reason why a package is unbuildable by the build bot
// controller service.
//
@@ -510,15 +656,30 @@ namespace brep
#pragma db member(requirement_key::middle) column("alternative_index")
#pragma db member(requirement_key::inner) column("index")
+ // Third-party service state which may optionally be associated with a
+ // tenant (see also mod/tenant-service.hxx for background).
+ //
+ #pragma db value
+ struct tenant_service
+ {
+ string id;
+ string type;
+ optional<string> data;
+
+ tenant_service () = default;
+
+ tenant_service (string i, string t, optional<string> d = nullopt)
+ : id (move (i)), type (move (t)), data (move (d)) {}
+ };
+
// Version comparison operators.
//
- // They allow comparing objects that have epoch, canonical_upstream,
- // canonical_release, and revision data members. The idea is that this
- // works for both query members of types version and canonical_version.
- // Note, though, that the object revisions should be comparable (both
- // optional, numeric, etc), so to compare version to query member or
- // canonical_version you may need to explicitly convert the version object
- // to canonical_version.
+ // Compare objects that have epoch, canonical_upstream, canonical_release,
+ // and revision data members. The idea is that this works for both query
+ // members of types version and canonical_version. Note, though, that the
+ // object revisions should be comparable (both optional, numeric, etc), so
+ // to compare version to query member or canonical_version you may need to
+ // explicitly convert the version object to canonical_version.
//
template <typename T1, typename T2>
inline auto
@@ -670,10 +831,9 @@ namespace brep
return compare_version_lt (x.version, y.version, true);
}
- // They allow comparing objects that have tenant, name, and version data
- // members. The idea is that this works for both query members of package id
- // types (in particular in join conditions) as well as for values of
- // package_id type.
+ // Compare objects that have tenant, name, and version data members. The
+ // idea is that this works for both query members of package id types (in
+ // particular in join conditions) as well as for values of package_id type.
//
template <typename T1, typename T2>
inline auto
@@ -700,6 +860,27 @@ namespace brep
}
// Allow comparing the query members with the query parameters bound by
+ // reference to variables of the canonical version type (in particular in
+ // the prepared queries).
+ //
+ // Note that it is not operator==() since the query template parameter type
+ // can not be deduced from the function parameter types and needs to be
+ // specified explicitly.
+ //
+ template <typename T, typename V>
+ inline auto
+ equal (const V& x, const canonical_version& y)
+ -> decltype (x.epoch == odb::query<T>::_ref (y.epoch))
+ {
+ using query = odb::query<T>;
+
+ return x.epoch == query::_ref (y.epoch) &&
+ x.canonical_upstream == query::_ref (y.canonical_upstream) &&
+ x.canonical_release == query::_ref (y.canonical_release) &&
+ x.revision == query::_ref (y.revision);
+ }
+
+ // Allow comparing the query members with the query parameters bound by
// reference to variables of the package id type (in particular in the
// prepared queries).
//
@@ -710,21 +891,15 @@ namespace brep
template <typename T, typename ID>
inline auto
equal (const ID& x, const package_id& y)
- -> decltype (x.tenant == odb::query<T>::_ref (y.tenant) &&
- x.name == odb::query<T>::_ref (y.name) &&
+ -> decltype (x.tenant == odb::query<T>::_ref (y.tenant) &&
+ x.name == odb::query<T>::_ref (y.name) &&
x.version.epoch == odb::query<T>::_ref (y.version.epoch))
{
using query = odb::query<T>;
- const auto& qv (x.version);
- const canonical_version& v (y.version);
-
- return x.tenant == query::_ref (y.tenant) &&
- x.name == query::_ref (y.name) &&
- qv.epoch == query::_ref (v.epoch) &&
- qv.canonical_upstream == query::_ref (v.canonical_upstream) &&
- qv.canonical_release == query::_ref (v.canonical_release) &&
- qv.revision == query::_ref (v.revision);
+ return x.tenant == query::_ref (y.tenant) &&
+ x.name == query::_ref (y.name) &&
+ equal<T> (x.version, y.version);
}
// Repository id comparison operators.
@@ -738,10 +913,10 @@ namespace brep
return x.canonical_name.compare (y.canonical_name) < 0;
}
- // They allow comparing objects that have tenant and canonical_name data
- // members. The idea is that this works for both query members of repository
- // id types (in particular in join conditions) as well as for values of
- // repository_id type.
+ // Compare objects that have tenant and canonical_name data members. The
+ // idea is that this works for both query members of repository id types (in
+ // particular in join conditions) as well as for values of repository_id
+ // type.
//
template <typename T1, typename T2>
inline auto
@@ -758,6 +933,38 @@ namespace brep
{
return x.tenant != y.tenant || x.canonical_name != y.canonical_name;
}
+
+ // Public key id comparison operators.
+ //
+ inline bool
+ operator< (const public_key_id& x, const public_key_id& y)
+ {
+ if (int r = x.tenant.compare (y.tenant))
+ return r < 0;
+
+ return x.fingerprint.compare (y.fingerprint) < 0;
+ }
+
+ // Compare objects that have tenant and fingerprint data members. The idea
+ // is that this works for both query members of public key id types (in
+ // particular in join conditions) as well as for values of public_key_id
+ // type.
+ //
+ template <typename T1, typename T2>
+ inline auto
+ operator== (const T1& x, const T2& y)
+ -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint)
+ {
+ return x.tenant == y.tenant && x.fingerprint == y.fingerprint;
+ }
+
+ template <typename T1, typename T2>
+ inline auto
+ operator!= (const T1& x, const T2& y)
+ -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint)
+ {
+ return x.tenant != y.tenant || x.fingerprint != y.fingerprint;
+ }
}
#endif // LIBBREP_COMMON_HXX
diff --git a/libbrep/odb.sh b/libbrep/odb.sh
index 9ee11fa..7c62acb 100755
--- a/libbrep/odb.sh
+++ b/libbrep/odb.sh
@@ -16,6 +16,8 @@ if test -d ../.bdep; then
sed -r -ne 's#^(@[^ ]+ )?([^ ]+)/ .*default.*$#\2#p')"
fi
+ # Note: here we use libodb*, not libbutl-odb.
+ #
inc+=("-I$(echo "$cfg"/libodb-[1-9]*/)")
inc+=("-I$(echo "$cfg"/libodb-pgsql-[1-9]*/)")
@@ -33,11 +35,8 @@ sed -r -ne 's#^(@[^ ]+ )?([^ ]+)/ .*default.*$#\2#p')"
else
- inc+=("-I$HOME/work/odb/builds/default/libodb-pgsql-default")
- inc+=("-I$HOME/work/odb/libodb-pgsql")
-
- inc+=("-I$HOME/work/odb/builds/default/libodb-default")
- inc+=("-I$HOME/work/odb/libodb")
+ inc+=("-I$HOME/work/odb/odb/libodb-pgsql")
+ inc+=("-I$HOME/work/odb/odb/libodb")
inc+=(-I.. -I../../libbbot -I../../libbpkg -I../../libbutl)
@@ -53,7 +52,7 @@ $odb "${inc[@]}" -d pgsql --std c++14 --generate-query \
--hxx-prologue '#include <libbrep/common-traits.hxx>' \
-DLIBODB_BUILD2 -DLIBODB_PGSQL_BUILD2 \
--include-with-brackets --include-prefix libbrep \
- --guard-prefix LIBBREP \
+ --guard-prefix LIBBREP \
common.hxx
$odb "${inc[@]}" -d pgsql --std c++14 --generate-query --generate-schema \
@@ -74,7 +73,7 @@ $odb "${inc[@]}" -d pgsql --std c++14 --generate-query --generate-schema \
--odb-epilogue '#include <libbrep/wrapper-traits.hxx>' \
--generate-prepared -DLIBODB_BUILD2 -DLIBODB_PGSQL_BUILD2 \
--include-with-brackets --include-prefix libbrep \
- --guard-prefix LIBBREP \
+ --guard-prefix LIBBREP \
build.hxx
$odb "${inc[@]}" -d pgsql --std c++14 --generate-query \
diff --git a/libbrep/package.cxx b/libbrep/package.cxx
index 152d1d8..4eb6fe8 100644
--- a/libbrep/package.cxx
+++ b/libbrep/package.cxx
@@ -40,11 +40,15 @@ namespace brep
// tenant
//
tenant::
- tenant (string i, bool p, optional<string> r)
+ tenant (string i,
+ bool p,
+ optional<string> r,
+ optional<tenant_service> s)
: id (move (i)),
private_ (p),
interactive (move (r)),
- creation_timestamp (timestamp::clock::now ())
+ creation_timestamp (timestamp::clock::now ()),
+ service (move (s))
{
}
@@ -60,9 +64,9 @@ namespace brep
license_alternatives_type la,
small_vector<string, 5> tp,
small_vector<string, 5> kw,
- optional<string> ds,
- optional<text_type> dt,
- string ch,
+ optional<typed_text> ds,
+ optional<typed_text> pds,
+ optional<typed_text> ch,
optional<manifest_url> ur,
optional<manifest_url> du,
optional<manifest_url> su,
@@ -77,7 +81,9 @@ namespace brep
small_vector<test_dependency, 1> ts,
build_class_exprs bs,
build_constraints_type bc,
- build_package_configs bcs,
+ build_auxiliaries_type ac,
+ package_build_bot_keys bk,
+ package_build_configs bcs,
optional<path> lc,
optional<string> fr,
optional<string> sh,
@@ -94,7 +100,7 @@ namespace brep
topics (move (tp)),
keywords (move (kw)),
description (move (ds)),
- description_type (move (dt)),
+ package_description (move (pds)),
changes (move (ch)),
url (move (ur)),
doc_url (move (du)),
@@ -110,28 +116,18 @@ namespace brep
tests (move (ts)),
builds (move (bs)),
build_constraints (move (bc)),
+ build_auxiliaries (move (ac)),
+ build_bot_keys (move (bk)),
+ build_configs (move (bcs)),
internal_repository (move (rp)),
location (move (lc)),
fragment (move (fr)),
sha256sum (move (sh))
{
- // Add the default build configuration at the beginning, unless it is
- // specified explicitly.
+ // The default configuration is always added by the package manifest
+ // parser (see libbpkg/manifest.cxx for details).
//
- if (find_if (bcs.begin (), bcs.end (),
- [] (const build_package_config& c)
- {return c.name == "default";}) != bcs.end ())
- {
- build_configs = move (bcs);
- }
- else
- {
- build_configs.reserve (bcs.size () + 1);
- build_configs.emplace_back ("default");
- build_configs.insert (build_configs.end (),
- make_move_iterator (bcs.begin ()),
- make_move_iterator (bcs.end ()));
- }
+ assert (find ("default", build_configs) != nullptr);
if (stub ())
unbuildable_reason = brep::unbuildable_reason::stub;
@@ -140,6 +136,31 @@ namespace brep
buildable = !unbuildable_reason;
+ // If the package is buildable deduce the custom_bot flag.
+ //
+ if (buildable)
+ {
+ for (const package_build_config& bc: build_configs)
+ {
+ bool custom (!bc.effective_bot_keys (build_bot_keys).empty ());
+
+ if (!custom_bot)
+ {
+ custom_bot = custom;
+ }
+ //
+ // If both the custom and default bots are used by the package, then
+ // reset the custom_bot flag to nullopt and bail out from the build
+ // package configurations loop.
+ //
+ else if (*custom_bot != custom)
+ {
+ custom_bot = nullopt;
+ break;
+ }
+ }
+ }
+
assert (internal_repository->internal);
}
@@ -148,6 +169,8 @@ namespace brep
version_type vr,
build_class_exprs bs,
build_constraints_type bc,
+ build_auxiliaries_type ac,
+ package_build_configs bcs,
shared_ptr<repository_type> rp)
: id (rp->tenant, move (nm), vr),
tenant (id.tenant),
@@ -155,11 +178,18 @@ namespace brep
version (move (vr)),
builds (move (bs)),
build_constraints (move (bc)),
+ build_auxiliaries (move (ac)),
+ build_configs (move (bcs)),
buildable (false),
unbuildable_reason (stub ()
? brep::unbuildable_reason::stub
: brep::unbuildable_reason::external)
{
+ // The default configuration is always added by the package manifest
+ // parser (see libbpkg/manifest.cxx for details).
+ //
+ assert (find ("default", build_configs) != nullptr);
+
assert (!rp->internal);
other_repositories.emplace_back (move (rp));
}
@@ -216,7 +246,17 @@ namespace brep
for (const auto& k: keywords)
k2 += ' ' + k;
- return {move (k), move (k2), description ? *description : "", changes};
+ string d (description ? description->text : "");
+
+ if (package_description)
+ {
+ if (description)
+ d += ' ';
+
+ d += package_description->text;
+ }
+
+ return {move (k), move (k2), move (d), changes ? changes->text : ""};
}
// repository
diff --git a/libbrep/package.hxx b/libbrep/package.hxx
index cf6ae64..45008d4 100644
--- a/libbrep/package.hxx
+++ b/libbrep/package.hxx
@@ -18,9 +18,9 @@
// Used by the data migration entries.
//
-#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 26
+#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 27
-#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 26, closed)
+#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 33, closed)
namespace brep
{
@@ -49,9 +49,12 @@ namespace brep
using bpkg::text_type;
using bpkg::to_text_type;
+ // Note that here we assume that the saved string representation of a type
+ // is always recognized later.
+ //
#pragma db map type(text_type) as(string) \
to(to_string (?)) \
- from(brep::to_text_type (?))
+ from(*brep::to_text_type (?))
using optional_text_type = optional<text_type>;
@@ -69,13 +72,6 @@ namespace brep
set(this = brep::manifest_url ((?), "" /* comment */)) \
column("")
- // email
- //
- using bpkg::email;
-
- #pragma db value(email) definition
- #pragma db member(email::value) virtual(string) before access(this) column("")
-
// licenses
//
using bpkg::licenses;
@@ -202,6 +198,7 @@ namespace brep
{
test_dependency_type type;
bool buildtime;
+ optional<string> enable;
optional<string> reflect;
test_dependency () = default;
@@ -209,10 +206,12 @@ namespace brep
test_dependency_type t,
bool b,
optional<version_constraint> c,
+ optional<string> e,
optional<string> r)
: dependency {move (n), move (c), nullptr /* package */},
type (t),
buildtime (b),
+ enable (move (e)),
reflect (move (r))
{
}
@@ -242,31 +241,83 @@ namespace brep
// Create the tenant object with the timestamp set to now and the archived
// flag set to false.
//
- explicit
- tenant (string id, bool private_, optional<string> interactive);
+ tenant (string id,
+ bool private_,
+ optional<string> interactive,
+ optional<tenant_service>);
string id;
- // If true, display the packages in the web interface only in the tenant
- // view mode.
+ // If this flag is true, then display the packages in the web interface
+ // only in the tenant view mode.
//
- bool private_; // Note: foreign-mapped in build.
+ bool private_; // Note: foreign-mapped in build.
// Interactive package build breakpoint.
//
// If present, then packages from this tenant will only be built
// interactively and only non-interactively otherwise.
//
- optional<string> interactive; // Note: foreign-mapped in build.
+ optional<string> interactive; // Note: foreign-mapped in build.
timestamp creation_timestamp;
- bool archived = false; // Note: foreign-mapped in build.
+ bool archived = false; // Note: foreign-mapped in build.
+
+ optional<tenant_service> service; // Note: foreign-mapped in build.
+
+ // Note that due to the implementation complexity and performance
+ // considerations, the service notifications are not synchronized. This
+ // leads to a potential race, so that before we have sent the `queued`
+ // notification for a package build, some other thread (potentially in a
+ // different process) could have already sent the `building` notification
+ // for it. It feels like there is no easy way to reliably fix that.
+ // Instead, we just decrease the probability of such a notifications
+ // sequence failure by delaying builds of the freshly queued packages for
+ // some time. Specifically, whenever the `queued` notification is ought
+ // to be sent (normally out of the database transaction, since it likely
+ // sends an HTTP request, etc) the tenant's queued_timestamp member is set
+ // to the current time. During the configured time interval since that
+ // time point the build tasks may not be issued for the tenant's packages.
+ //
+ // Also note that while there are similar potential races for other
+ // notification sequences, their probability is rather low due to the
+ // natural reasons (non-zero build task execution time, etc) and thus we
+ // just ignore them.
+ //
+ optional<timestamp> queued_timestamp; // Note: foreign-mapped in build.
+
+ // Note that after the package tenant is created but before the first
+ // build object is created, there is no easy way to produce a list of
+ // unbuilt package configurations. That would require to know the build
+ // toolchain(s), which are normally extracted from the build objects.
+ // Thus, the empty unbuilt package configurations list is ambiguous and
+ // can either mean that no more package configurations can be built or
+ // that we have not enough information to produce the list. To
+ // disambiguate the empty list in the interface, in the latter case we
+ // want to display the question mark instead of 0 as an unbuilt package
+ // configurations count. To achieve this we will stash the build toolchain
+ // in the tenant when a package from this tenant is considered for a build
+ // for the first time but no configuration is picked for the build (the
+ // target configurations are excluded, an auxiliary machine is not
+ // available, etc). We will also use the stashed toolchain as a fallback
+ // until we are able to retrieve the toolchain(s) from the tenant builds
+ // to produce the unbuilt package configurations list.
+ //
+ // Note: foreign-mapped in build.
+ //
+ optional<brep::build_toolchain> build_toolchain;
// Database mapping.
//
#pragma db member(id) id
#pragma db member(private_)
+ #pragma db index("tenant_service_i") \
+ unique \
+ members(service.id, service.type)
+
+ #pragma db index member(service.id)
+
private:
friend class odb::access;
tenant () = default;
@@ -396,6 +447,67 @@ namespace brep
string d;
};
+ #pragma db value
+ struct typed_text
+ {
+ string text;
+ text_type type;
+
+ #pragma db member(text) column("")
+ };
+
+ // Tweak public_key_id mapping to include a constraint (this only affects the
+ // database schema).
+ //
+ #pragma db member(public_key_id::tenant) points_to(tenant)
+
+ #pragma db object pointer(shared_ptr) session
+ class public_key: public string
+ {
+ public:
+ public_key (string tenant, string fingerprint, string key)
+ : string (move (key)), id (move (tenant), move (fingerprint)) {}
+
+ public_key_id id;
+
+ // Database mapping.
+ //
+ #pragma db member(id) id column("")
+
+ #pragma db member(data) virtual(string) access(this)
+
+ private:
+ friend class odb::access;
+ public_key () = default;
+ };
+
+ // package_build_config
+ //
+ using package_build_config =
+ build_package_config_template<lazy_shared_ptr<public_key>>;
+
+ using package_build_configs =
+ build_package_configs_template<lazy_shared_ptr<public_key>>;
+
+ #pragma db value(package_build_config) definition
+
+ #pragma db member(package_build_config::builds) transient
+ #pragma db member(package_build_config::constraints) transient
+ #pragma db member(package_build_config::auxiliaries) transient
+ #pragma db member(package_build_config::bot_keys) transient
+
+ // package_build_bot_keys
+ //
+ using package_build_bot_keys = vector<lazy_shared_ptr<public_key>>;
+ using package_build_bot_key_key = odb::nested_key<package_build_bot_keys>;
+
+ using package_build_bot_keys_map = std::map<package_build_bot_key_key,
+ lazy_shared_ptr<public_key>>;
+
+ #pragma db value(package_build_bot_key_key)
+ #pragma db member(package_build_bot_key_key::outer) column("config_index")
+ #pragma db member(package_build_bot_key_key::inner) column("index")
+
// Tweak package_id mapping to include a constraint (this only affects the
// database schema).
//
@@ -414,11 +526,11 @@ namespace brep
using dependencies_type = brep::dependencies;
using requirements_type = brep::requirements;
using build_constraints_type = brep::build_constraints;
+ using build_auxiliaries_type = brep::build_auxiliaries;
// Create internal package object.
//
- // Note: adds the default build package config at the first position if it
- // is not present yet.
+ // Note: the default build package config is expected to always be present.
//
package (package_name,
version_type,
@@ -429,9 +541,9 @@ namespace brep
license_alternatives_type,
small_vector<string, 5> topics,
small_vector<string, 5> keywords,
- optional<string> description,
- optional<text_type> description_type,
- string changes,
+ optional<typed_text> description,
+ optional<typed_text> package_description,
+ optional<typed_text> changes,
optional<manifest_url> url,
optional<manifest_url> doc_url,
optional<manifest_url> src_url,
@@ -446,7 +558,9 @@ namespace brep
small_vector<test_dependency, 1> tests,
build_class_exprs,
build_constraints_type,
- build_package_configs,
+ build_auxiliaries_type,
+ package_build_bot_keys,
+ package_build_configs,
optional<path> location,
optional<string> fragment,
optional<string> sha256sum,
@@ -461,14 +575,20 @@ namespace brep
//
// External package can also be a separate test for some primary package
// (and belong to a complement but yet external repository), and so we may
- // need its build class expressions and constraints to decide if to build
- // it together with the primary package or not (see test-exclude task
- // manifest value for details).
+ // need its build class expressions, constraints, and configurations to
+ // decide if to build it together with the primary package or not (see
+ // test-exclude task manifest value for details). Additionally, when the
+ // test package is being built the auxiliary machines may also be
+ // required.
+ //
+ // Note: the default build package config is expected to always be present.
//
package (package_name name,
version_type,
build_class_exprs,
build_constraints_type,
+ build_auxiliaries_type,
+ package_build_configs,
shared_ptr<repository_type>);
bool
@@ -494,37 +614,53 @@ namespace brep
// Matches the package name if the project name is not specified in
// the manifest.
//
- package_name project;
+ package_name project; // Note: foreign-mapped in build.
priority_type priority;
string summary;
license_alternatives_type license_alternatives;
small_vector<string, 5> topics;
small_vector<string, 5> keywords;
- optional<string> description; // Absent if type is unknown.
- optional<text_type> description_type; // Present if description is present.
- string changes;
+
+ // Note that the descriptions and changes are absent if the respective
+ // type is unknown.
+ //
+ optional<typed_text> description;
+ optional<typed_text> package_description;
+ optional<typed_text> changes;
+
optional<manifest_url> url;
optional<manifest_url> doc_url;
optional<manifest_url> src_url;
optional<manifest_url> package_url;
optional<email_type> email;
optional<email_type> package_email;
- optional<email_type> build_email;
- optional<email_type> build_warning_email;
- optional<email_type> build_error_email;
+ optional<email_type> build_email; // Note: foreign-mapped in build.
+ optional<email_type> build_warning_email; // Note: foreign-mapped in build.
+ optional<email_type> build_error_email; // Note: foreign-mapped in build.
dependencies_type dependencies;
requirements_type requirements; // Note: foreign-mapped in build.
small_vector<test_dependency, 1> tests; // Note: foreign-mapped in build.
- // Common build classes/constraints that apply to all configurations
- // unless overridden.
+ // Common build classes, constraints, auxiliaries, and bot keys that apply
+ // to all configurations unless overridden.
//
build_class_exprs builds; // Note: foreign-mapped in build.
build_constraints_type build_constraints; // Note: foreign-mapped in build.
+ build_auxiliaries_type build_auxiliaries; // Note: foreign-mapped in build.
+ package_build_bot_keys build_bot_keys; // Note: foreign-mapped in build.
+ package_build_configs build_configs; // Note: foreign-mapped in build.
- build_package_configs build_configs; // Note: foreign-mapped in build.
-
+ // Group the build_configs, builds, and build_constraints members of this
+ // object together with their respective nested configs entries into the
+ // separate section for an explicit load.
+ //
+ // Note that while the build auxiliaries and bot keys are persisted via
+ // the newly created package objects, they are only used via the
+ // foreign-mapped build_package objects (see build-package.hxx for
+ // details). Thus, we add them to the never-loaded unused_section (see
+ // below).
+ //
odb::section build_section;
// Note that it is foreign-mapped in build.
@@ -555,6 +691,18 @@ namespace brep
bool buildable; // Note: foreign-mapped in build.
optional<brep::unbuildable_reason> unbuildable_reason;
+ // If this flag is true, then all the package configurations are buildable
+ // with the custom build bots. If false, then all configurations are
+ // buildable with the default bots. If nullopt, then some configurations
+ // are buildable with the custom and some with the default build bots.
+ //
+ // Note: meaningless if buildable is false.
+ //
+ optional<bool> custom_bot; // Note: foreign-mapped in build.
+
+ private:
+ odb::section unused_section;
+
// Database mapping.
//
#pragma db member(id) id column("")
@@ -674,11 +822,22 @@ namespace brep
#pragma db member(build_constraints) id_column("") value_column("") \
section(build_section)
+ // build_auxiliaries
+ //
+ #pragma db member(build_auxiliaries) id_column("") value_column("") \
+ section(unused_section)
+
+ // build_bot_keys
+ //
+ #pragma db member(build_bot_keys) \
+ id_column("") value_column("key_") value_not_null \
+ section(unused_section)
+
// build_configs
//
- // Note that build_package_config::{builds,constraints} are
- // persisted/loaded via the separate nested containers (see commons.hxx
- // for details).
+ // Note that package_build_config::{builds,constraints,auxiliaries,
+ // bot_keys} are persisted/loaded via the separate nested containers (see
+ // commons.hxx for details).
//
#pragma db member(build_configs) id_column("") value_column("config_") \
section(build_section)
@@ -705,7 +864,32 @@ namespace brep
id_column("") key_column("") value_column("") \
section(build_section)
- #pragma db member(build_section) load(lazy) update(always)
+ #pragma db member(build_config_auxiliaries) \
+ virtual(build_auxiliaries_map) \
+ after(build_config_constraints) \
+ get(odb::nested_get ( \
+ brep::build_package_config_auxiliaries (this.build_configs))) \
+ set(brep::build_package_config_auxiliaries as; \
+ odb::nested_set (as, std::move (?)); \
+ move (as).to_configs (this.build_configs)) \
+ id_column("") key_column("") value_column("") \
+ section(unused_section)
+
+ #pragma db member(build_config_bot_keys) \
+ virtual(package_build_bot_keys_map) \
+ after(build_config_auxiliaries) \
+ get(odb::nested_get ( \
+ brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::public_key>> (this.build_configs))) \
+ set(brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::public_key>> bks; \
+ odb::nested_set (bks, std::move (?)); \
+ move (bks).to_configs (this.build_configs)) \
+ id_column("") key_column("") value_column("key_") value_not_null \
+ section(unused_section)
+
+ #pragma db member(build_section) load(lazy) update(always)
+ #pragma db member(unused_section) load(lazy) update(manual)
// other_repositories
//
@@ -723,9 +907,9 @@ namespace brep
friend class odb::access;
package (): tenant (id.tenant), 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
- // have a higher weight than if it's found in the summary.
+ // Save keywords, summary, descriptions, and changes to weighted_text a,
+ // b, c, d members, respectively. So a word found in keywords will have a
+ // higher weight than if it's found in the summary.
//
weighted_text
search_text () const;
diff --git a/libbrep/package.xml b/libbrep/package.xml
index 8f32284..96e93a7 100644
--- a/libbrep/package.xml
+++ b/libbrep/package.xml
@@ -1,5 +1,276 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="package" version="1">
- <model version="26">
+ <changeset version="33">
+ <add-table name="public_key" kind="object">
+ <column name="tenant" type="TEXT" null="false"/>
+ <column name="fingerprint" type="TEXT" null="false"/>
+ <column name="data" type="TEXT" null="false"/>
+ <primary-key>
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </primary-key>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ <alter-table name="package">
+ <add-column name="custom_bot" type="BOOLEAN" null="true"/>
+ </alter-table>
+ <add-table name="package_build_bot_keys" 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="key_tenant" type="TEXT" null="false"/>
+ <column name="key_fingerprint" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <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"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_bot_keys_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_build_bot_keys_index_i">
+ <column name="index"/>
+ </index>
+ <foreign-key name="key_tenant_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="key_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <column name="key_fingerprint"/>
+ <references table="public_key">
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ <add-table name="package_build_config_bot_keys" 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="config_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="key_tenant" type="TEXT" null="false"/>
+ <column name="key_fingerprint" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <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"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_config_bot_keys_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <foreign-key name="key_tenant_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="key_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <column name="key_fingerprint"/>
+ <references table="public_key">
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ </changeset>
+
+ <changeset version="32">
+ <alter-table name="tenant">
+ <add-column name="build_toolchain_name" type="TEXT" null="true"/>
+ <add-column name="build_toolchain_version_epoch" type="INTEGER" null="true"/>
+ <add-column name="build_toolchain_version_canonical_upstream" type="TEXT" null="true"/>
+ <add-column name="build_toolchain_version_canonical_release" type="TEXT" null="true"/>
+ <add-column name="build_toolchain_version_revision" type="INTEGER" null="true"/>
+ <add-column name="build_toolchain_version_upstream" type="TEXT" null="true"/>
+ <add-column name="build_toolchain_version_release" type="TEXT" null="true"/>
+ </alter-table>
+ </changeset>
+
+ <changeset version="31">
+ <add-table name="package_build_auxiliaries" 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="environment_name" type="TEXT" null="false"/>
+ <column name="config" type="TEXT" null="false"/>
+ <column name="comment" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <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"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_auxiliaries_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_build_auxiliaries_index_i">
+ <column name="index"/>
+ </index>
+ </add-table>
+ <add-table name="package_build_config_auxiliaries" 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="config_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="environment_name" type="TEXT" null="false"/>
+ <column name="config" type="TEXT" null="false"/>
+ <column name="comment" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <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"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_config_auxiliaries_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ </add-table>
+ </changeset>
+
+ <changeset version="30">
+ <alter-table name="tenant">
+ <add-column name="service_id" type="TEXT" null="true"/>
+ <add-column name="service_type" type="TEXT" null="true"/>
+ <add-column name="service_data" type="TEXT" null="true"/>
+ <add-column name="queued_timestamp" type="BIGINT" null="true"/>
+ <add-index name="tenant_service_i" type="UNIQUE">
+ <column name="service_id"/>
+ <column name="service_type"/>
+ </add-index>
+ <add-index name="tenant_service_id_i">
+ <column name="service_id"/>
+ </add-index>
+ </alter-table>
+ </changeset>
+
+ <changeset version="29">
+ <alter-table name="package_tests">
+ <add-column name="test_enable" type="TEXT" null="true"/>
+ </alter-table>
+ </changeset>
+
+ <changeset version="28">
+ <alter-table name="package_build_configs">
+ <add-column name="config_email" type="TEXT" null="true"/>
+ <add-column name="config_email_comment" type="TEXT" null="true"/>
+ <add-column name="config_warning_email" type="TEXT" null="true"/>
+ <add-column name="config_warning_email_comment" type="TEXT" null="true"/>
+ <add-column name="config_error_email" type="TEXT" null="true"/>
+ <add-column name="config_error_email_comment" type="TEXT" null="true"/>
+ </alter-table>
+ </changeset>
+
+ <model version="27">
<table name="tenant" kind="object">
<column name="id" type="TEXT" null="false"/>
<column name="private" type="BOOLEAN" null="false"/>
@@ -144,7 +415,10 @@
<column name="summary" type="TEXT" null="false"/>
<column name="description" type="TEXT" null="true"/>
<column name="description_type" type="TEXT" null="true"/>
- <column name="changes" type="TEXT" null="false"/>
+ <column name="package_description" type="TEXT" null="true"/>
+ <column name="package_description_type" type="TEXT" null="true"/>
+ <column name="changes" type="TEXT" null="true"/>
+ <column name="changes_type" type="TEXT" null="true"/>
<column name="url" type="TEXT" null="true"/>
<column name="url_comment" type="TEXT" null="true"/>
<column name="doc_url" type="TEXT" null="true"/>
diff --git a/libbrep/version.hxx.in b/libbrep/version.hxx.in
index 3ac3752..9adb5ab 100644
--- a/libbrep/version.hxx.in
+++ b/libbrep/version.hxx.in
@@ -49,11 +49,11 @@ $libbbot.check(LIBBBOT_VERSION, LIBBBOT_SNAPSHOT)$
#include <odb/version.hxx>
-$libodb.check(LIBODB_VERSION, LIBODB_SNAPSHOT)$
+$libodb.check(LIBODB_VERSION_FULL, LIBODB_SNAPSHOT)$
#include <odb/pgsql/version.hxx>
-$libodb_pgsql.check(LIBODB_PGSQL_VERSION, LIBODB_PGSQL_SNAPSHOT)$
+$libodb_pgsql.check(LIBODB_PGSQL_VERSION_FULL, LIBODB_PGSQL_SNAPSHOT)$
// For now these are the same.
//