From d3b3ae165fd61863e001aab70daddbf7b3354984 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 10 Oct 2024 14:54:26 +0200 Subject: [PATCH 1/2] admin/transfer_crates: Count owners directly via SQL query `krate.owners()` runs two queries and loads all details of the users/teams, while all what we want is the number of owners. This commit replaces the call with a simple `SELECT COUNT(*)` query. --- src/admin/transfer_crates.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/admin/transfer_crates.rs b/src/admin/transfer_crates.rs index cc1a74955cd..05dff0b8d92 100644 --- a/src/admin/transfer_crates.rs +++ b/src/admin/transfer_crates.rs @@ -68,8 +68,13 @@ fn transfer(opts: Opts, conn: &mut PgConnection) -> anyhow::Result<()> { .load(conn)?; for krate in crates { - let owners = krate.owners(conn)?; - if owners.len() != 1 { + let num_owners: i64 = crate_owners::table + .count() + .filter(crate_owners::deleted.eq(false)) + .filter(crate_owners::crate_id.eq(krate.id)) + .get_result(conn)?; + + if num_owners != 1 { println!("warning: not exactly one owner for {}", krate.name); } } From 6f600a60cccd7f8ae664c8a72d0bfd1684c64867 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 10 Oct 2024 14:45:52 +0200 Subject: [PATCH 2/2] admin/transfer_crates: Replace `spawn_blocking()` with `diesel_async` usage --- src/admin/transfer_crates.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/admin/transfer_crates.rs b/src/admin/transfer_crates.rs index 05dff0b8d92..5d894ef7791 100644 --- a/src/admin/transfer_crates.rs +++ b/src/admin/transfer_crates.rs @@ -5,8 +5,8 @@ use crate::{ schema::{crate_owners, crates, users}, }; -use crate::tasks::spawn_blocking; use diesel::prelude::*; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; #[derive(clap::Parser, Debug)] #[command( @@ -21,22 +21,21 @@ pub struct Opts { } pub async fn run(opts: Opts) -> anyhow::Result<()> { - spawn_blocking(move || { - let conn = &mut db::oneoff_connection()?; - transfer(opts, conn)?; - Ok(()) - }) - .await + let mut conn = db::oneoff_async_connection().await?; + transfer(opts, &mut conn).await?; + Ok(()) } -fn transfer(opts: Opts, conn: &mut PgConnection) -> anyhow::Result<()> { +async fn transfer(opts: Opts, conn: &mut AsyncPgConnection) -> anyhow::Result<()> { let from: User = users::table .filter(users::gh_login.eq(opts.from_user)) - .first(conn)?; + .first(conn) + .await?; let to: User = users::table .filter(users::gh_login.eq(opts.to_user)) - .first(conn)?; + .first(conn) + .await?; if from.gh_id != to.gh_id { println!("===================================================="); @@ -47,7 +46,7 @@ fn transfer(opts: Opts, conn: &mut PgConnection) -> anyhow::Result<()> { println!("from: {:?}", from.gh_id); println!("to: {:?}", to.gh_id); - if !dialoguer::confirm("continue?")? { + if !dialoguer::async_confirm("continue?").await? { return Ok(()); } } @@ -56,7 +55,7 @@ fn transfer(opts: Opts, conn: &mut PgConnection) -> anyhow::Result<()> { "Are you sure you want to transfer crates from {} to {}?", from.gh_login, to.gh_login ); - if !dialoguer::confirm(&prompt)? { + if !dialoguer::async_confirm(&prompt).await? { return Ok(()); } @@ -65,27 +64,30 @@ fn transfer(opts: Opts, conn: &mut PgConnection) -> anyhow::Result<()> { .filter(crate_owners::owner_kind.eq(OwnerKind::User)); let crates: Vec = Crate::all() .filter(crates::id.eq_any(crate_owners.select(crate_owners::crate_id))) - .load(conn)?; + .load(conn) + .await?; for krate in crates { let num_owners: i64 = crate_owners::table .count() .filter(crate_owners::deleted.eq(false)) .filter(crate_owners::crate_id.eq(krate.id)) - .get_result(conn)?; + .get_result(conn) + .await?; if num_owners != 1 { println!("warning: not exactly one owner for {}", krate.name); } } - if !dialoguer::confirm("commit?")? { + if !dialoguer::async_confirm("commit?").await? { return Ok(()); } diesel::update(crate_owners) .set(crate_owners::owner_id.eq(to.id)) - .execute(conn)?; + .execute(conn) + .await?; Ok(()) }