Skip to content

Commit 13bf9cd

Browse files
committed
Port categories::sync over to use Diesel
I've changed this to do the whole thing in one insert rather than one per category.
1 parent fcca5cc commit 13bf9cd

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

src/categories.rs

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// Sync available crate categories from `src/categories.toml`.
22
// Runs when the server is started.
33

4+
use diesel;
5+
use diesel::prelude::*;
46
use toml;
57

68
use db;
9+
use schema::categories;
710
use util::errors::{CargoResult, ChainError, internal};
811

912
#[derive(Debug)]
@@ -87,45 +90,54 @@ fn categories_from_toml(
8790
Ok(result)
8891
}
8992

93+
#[derive(Insertable)]
94+
#[table_name = "categories"]
95+
struct NewCategory {
96+
slug: String,
97+
category: String,
98+
description: String,
99+
}
100+
90101
pub fn sync() -> CargoResult<()> {
91-
let conn = db::connect_now_old();
92-
let tx = conn.transaction().unwrap();
102+
use diesel::pg::upsert::*;
103+
use diesel::expression::dsl::any;
104+
105+
let conn = db::connect_now().unwrap();
93106

94107
let categories = include_str!("./categories.toml");
95108
let toml: toml::value::Table =
96109
toml::from_str(categories).expect("Could not parse categories.toml");
97110

98-
let categories =
99-
categories_from_toml(&toml, None).expect("Could not convert categories from TOML");
100-
101-
for category in &categories {
102-
tx.execute(
103-
"\
104-
INSERT INTO categories (slug, category, description) \
105-
VALUES (LOWER($1), $2, $3) \
106-
ON CONFLICT (slug) DO UPDATE \
107-
SET category = EXCLUDED.category, \
108-
description = EXCLUDED.description;",
109-
&[&category.slug, &category.name, &category.description],
110-
)?;
111-
}
112-
113-
let in_clause = categories
114-
.iter()
115-
.map(|category| format!("LOWER('{}')", category.slug))
116-
.collect::<Vec<_>>()
117-
.join(",");
118-
119-
tx.execute(
120-
&format!(
121-
"\
122-
DELETE FROM categories \
123-
WHERE slug NOT IN ({});",
124-
in_clause
125-
),
126-
&[],
127-
)?;
128-
tx.set_commit();
129-
tx.finish().unwrap();
130-
Ok(())
111+
let categories = categories_from_toml(&toml, None)
112+
.expect("Could not convert categories from TOML")
113+
.into_iter()
114+
.map(|c| {
115+
NewCategory {
116+
slug: c.slug.to_lowercase(),
117+
category: c.name,
118+
description: c.description,
119+
}
120+
})
121+
.collect::<Vec<_>>();
122+
123+
let to_insert = categories.on_conflict(
124+
categories::slug,
125+
do_update().set((
126+
categories::category.eq(excluded(categories::category)),
127+
categories::description.eq(
128+
excluded(categories::description),
129+
),
130+
)),
131+
);
132+
133+
conn.transaction(|| {
134+
let slugs = diesel::insert(&to_insert)
135+
.into(categories::table)
136+
.returning(categories::slug)
137+
.get_results::<String>(&conn)?;
138+
139+
let to_delete = categories::table.filter(categories::slug.ne(any(slugs)));
140+
diesel::delete(to_delete).execute(&conn)?;
141+
Ok(())
142+
})
131143
}

0 commit comments

Comments
 (0)