Skip to content

Commit 03690e8

Browse files
committed
Refactor queries to use the more semantic postgres::Client methods
1 parent 5c7f288 commit 03690e8

17 files changed

+194
-196
lines changed

src/bin/cratesfyi.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,12 @@ impl BuildSubcommand {
371371
.pool()?
372372
.get()
373373
.context("failed to get a database connection")?;
374-
let res =
375-
conn.query("SELECT * FROM config WHERE name = 'rustc_version';", &[])?;
374+
let res = conn.query_one(
375+
"SELECT COUNT(*) > 1 FROM config WHERE name = 'rustc_version';",
376+
&[],
377+
)?;
376378

377-
if !res.is_empty() {
379+
if res.get(0) {
378380
println!("update-toolchain was already called in the past, exiting");
379381
return Ok(());
380382
}

src/build_queue.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,27 @@ impl BuildQueue {
3535
}
3636

3737
pub(crate) fn pending_count(&self) -> Result<usize> {
38-
let res = self.db.get()?.query(
38+
let res = self.db.get()?.query_one(
3939
"SELECT COUNT(*) FROM queue WHERE attempt < $1;",
4040
&[&self.max_attempts],
4141
)?;
42-
Ok(res[0].get::<_, i64>(0) as usize)
42+
Ok(res.get::<_, i64>(0) as usize)
4343
}
4444

4545
pub(crate) fn prioritized_count(&self) -> Result<usize> {
46-
let res = self.db.get()?.query(
46+
let res = self.db.get()?.query_one(
4747
"SELECT COUNT(*) FROM queue WHERE attempt < $1 AND priority <= 0;",
4848
&[&self.max_attempts],
4949
)?;
50-
Ok(res[0].get::<_, i64>(0) as usize)
50+
Ok(res.get::<_, i64>(0) as usize)
5151
}
5252

5353
pub(crate) fn failed_count(&self) -> Result<usize> {
54-
let res = self.db.get()?.query(
54+
let res = self.db.get()?.query_one(
5555
"SELECT COUNT(*) FROM queue WHERE attempt >= $1;",
5656
&[&self.max_attempts],
5757
)?;
58-
Ok(res[0].get::<_, i64>(0) as usize)
58+
Ok(res.get::<_, i64>(0) as usize)
5959
}
6060

6161
pub(crate) fn queued_crates(&self) -> Result<Vec<QueuedCrate>> {
@@ -98,11 +98,11 @@ impl BuildQueue {
9898
}
9999
Err(e) => {
100100
// Increase attempt count
101-
let rows = conn.query(
101+
let rows = conn.query_one(
102102
"UPDATE queue SET attempt = attempt + 1 WHERE id = $1 RETURNING attempt;",
103103
&[&to_process.id],
104104
)?;
105-
let attempt: i32 = rows[0].get(0);
105+
let attempt: i32 = rows.get(0);
106106

107107
if attempt >= self.max_attempts {
108108
crate::web::metrics::FAILED_BUILDS.inc();

src/db/add_package.rs

+67-45
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub(crate) fn add_build_into_database(
137137
res: &BuildResult,
138138
) -> Result<i32> {
139139
debug!("Adding build into database");
140-
let rows = conn.query(
140+
let row = conn.query_one(
141141
"INSERT INTO builds (rid, rustc_version,
142142
cratesfyi_version,
143143
build_status, output)
@@ -151,19 +151,23 @@ pub(crate) fn add_build_into_database(
151151
&res.build_log,
152152
],
153153
)?;
154-
Ok(rows[0].get(0))
154+
Ok(row.get(0))
155155
}
156156

157157
fn initialize_package_in_database(conn: &mut Client, pkg: &MetadataPackage) -> Result<i32> {
158-
let mut rows = conn.query("SELECT id FROM crates WHERE name = $1", &[&pkg.name])?;
159158
// insert crate into database if it is not exists
160-
if rows.is_empty() {
161-
rows = conn.query(
162-
"INSERT INTO crates (name) VALUES ($1) RETURNING id",
163-
&[&pkg.name],
164-
)?;
165-
}
166-
Ok(rows[0].get(0))
159+
let row = conn
160+
.query_opt("SELECT id FROM crates WHERE name = $1", &[&pkg.name])
161+
.transpose()
162+
.unwrap_or_else(|| {
163+
conn.query_one(
164+
"INSERT INTO crates (name)
165+
VALUES ($1)
166+
RETURNING id",
167+
&[&pkg.name],
168+
)
169+
})?;
170+
Ok(row.get(0))
167171
}
168172

169173
/// Convert dependencies into Vec<(String, String, String)>
@@ -257,23 +261,26 @@ fn add_keywords_into_database(
257261
for keyword in &pkg.keywords {
258262
let slug = slugify(&keyword);
259263
let keyword_id: i32 = {
260-
let rows = conn.query("SELECT id FROM keywords WHERE slug = $1", &[&slug])?;
261-
if !rows.is_empty() {
262-
rows[0].get(0)
263-
} else {
264-
conn.query(
265-
"INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id",
266-
&[&keyword, &slug],
267-
)?[0]
268-
.get(0)
269-
}
264+
conn.query_opt("SELECT id FROM keywords WHERE slug = $1", &[&slug])
265+
.transpose()
266+
.unwrap_or_else(|| {
267+
conn.query_one(
268+
"INSERT INTO keywords (name, slug)
269+
VALUES ($1, $2)
270+
RETURNING id",
271+
&[&keyword, &slug],
272+
)
273+
})?
274+
.get(0)
270275
};
271276

272-
// add releationship
273-
let _ = conn.query(
274-
"INSERT INTO keyword_rels (rid, kid) VALUES ($1, $2)",
277+
// add relationship
278+
conn.execute(
279+
"INSERT INTO keyword_rels (rid, kid)
280+
VALUES ($1, $2)
281+
ON CONFLICT DO NOTHING",
275282
&[&release_id, &keyword_id],
276-
);
283+
)?;
277284
}
278285

279286
Ok(())
@@ -301,24 +308,32 @@ fn add_authors_into_database(
301308
let slug = slugify(&author);
302309

303310
let author_id: i32 = {
304-
let rows = conn.query("SELECT id FROM authors WHERE slug = $1", &[&slug])?;
305-
if !rows.is_empty() {
306-
rows[0].get(0)
307-
} else {
308-
conn.query(
309-
"INSERT INTO authors (name, email, slug) VALUES ($1, $2, $3)
310-
RETURNING id",
311-
&[&author, &email, &slug],
312-
)?[0]
313-
.get(0)
314-
}
311+
// TODO: If an author uses different email addresses per crate, or multiple authors
312+
// have the same slugified name, this will flip-flop their name and email address
313+
// on each crate publish.
314+
//
315+
// But, at least doing an upsert will result in their email/exact name rendering
316+
// being updated if they change it in a new release.
317+
conn.query_one(
318+
"INSERT INTO authors (name, email, slug)
319+
VALUES ($1, $2, $3)
320+
ON CONFLICT (slug) DO UPDATE
321+
SET
322+
name = $1,
323+
email = $2
324+
RETURNING id",
325+
&[&author, &email, &slug],
326+
)?
327+
.get(0)
315328
};
316329

317330
// add relationship
318-
let _ = conn.query(
319-
"INSERT INTO author_rels (rid, aid) VALUES ($1, $2)",
331+
conn.execute(
332+
"INSERT INTO author_rels (rid, aid)
333+
VALUES ($1, $2)
334+
ON CONFLICT DO NOTHING",
320335
&[&release_id, &author_id],
321-
);
336+
)?;
322337
}
323338
}
324339

@@ -331,7 +346,14 @@ pub fn update_crate_data_in_database(
331346
registry_data: &CrateData,
332347
) -> Result<()> {
333348
info!("Updating crate data for {}", name);
334-
let crate_id = conn.query("SELECT id FROM crates WHERE crates.name = $1", &[&name])?[0].get(0);
349+
let crate_id = conn
350+
.query_one(
351+
"SELECT id
352+
FROM crates
353+
WHERE crates.name = $1",
354+
&[&name],
355+
)?
356+
.get(0);
335357

336358
update_owners_in_database(conn, &registry_data.owners, crate_id)?;
337359

@@ -362,7 +384,7 @@ fn update_owners_in_database(
362384
// Update any existing owner data since it is mutable and could have changed since last
363385
// time we pulled it
364386
let owner_id: i32 = {
365-
conn.query(
387+
conn.query_one(
366388
"
367389
INSERT INTO owners (login, avatar, name, email)
368390
VALUES ($1, $2, $3, $4)
@@ -374,12 +396,12 @@ fn update_owners_in_database(
374396
RETURNING id
375397
",
376398
&[&owner.login, &owner.avatar, &owner.name, &owner.email],
377-
)?[0]
378-
.get(0)
399+
)?
400+
.get(0)
379401
};
380402

381403
// add relationship
382-
conn.query(
404+
conn.execute(
383405
"INSERT INTO owner_rels (cid, oid) VALUES ($1, $2) ON CONFLICT DO NOTHING",
384406
&[&crate_id, &owner_id],
385407
)?;
@@ -391,7 +413,7 @@ fn update_owners_in_database(
391413
for login in to_remove {
392414
debug!("Removing owner relationship {}", login);
393415
// remove relationship
394-
conn.query(
416+
conn.execute(
395417
"
396418
DELETE FROM owner_rels
397419
USING owners
@@ -417,7 +439,7 @@ where
417439
ON CONFLICT DO NOTHING;";
418440
let prepared = conn.prepare(sql)?;
419441
for alg in algorithms {
420-
conn.query(&prepared, &[&release_id, &(alg as i32)])?;
442+
conn.execute(&prepared, &[&release_id, &(alg as i32)])?;
421443
}
422444
Ok(())
423445
}

src/db/blacklist.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ enum BlacklistError {
1212

1313
/// Returns whether the given name is blacklisted.
1414
pub fn is_blacklisted(conn: &mut Client, name: &str) -> Result<bool, Error> {
15-
let rows = conn.query(
15+
let row = conn.query_one(
1616
"SELECT COUNT(*) FROM blacklisted_crates WHERE crate_name = $1;",
1717
&[&name],
1818
)?;
19-
let count: i64 = rows[0].get(0);
19+
let count: i64 = row.get(0);
2020

2121
Ok(count != 0)
2222
}

src/db/delete.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ pub fn delete_version(
3939
}
4040

4141
fn get_id(conn: &mut Client, name: &str) -> Result<i32, Error> {
42-
let crate_id_res = conn.query("SELECT id FROM crates WHERE name = $1", &[&name])?;
43-
if let Some(row) = crate_id_res.into_iter().next() {
42+
let row = conn.query_opt("SELECT id FROM crates WHERE name = $1", &[&name])?;
43+
if let Some(row) = row {
4444
Ok(row.get("id"))
4545
} else {
4646
Err(CrateDeletionError::MissingCrate(name.into()).into())
@@ -123,15 +123,15 @@ mod tests {
123123
use postgres::Client;
124124

125125
fn crate_exists(conn: &mut Client, name: &str) -> Result<bool, Error> {
126-
Ok(!conn
127-
.query("SELECT * FROM crates WHERE name = $1;", &[&name])?
128-
.is_empty())
126+
Ok(conn
127+
.query_one("SELECT COUNT(*) > 0 FROM crates WHERE name = $1;", &[&name])?
128+
.get(0))
129129
}
130130

131131
fn release_exists(conn: &mut Client, id: i32) -> Result<bool, Error> {
132-
Ok(!conn
133-
.query("SELECT * FROM releases WHERE id = $1;", &[&id])?
134-
.is_empty())
132+
Ok(conn
133+
.query_one("SELECT COUNT(*) > 0 FROM releases WHERE id = $1;", &[&id])?
134+
.get(0))
135135
}
136136

137137
#[test]
@@ -160,7 +160,7 @@ mod tests {
160160

161161
let pkg1_id = &db
162162
.conn()
163-
.query("SELECT id FROM crates WHERE name = 'package-1';", &[])?[0]
163+
.query_one("SELECT id FROM crates WHERE name = 'package-1';", &[])?
164164
.get("id");
165165

166166
delete_crate_from_database(&mut db.conn(), "package-1", *pkg1_id)?;
@@ -209,10 +209,7 @@ mod tests {
209209
assert!(release_exists(&mut db.conn(), v2)?);
210210
let crate_id = db
211211
.conn()
212-
.query("SELECT crate_id FROM releases WHERE id = $1", &[&v1])?
213-
.into_iter()
214-
.next()
215-
.unwrap()
212+
.query_one("SELECT crate_id FROM releases WHERE id = $1", &[&v1])?
216213
.get(0);
217214
assert_eq!(
218215
authors(&mut db.conn(), crate_id)?,

src/docbuilder/limits.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,11 @@ impl Limits {
2828
pub(crate) fn for_crate(conn: &mut Client, name: &str) -> Result<Self> {
2929
let mut limits = Self::default();
3030

31-
let res = conn.query(
31+
let res = conn.query_opt(
3232
"SELECT * FROM sandbox_overrides WHERE crate_name = $1;",
3333
&[&name],
3434
)?;
35-
if !res.is_empty() {
36-
let row = &res[0];
35+
if let Some(row) = res {
3736
if let Some(memory) = row.get::<_, Option<i64>>("max_memory_bytes") {
3837
limits.memory = memory as usize;
3938
}
@@ -84,7 +83,7 @@ mod test {
8483
let hexponent = Limits::for_crate(&mut db.conn(), krate)?;
8584
assert_eq!(hexponent, Limits::default());
8685

87-
db.conn().query(
86+
db.conn().execute(
8887
"INSERT INTO sandbox_overrides (crate_name, max_targets) VALUES ($1, 15)",
8988
&[&krate],
9089
)?;
@@ -106,7 +105,7 @@ mod test {
106105
targets: 1,
107106
..Limits::default()
108107
};
109-
db.conn().query(
108+
db.conn().execute(
110109
"INSERT INTO sandbox_overrides (crate_name, max_memory_bytes, timeout_seconds, max_targets)
111110
VALUES ($1, $2, $3, $4)",
112111
&[&krate, &(limits.memory as i64), &(limits.timeout.as_secs() as i32), &(limits.targets as i32)]

src/docbuilder/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl DocBuilder {
6868
debug!("Loading database cache");
6969

7070
let mut conn = self.db.get()?;
71-
for row in &mut conn.query(
71+
for row in conn.query(
7272
"SELECT name, version FROM crates, releases \
7373
WHERE crates.id = releases.crate_id",
7474
&[],

src/docbuilder/rustwide_builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl RustwideBuilder {
260260
}
261261

262262
add_path_into_database(&self.storage, "", &dest)?;
263-
conn.query(
263+
conn.execute(
264264
"INSERT INTO config (name, value) VALUES ('rustc_version', $1) \
265265
ON CONFLICT (name) DO UPDATE SET value = $1;",
266266
&[&Value::String(self.rustc_version.clone())],

0 commit comments

Comments
 (0)