Skip to content

Commit 1fc6226

Browse files
committed
admin/delete_crate: Aggregate owner names within the query
1 parent a6e1a45 commit 1fc6226

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

src/admin/delete_crate.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
use crate::schema::{crate_downloads, crate_owners, teams, users};
1+
use crate::schema::crate_downloads;
22
use crate::worker::jobs;
33
use crate::{admin::dialoguer, db, schema::crates};
44
use anyhow::Context;
55
use colored::Colorize;
66
use crates_io_worker::BackgroundJob;
77
use diesel::dsl::sql;
8-
use diesel::sql_types::Text;
9-
use diesel::{ExpressionMethods, JoinOnDsl, QueryDsl};
8+
use diesel::sql_types::{Array, Text};
9+
use diesel::{ExpressionMethods, QueryDsl};
1010
use diesel_async::RunQueryDsl;
11+
use futures_util::TryStreamExt;
1112
use std::collections::HashMap;
1213
use std::fmt::Display;
1314

@@ -35,32 +36,38 @@ pub async fn run(opts: Opts) -> anyhow::Result<()> {
3536
let mut crate_names = opts.crate_names;
3637
crate_names.sort();
3738

38-
let query_result = crates::table
39+
let existing_crates = crates::table
3940
.inner_join(crate_downloads::table)
40-
.left_join(crate_owners::table.on(crate_owners::crate_id.eq(crates::id)))
41-
.left_join(teams::table.on(teams::id.eq(crate_owners::owner_id)))
42-
.left_join(users::table.on(users::id.eq(crate_owners::owner_id)))
4341
.filter(crates::name.eq_any(&crate_names))
4442
.select((
4543
crates::name,
4644
crates::id,
4745
crate_downloads::downloads,
48-
sql::<Text>(
49-
"CASE WHEN crate_owners.owner_kind = 1 THEN teams.login ELSE users.gh_login END",
46+
sql::<Array<Text>>(
47+
r#"
48+
ARRAY(
49+
SELECT
50+
CASE WHEN crate_owners.owner_kind = 1 THEN
51+
teams.login
52+
ELSE
53+
users.gh_login
54+
END
55+
FROM crate_owners
56+
LEFT JOIN teams ON teams.id = crate_owners.owner_id
57+
LEFT JOIN users ON users.id = crate_owners.owner_id
58+
WHERE crate_owners.crate_id = crates.id
59+
)
60+
"#,
5061
),
5162
))
52-
.load::<(String, i32, i64, String)>(&mut conn)
63+
.load_stream::<(String, i32, i64, Vec<String>)>(&mut conn)
5364
.await
54-
.context("Failed to look up crate name from the database")?;
55-
56-
let mut existing_crates: HashMap<String, CrateInfo> = HashMap::new();
57-
for (name, id, downloads, login) in query_result {
58-
let entry = existing_crates
59-
.entry(name)
60-
.or_insert_with(|| CrateInfo::new(id, downloads));
61-
62-
entry.owners.push(login);
63-
}
65+
.context("Failed to look up crate name from the database")?
66+
.try_fold(HashMap::new(), |mut map, (name, id, downloads, owners)| {
67+
map.insert(name, CrateInfo::new(id, downloads, owners));
68+
futures_util::future::ready(Ok(map))
69+
})
70+
.await?;
6471

6572
println!("Deleting the following crates:");
6673
println!();
@@ -122,11 +129,11 @@ struct CrateInfo {
122129
}
123130

124131
impl CrateInfo {
125-
pub fn new(id: i32, downloads: i64) -> Self {
132+
pub fn new(id: i32, downloads: i64, owners: Vec<String>) -> Self {
126133
Self {
127134
id,
128135
downloads,
129-
owners: Vec::with_capacity(1),
136+
owners,
130137
}
131138
}
132139
}

0 commit comments

Comments
 (0)