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 0228423
Showing 1 changed file with 46 additions and 19 deletions.
65 changes: 46 additions & 19 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 Down

0 comments on commit 0228423

Please sign in to comment.