aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-02-15 13:37:31 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-02-22 11:18:08 +0300
commit10ab5a9bdc0e27691ec2d09772c8e62587b779a7 (patch)
tree6060ccdcbc7e5f83863ef233056ab039b1cd3313
parentd4900d85f7a5d791f89821713d02d3dd19361044 (diff)
Cleanup build queries in monitor
-rw-r--r--libbrep/build.hxx35
-rw-r--r--libbrep/common.hxx37
-rw-r--r--monitor/monitor.cxx76
3 files changed, 90 insertions, 58 deletions
diff --git a/libbrep/build.hxx b/libbrep/build.hxx
index 236f73c..1e9a9fc 100644
--- a/libbrep/build.hxx
+++ b/libbrep/build.hxx
@@ -127,6 +127,41 @@ 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
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index 11aae67..04d8453 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -737,6 +737,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).
//
@@ -747,21 +768,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.
diff --git a/monitor/monitor.cxx b/monitor/monitor.cxx
index 77f387b..27e8b84 100644
--- a/monitor/monitor.cxx
+++ b/monitor/monitor.cxx
@@ -655,8 +655,13 @@ namespace brep
conn->prepare_query<buildable_package> ("buildable-package-query",
pq));
- // Prepare the package configuration build prepared query.
+ // Prepare the package configuration build prepared queries.
//
+ using bquery = query<build>;
+ using prep_bquery = prepared_query<build>;
+
+ build_id id;
+
// This query will only be used for toolchains that have no version
// specified on the command line to obtain the latest completed build
// across all toolchain versions, if present, and the latest incomplete
@@ -667,29 +672,26 @@ namespace brep
// toolchain that built the package last and if there are none, pick the
// one for which the build task was issued last.
//
- using bquery = query<package_build>;
- using prep_bquery = prepared_query<package_build>;
-
- build_id id;
- string package_config_name;
-
- const auto& bid (bquery::build::id);
-
- bquery bq ((bquery::build::state != "queued" &&
- equal<package_build> (bid.package, id.package) &&
- bid.target == bquery::_ref (id.target) &&
- bid.target_config_name ==
- bquery::_ref (id.target_config_name) &&
- bid.package_config_name ==
- bquery::_ref (package_config_name) &&
- bid.toolchain_name == bquery::_ref (id.toolchain_name)) +
- "ORDER BY" +
- bquery::build::soft_timestamp + "DESC, " +
- bquery::build::timestamp + "DESC" +
- "LIMIT 1");
-
- prep_bquery pbq (
- conn->prepare_query<package_build> ("package-build-query", bq));
+ // @@ TMP Check if we can optimize this query by adding index for
+ // soft_timestamp and/or by setting enable_nestloop=off (or some
+ // such) as we do in mod/mod-builds.cxx.
+ //
+ bquery lbq ((equal<build> (bquery::id,
+ id,
+ false /* toolchain_version */) &&
+ bquery::state != "queued") +
+ "ORDER BY" +
+ bquery::soft_timestamp + "DESC, " +
+ bquery::timestamp + "DESC" +
+ "LIMIT 1");
+
+ prep_bquery plbq (
+ conn->prepare_query<build> ("package-latest-build-query", lbq));
+
+ // This query will only be used to retrieve a specific build by id.
+ //
+ bquery bq (equal<build> (bquery::id, id) && bquery::state != "queued");
+ prep_bquery pbq (conn->prepare_query<build> ("package-build-query", bq));
timestamp now (system_clock::now ());
@@ -848,29 +850,9 @@ namespace brep
// the latest build across all toolchain versions and search
// for a specific build otherwise.
//
- shared_ptr<build> b;
-
- if (id.toolchain_version.empty ())
- {
- package_config_name = pc.name;
-
- // @@ TMP Check if we can optimize this query by adding
- // index for soft_timestamp and/or by setting
- // enable_nestloop=off (or some such) as we do in
- // mod/mod-builds.cxx.
- //
- auto pbs (pbq.execute ());
-
- if (!pbs.empty ())
- b = move (pbs.begin ()->build);
- }
- else
- {
- b = db.find<build> (id);
-
- if (b->state == build_state::queued)
- b = nullptr;
- }
+ shared_ptr<build> b (id.toolchain_version.empty ()
+ ? plbq.execute_one ()
+ : pbq.execute_one ());
// Note that we consider a build as delayed if it is not
// completed in the expected timeframe. So even if the build