Skip to content

Commit

Permalink
Resolves rust-lang#530 - add_package logic, make database calls in f…
Browse files Browse the repository at this point in the history
…or loops
  • Loading branch information
syphar committed Apr 18, 2021
1 parent 55c7386 commit 12ee52a
Showing 1 changed file with 62 additions and 36 deletions.
98 changes: 62 additions & 36 deletions src/db/add_package.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::HashMap,
fs,
io::{BufRead, BufReader},
path::Path,
Expand Down Expand Up @@ -316,28 +317,54 @@ fn add_keywords_into_database(
pkg: &MetadataPackage,
release_id: i32,
) -> Result<()> {
for keyword in &pkg.keywords {
let slug = slugify(&keyword);
let keyword_id: i32 = {
let rows = conn.query("SELECT id FROM keywords WHERE slug = $1", &[&slug])?;
if !rows.is_empty() {
rows[0].get(0)
} else {
conn.query(
"INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id",
&[&keyword, &slug],
)?[0]
.get(0)
}
};
let wanted_keywords: HashMap<String, String> = pkg
.keywords
.iter()
.map(|kw| (slugify(&kw), kw.clone()))
.collect();

let mut existing_keyword_slugs: HashMap<String, i32> = conn
.query(
"SELECT slug, id FROM keywords WHERE slug IN $1",
&[&wanted_keywords.keys().collect::<Vec<_>>()],
)?
.iter()
.map(|row| (row.get("slug"), row.get("id")))
.collect();

// add releationship
let _ = conn.query(
"INSERT INTO keyword_rels (rid, kid) VALUES ($1, $2)",
&[&release_id, &keyword_id],
);
let new_keywords: Vec<(&String, &String)> = wanted_keywords
.iter()
.filter(|(k, _)| !(existing_keyword_slugs.contains_key(*k)))
.collect();

if !new_keywords.is_empty() {
// we create new keywords one-by-one, since most of the time we already have them,
// and because support for multi-record inserts is a mess without adding a new
// library
let insert_keyword_query =
conn.prepare("INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id")?;

for (slug, name) in new_keywords {
existing_keyword_slugs.insert(
slug.clone(),
conn.query_one(&insert_keyword_query, &[&name, &slug])?
.get(0),
);
}
}

conn.query(
"INSERT INTO keyword_rels (rid, kid)
SELECT
$1 as rid,
id as kid
FROM
keywords
WHERE
slug in $2",
&[&release_id, &wanted_keywords.keys().collect::<Vec<_>>()],
)?;

Ok(())
}

Expand All @@ -347,7 +374,9 @@ pub fn update_crate_data_in_database(
registry_data: &CrateData,
) -> Result<()> {
info!("Updating crate data for {}", name);
let crate_id = conn.query("SELECT id FROM crates WHERE crates.name = $1", &[&name])?[0].get(0);
let crate_id = conn
.query_one("SELECT id FROM crates WHERE crates.name = $1", &[&name])?
.get(0);

update_owners_in_database(conn, &registry_data.owners, crate_id)?;

Expand Down Expand Up @@ -401,23 +430,20 @@ fn update_owners_in_database(
)?;
}

let to_remove =
existing_owners.filter(|login| !owners.iter().any(|owner| &owner.login == login));
let to_remove: Vec<String> = existing_owners
.filter(|login| !owners.iter().any(|owner| &owner.login == login))
.collect();

for login in to_remove {
debug!("Removing owner relationship {}", login);
// remove relationship
conn.query(
"
DELETE FROM owner_rels
USING owners
WHERE owner_rels.cid = $1
AND owner_rels.oid = owners.id
AND owners.login = $2
",
&[&crate_id, &login],
)?;
}
conn.query(
"
DELETE FROM owner_rels
USING owners
WHERE owner_rels.cid = $1
AND owner_rels.oid = owners.id
AND owners.login IN $2
",
&[&crate_id, &to_remove],
)?;

Ok(())
}
Expand Down

0 comments on commit 12ee52a

Please sign in to comment.