Skip to content

Commit b35f76a

Browse files
committed
Rename a few poorly named methods, add some transactions
All the methods which do >1 query which modifies data should be wrapped in a transaction
1 parent 0d7e68b commit b35f76a

File tree

4 files changed

+65
-57
lines changed

4 files changed

+65
-57
lines changed

src/category.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,19 +97,21 @@ impl Category {
9797
slugs: &[&'a str]) -> QueryResult<Vec<&'a str>> {
9898
use diesel::expression::dsl::any;
9999

100-
let categories = categories::table
101-
.filter(categories::slug.eq(any(slugs)))
102-
.load::<Category>(conn)?;
103-
let invalid_categories = slugs.iter().cloned()
104-
.filter(|s| !categories.iter().any(|c| c.slug == *s))
105-
.collect();
106-
let crate_categories = categories.iter()
107-
.map(|c| CrateCategory { category_id: c.id, crate_id: krate.id })
108-
.collect::<Vec<_>>();
109-
110-
delete(CrateCategory::belonging_to(krate)).execute(conn)?;
111-
insert(&crate_categories).into(crates_categories::table).execute(conn)?;
112-
Ok(invalid_categories)
100+
conn.transaction(|| {
101+
let categories = categories::table
102+
.filter(categories::slug.eq(any(slugs)))
103+
.load::<Category>(conn)?;
104+
let invalid_categories = slugs.iter().cloned()
105+
.filter(|s| !categories.iter().any(|c| c.slug == *s))
106+
.collect();
107+
let crate_categories = categories.iter()
108+
.map(|c| CrateCategory { category_id: c.id, crate_id: krate.id })
109+
.collect::<Vec<_>>();
110+
111+
delete(CrateCategory::belonging_to(krate)).execute(conn)?;
112+
insert(&crate_categories).into(crates_categories::table).execute(conn)?;
113+
Ok(invalid_categories)
114+
})
113115
}
114116

115117
pub fn update_crate_old(conn: &GenericConnection,
@@ -237,7 +239,7 @@ pub struct NewCategory<'a> {
237239
}
238240

239241
impl<'a> NewCategory<'a> {
240-
pub fn create_or_update(&self, conn: &PgConnection) -> QueryResult<Category> {
242+
pub fn find_or_create(&self, conn: &PgConnection) -> QueryResult<Category> {
241243
use schema::categories::dsl::*;
242244
use diesel::pg::upsert::*;
243245

src/keyword.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl Keyword {
5252
Ok(rows.iter().next().map(|r| Model::from_row(&r)))
5353
}
5454

55-
pub fn find_all(conn: &PgConnection, names: &[&str]) -> QueryResult<Vec<Keyword>> {
55+
pub fn find_or_create_all(conn: &PgConnection, names: &[&str]) -> QueryResult<Vec<Keyword>> {
5656
use diesel::pg::upsert::*;
5757
use diesel::expression::dsl::any;
5858

@@ -130,15 +130,17 @@ impl Keyword {
130130
pub fn update_crate(conn: &PgConnection,
131131
krate: &Crate,
132132
keywords: &[&str]) -> QueryResult<()> {
133-
let keywords = Keyword::find_all(conn, keywords)?;
134-
diesel::delete(CrateKeyword::belonging_to(krate))
135-
.execute(conn)?;
136-
let crate_keywords = keywords.into_iter().map(|kw| {
137-
CrateKeyword { crate_id: krate.id, keyword_id: kw.id }
138-
}).collect::<Vec<_>>();
139-
diesel::insert(&crate_keywords).into(crates_keywords::table)
140-
.execute(conn)?;
141-
Ok(())
133+
conn.transaction(|| {
134+
let keywords = Keyword::find_or_create_all(conn, keywords)?;
135+
diesel::delete(CrateKeyword::belonging_to(krate))
136+
.execute(conn)?;
137+
let crate_keywords = keywords.into_iter().map(|kw| {
138+
CrateKeyword { crate_id: krate.id, keyword_id: kw.id }
139+
}).collect::<Vec<_>>();
140+
diesel::insert(&crate_keywords).into(crates_keywords::table)
141+
.execute(conn)?;
142+
Ok(())
143+
})
142144
}
143145

144146
pub fn update_crate_old(conn: &GenericConnection,

src/krate.rs

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,24 @@ impl<'a> NewCrate<'a> {
123123
self.validate(license_file)?;
124124
self.ensure_name_not_reserved(conn)?;
125125

126-
// To avoid race conditions, we try to insert
127-
// first so we know whether to add an owner
128-
if let Some(krate) = self.save_new_crate(conn, uploader)? {
129-
return Ok(krate)
130-
}
131-
132-
// We don't want to change the max_upload_size
133-
self.max_upload_size = None;
126+
conn.transaction(|| {
127+
// To avoid race conditions, we try to insert
128+
// first so we know whether to add an owner
129+
if let Some(krate) = self.save_new_crate(conn, uploader)? {
130+
return Ok(krate)
131+
}
134132

135-
let target = crates::table.filter(
136-
canon_crate_name(crates::name)
137-
.eq(canon_crate_name(self.name)));
138-
update(target).set(&self)
139-
.returning(ALL_COLUMNS)
140-
.get_result(conn)
141-
.map_err(Into::into)
133+
// We don't want to change the max_upload_size
134+
self.max_upload_size = None;
135+
136+
let target = crates::table.filter(
137+
canon_crate_name(crates::name)
138+
.eq(canon_crate_name(self.name)));
139+
update(target).set(&self)
140+
.returning(ALL_COLUMNS)
141+
.get_result(conn)
142+
.map_err(Into::into)
143+
})
142144
}
143145

144146
fn validate(&mut self, license_file: Option<&str>) -> CargoResult<()> {
@@ -205,23 +207,25 @@ impl<'a> NewCrate<'a> {
205207
use schema::crates::dsl::*;
206208
use diesel::insert;
207209

208-
let maybe_inserted = insert(&self.on_conflict_do_nothing()).into(crates)
209-
.returning(ALL_COLUMNS)
210-
.get_result::<Crate>(conn)
211-
.optional()?;
212-
213-
if let Some(ref krate) = maybe_inserted {
214-
let owner = CrateOwner {
215-
crate_id: krate.id,
216-
owner_id: user_id,
217-
created_by: user_id,
218-
owner_kind: OwnerKind::User as i32,
219-
};
220-
insert(&owner).into(crate_owners::table)
221-
.execute(conn)?;
222-
}
210+
conn.transaction(|| {
211+
let maybe_inserted = insert(&self.on_conflict_do_nothing()).into(crates)
212+
.returning(ALL_COLUMNS)
213+
.get_result::<Crate>(conn)
214+
.optional()?;
215+
216+
if let Some(ref krate) = maybe_inserted {
217+
let owner = CrateOwner {
218+
crate_id: krate.id,
219+
owner_id: user_id,
220+
created_by: user_id,
221+
owner_kind: OwnerKind::User as i32,
222+
};
223+
insert(&owner).into(crate_owners::table)
224+
.execute(conn)?;
225+
}
223226

224-
Ok(maybe_inserted)
227+
Ok(maybe_inserted)
228+
})
225229
}
226230
}
227231

src/tests/krate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ fn index_queries() {
143143
let mut response = ok_resp!(middle.call(req.with_query("keyword=kw2")));
144144
assert_eq!(::json::<CrateList>(&mut response).crates.len(), 0);
145145

146-
::new_category("cat1", "cat1").create_or_update(req.db_conn().unwrap()).unwrap();
147-
::new_category("cat1::bar", "cat1::bar").create_or_update(req.db_conn().unwrap()).unwrap();
146+
::new_category("cat1", "cat1").find_or_create(req.db_conn().unwrap()).unwrap();
147+
::new_category("cat1::bar", "cat1::bar").find_or_create(req.db_conn().unwrap()).unwrap();
148148
Category::update_crate(req.db_conn().unwrap(), &krate, &["cat1"]).unwrap();
149149
Category::update_crate(req.db_conn().unwrap(), &krate2, &["cat1::bar"]).unwrap();
150150
let mut response = ok_resp!(middle.call(req.with_query("category=cat1")));

0 commit comments

Comments
 (0)