Skip to content

Commit ab6eb95

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 7a38329 commit ab6eb95

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
@@ -124,22 +124,24 @@ impl<'a> NewCrate<'a> {
124124
self.validate(license_file)?;
125125
self.ensure_name_not_reserved(conn)?;
126126

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

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

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

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

225-
Ok(maybe_inserted)
228+
Ok(maybe_inserted)
229+
})
226230
}
227231
}
228232

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)