diff --git a/src/db.rs b/src/db.rs index 43bb7df59..28c9cd32f 100644 --- a/src/db.rs +++ b/src/db.rs @@ -11,6 +11,7 @@ pub mod issue_data; pub mod jobs; pub mod notifications; pub mod rustc_commits; +pub mod users; const CERT_URL: &str = "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem"; diff --git a/src/db/notifications.rs b/src/db/notifications.rs index 1e9f295ac..3077ef13a 100644 --- a/src/db/notifications.rs +++ b/src/db/notifications.rs @@ -15,17 +15,6 @@ pub struct Notification { pub team_name: Option, } -/// Add a new user (if not existing) -pub async fn record_username(db: &DbClient, user_id: u64, username: &str) -> anyhow::Result<()> { - db.execute( - "INSERT INTO users (user_id, username) VALUES ($1, $2) ON CONFLICT DO NOTHING", - &[&(user_id as i64), &username], - ) - .await - .context("inserting user id / username")?; - Ok(()) -} - pub async fn record_ping(db: &DbClient, notification: &Notification) -> anyhow::Result<()> { db.execute("INSERT INTO notifications (user_id, origin_url, origin_html, time, short_description, team_name, idx) VALUES ( diff --git a/src/db/users.rs b/src/db/users.rs new file mode 100644 index 000000000..ae8d6efe2 --- /dev/null +++ b/src/db/users.rs @@ -0,0 +1,60 @@ +use crate::github::User; +use anyhow::Context; +use tokio_postgres::Client as DbClient; + +/// Add a new user. +/// If an user already exists, updates their username. +pub async fn record_username(db: &DbClient, user_id: u64, username: &str) -> anyhow::Result<()> { + db.execute( + r" +INSERT INTO users (user_id, username) VALUES ($1, $2) +ON CONFLICT (user_id) +DO UPDATE SET username = $2", + &[&(user_id as i64), &username], + ) + .await + .context("inserting user id / username")?; + Ok(()) +} + +/// Return a user from the DB. +pub async fn get_user(db: &DbClient, user_id: u64) -> anyhow::Result> { + let row = db + .query_opt( + r" +SELECT username +FROM users +WHERE user_id = $1;", + &[&(user_id as i64)], + ) + .await + .context("cannot load user from DB")?; + Ok(row.map(|row| { + let username: &str = row.get(0); + User { + id: user_id, + login: username.to_string(), + } + })) +} + +#[cfg(test)] +mod tests { + use crate::db::users::{get_user, record_username}; + use crate::tests::run_test; + + #[tokio::test] + async fn update_username_on_conflict() { + run_test(|ctx| async { + let db = ctx.db_client().await; + + record_username(&db, 1, "Foo").await?; + record_username(&db, 1, "Bar").await?; + + assert_eq!(get_user(&db, 1).await?.unwrap().login, "Bar"); + + Ok(ctx) + }) + .await; + } +} diff --git a/src/handlers/notification.rs b/src/handlers/notification.rs index 87fe20539..e33eb9568 100644 --- a/src/handlers/notification.rs +++ b/src/handlers/notification.rs @@ -4,7 +4,7 @@ //! //! Parsing is done in the `parser::command::ping` module. -use crate::db::notifications; +use crate::db::{notifications, users}; use crate::github::get_id_for_username; use crate::{ github::{self, Event}, @@ -92,7 +92,7 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { continue; } - if let Err(err) = notifications::record_username(&client, user.id, &user.login) + if let Err(err) = users::record_username(&client, user.id, &user.login) .await .context("failed to record username") { diff --git a/src/handlers/pr_tracking.rs b/src/handlers/pr_tracking.rs index fb1c9bd0c..f793fb128 100644 --- a/src/handlers/pr_tracking.rs +++ b/src/handlers/pr_tracking.rs @@ -7,10 +7,10 @@ //! - Removes the PR from the workqueue of one team member (after the PR has been unassigned or closed) use super::assign::{FindReviewerError, REVIEWER_HAS_NO_CAPACITY, SELF_ASSIGN_HAS_NO_CAPACITY}; +use crate::db::users::record_username; use crate::github::User; use crate::{ config::ReviewPrefsConfig, - db::notifications::record_username, github::{IssuesAction, IssuesEvent}, handlers::Context, ReviewPrefs, diff --git a/src/handlers/pull_requests_assignment_update.rs b/src/handlers/pull_requests_assignment_update.rs index fe544afeb..c5e6acef9 100644 --- a/src/handlers/pull_requests_assignment_update.rs +++ b/src/handlers/pull_requests_assignment_update.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::db::notifications::record_username; +use crate::db::users::record_username; use crate::github::retrieve_pull_requests; use crate::jobs::Job; use crate::ReviewPrefs; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index adfb7c3fa..e24a21251 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,5 +1,5 @@ use crate::db; -use crate::db::notifications::record_username; +use crate::db::users::record_username; use crate::db::{make_client, ClientPool, PooledClient}; use crate::github::GithubClient; use crate::handlers::Context;