From 82121de9dff59ed0b18096d5416d7e6738ddf2ca Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 9 Apr 2021 11:18:24 +0200 Subject: Rewrite jobs-env-filtering This patch rewrites the filtering for environment variables in the "db jobs" subcommand. The output does not contain the environment variables anymore, which is a drawback, but the implementation is _way_ more easy to understand, which I consider an bigger advantage. The implementation now actually queries the database twice: first it gets all job ids from the JobEnv->EnvVar mapping and then builds a filter based on these IDs for the job output. Signed-off-by: Matthias Beyer --- src/commands/db.rs | 58 ++++++++++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/src/commands/db.rs b/src/commands/db.rs index 8b51570..d8669aa 100644 --- a/src/commands/db.rs +++ b/src/commands/db.rs @@ -300,19 +300,13 @@ fn jobs(conn_cfg: DbConnectionConfig, matches: &ArgMatches) -> Result<()> { "success", "package", "version", - "Env", ]); let conn = crate::db::establish_connection(conn_cfg)?; - let env_filter_tpl = matches - .value_of("filter_env") - .map(crate::util::env::parse_to_env) - .transpose()?; let sel = schema::jobs::table .inner_join(schema::submits::table) .inner_join(schema::endpoints::table) .inner_join(schema::packages::table) - .left_outer_join(schema::job_envs::table.inner_join(schema::envvars::table)) .into_boxed(); let sel = if let Some(submit_uuid) = matches @@ -325,39 +319,30 @@ fn jobs(conn_cfg: DbConnectionConfig, matches: &ArgMatches) -> Result<()> { sel }; - let sel = if let Some((name, val)) = env_filter_tpl.as_ref() { - use crate::diesel::BoolExpressionMethods; + // Filter for environment variables from the CLI + // + // If we get a filter for environment on CLI, we fetch all job ids that are associated with the + // passed environment variables and make `sel` filter for those. + let sel = if let Some((name, val)) = matches.value_of("filter_env").map(crate::util::env::parse_to_env).transpose()? { + let jids = schema::envvars::table + .filter({ + use crate::diesel::BoolExpressionMethods; + schema::envvars::dsl::name.eq(name.as_ref()) + .and(schema::envvars::dsl::value.eq(val)) + }) + .inner_join(schema::job_envs::table) + .select(schema::job_envs::all_columns) + .load::(&conn) + .map(|jobenvs| jobenvs.into_iter().map(|je| je.job_id).collect::>())?; - sel.filter({ - schema::envvars::dsl::name.eq(name.as_ref()) - .and(schema::envvars::dsl::value.eq(val)) - }) + sel.filter(schema::jobs::dsl::id.eq_any(jids)) } else { sel }; - let jobs = sel.load::<( - models::Job, - models::Submit, - models::Endpoint, - models::Package, - Option<(models::JobEnv, models::EnvVar)>, - )>(&conn)?; - - let data = jobs - .iter() - .group_by(|(job, submit, ep, package, _)| { - (job, submit, ep, package) - }); - - let data = data + let data = sel.load::<(models::Job, models::Submit, models::Endpoint, models::Package)>(&conn)? .into_iter() - .map(|((job, submit, ep, package), grouped)| { - let envs = grouped - .filter_map(|opt| opt.4.as_ref()) - .map(|tpl| format!("{}={}", tpl.1.name, tpl.1.value)) - .join(", "); - + .map(|(job, submit, ep, package)| { let success = crate::log::ParsedLog::build_from(&job.log_text)? .is_successfull() .map(|b| if b { "yes" } else { "no" }) @@ -369,11 +354,10 @@ fn jobs(conn_cfg: DbConnectionConfig, matches: &ArgMatches) -> Result<()> { submit.uuid.to_string(), job.uuid.to_string(), submit.submit_time.to_string(), - ep.name.clone(), + ep.name, success, - package.name.clone(), - package.version.clone(), - envs, + package.name, + package.version, ]) }) .collect::>>()?; -- cgit v1.2.3