Skip to content

Commit 0228423

Browse files
committed
Resolves rust-lang#530 - add_package logic, make database calls in for loops
1 parent 55c7386 commit 0228423

File tree

1 file changed

+46
-19
lines changed

1 file changed

+46
-19
lines changed

src/db/add_package.rs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
collections::HashMap,
23
fs,
34
io::{BufRead, BufReader},
45
path::Path,
@@ -316,28 +317,54 @@ fn add_keywords_into_database(
316317
pkg: &MetadataPackage,
317318
release_id: i32,
318319
) -> Result<()> {
319-
for keyword in &pkg.keywords {
320-
let slug = slugify(&keyword);
321-
let keyword_id: i32 = {
322-
let rows = conn.query("SELECT id FROM keywords WHERE slug = $1", &[&slug])?;
323-
if !rows.is_empty() {
324-
rows[0].get(0)
325-
} else {
326-
conn.query(
327-
"INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id",
328-
&[&keyword, &slug],
329-
)?[0]
330-
.get(0)
331-
}
332-
};
320+
let wanted_keywords: HashMap<String, String> = pkg
321+
.keywords
322+
.iter()
323+
.map(|kw| (slugify(&kw), kw.clone()))
324+
.collect();
325+
326+
let mut existing_keyword_slugs: HashMap<String, i32> = conn
327+
.query(
328+
"SELECT slug, id FROM keywords WHERE slug IN $1",
329+
&[&wanted_keywords.keys().collect::<Vec<_>>()],
330+
)?
331+
.iter()
332+
.map(|row| (row.get("slug"), row.get("id")))
333+
.collect();
333334

334-
// add releationship
335-
let _ = conn.query(
336-
"INSERT INTO keyword_rels (rid, kid) VALUES ($1, $2)",
337-
&[&release_id, &keyword_id],
338-
);
335+
let new_keywords: Vec<(&String, &String)> = wanted_keywords
336+
.iter()
337+
.filter(|(k, _)| !(existing_keyword_slugs.contains_key(*k)))
338+
.collect();
339+
340+
if !new_keywords.is_empty() {
341+
// we create new keywords one-by-one, since most of the time we already have them,
342+
// and because support for multi-record inserts is a mess without adding a new
343+
// library
344+
let insert_keyword_query =
345+
conn.prepare("INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id")?;
346+
347+
for (slug, name) in new_keywords {
348+
existing_keyword_slugs.insert(
349+
slug.clone(),
350+
conn.query_one(&insert_keyword_query, &[&name, &slug])?
351+
.get(0),
352+
);
353+
}
339354
}
340355

356+
conn.query(
357+
"INSERT INTO keyword_rels (rid, kid)
358+
SELECT
359+
$1 as rid,
360+
id as kid
361+
FROM
362+
keywords
363+
WHERE
364+
slug in $2",
365+
&[&release_id, &wanted_keywords.keys().collect::<Vec<_>>()],
366+
)?;
367+
341368
Ok(())
342369
}
343370

0 commit comments

Comments
 (0)