Properly catch violations of unique constraint

This commit is contained in:
silverpill 2021-11-12 23:10:20 +00:00
parent ce551e9c8b
commit 3d537f5987
3 changed files with 20 additions and 37 deletions

View file

@ -1,6 +1,7 @@
use tokio_postgres::GenericClient; use tokio_postgres::GenericClient;
use uuid::Uuid; use uuid::Uuid;
use crate::database::catch_unique_violation;
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::models::cleanup::{ use crate::models::cleanup::{
find_orphaned_files, find_orphaned_files,
@ -21,7 +22,7 @@ pub async fn create_profile(
) -> Result<DbActorProfile, DatabaseError> { ) -> Result<DbActorProfile, DatabaseError> {
let profile_id = Uuid::new_v4(); let profile_id = Uuid::new_v4();
let extra_fields = ExtraFields(profile_data.extra_fields.clone()); let extra_fields = ExtraFields(profile_data.extra_fields.clone());
let result = db_client.query_one( let row = db_client.query_one(
" "
INSERT INTO actor_profile ( INSERT INTO actor_profile (
id, username, display_name, acct, bio, bio_source, id, username, display_name, acct, bio, bio_source,
@ -43,15 +44,8 @@ pub async fn create_profile(
&extra_fields, &extra_fields,
&profile_data.actor, &profile_data.actor,
], ],
).await; ).await.map_err(catch_unique_violation("profile"))?;
let profile = match result { let profile = row.try_get("actor_profile")?;
Ok(row) => row.try_get("actor_profile")?,
Err(err) => {
// TODO: catch profile already exists error
log::warn!("{}", err);
return Err(DatabaseError::AlreadyExists("profile"));
},
};
Ok(profile) Ok(profile)
} }

View file

@ -3,6 +3,7 @@ use std::convert::TryFrom;
use tokio_postgres::GenericClient; use tokio_postgres::GenericClient;
use uuid::Uuid; use uuid::Uuid;
use crate::database::catch_unique_violation;
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::models::notifications::queries::create_follow_notification; use crate::models::notifications::queries::create_follow_notification;
use crate::models::profiles::queries::{ use crate::models::profiles::queries::{
@ -87,17 +88,13 @@ pub async fn follow(
target_id: &Uuid, target_id: &Uuid,
) -> Result<Relationship, DatabaseError> { ) -> Result<Relationship, DatabaseError> {
let transaction = db_client.transaction().await?; let transaction = db_client.transaction().await?;
let result = transaction.execute( transaction.execute(
" "
INSERT INTO relationship (source_id, target_id) INSERT INTO relationship (source_id, target_id)
VALUES ($1, $2) VALUES ($1, $2)
", ",
&[&source_id, &target_id], &[&source_id, &target_id],
).await; ).await.map_err(catch_unique_violation("relationship"))?;
if let Err(err) = result {
log::info!("{}", err);
return Err(DatabaseError::AlreadyExists("relationship"));
};
let target_profile = update_follower_count(&transaction, target_id, 1).await?; let target_profile = update_follower_count(&transaction, target_id, 1).await?;
update_following_count(&transaction, source_id, 1).await?; update_following_count(&transaction, source_id, 1).await?;
if target_profile.is_local() { if target_profile.is_local() {

View file

@ -1,6 +1,7 @@
use tokio_postgres::GenericClient; use tokio_postgres::GenericClient;
use uuid::Uuid; use uuid::Uuid;
use crate::database::catch_unique_violation;
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::models::profiles::queries::create_profile; use crate::models::profiles::queries::create_profile;
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData}; use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
@ -150,7 +151,7 @@ pub async fn create_user(
}; };
let profile = create_profile(&transaction, &profile_data).await?; let profile = create_profile(&transaction, &profile_data).await?;
// Create user // Create user
let result = transaction.query_one( let row = transaction.query_one(
" "
INSERT INTO user_account ( INSERT INTO user_account (
id, wallet_address, password_hash, private_key, invite_code id, wallet_address, password_hash, private_key, invite_code
@ -165,26 +166,17 @@ pub async fn create_user(
&private_key_pem, &private_key_pem,
&user_data.invite_code, &user_data.invite_code,
], ],
).await; ).await.map_err(catch_unique_violation("user"))?;
match result { let db_user: DbUser = row.try_get("user_account")?;
Ok(row) => { let user = User {
transaction.commit().await?; id: db_user.id,
let db_user: DbUser = row.try_get("user_account")?; wallet_address: db_user.wallet_address,
let user = User { password_hash: db_user.password_hash,
id: db_user.id, private_key: db_user.private_key,
wallet_address: db_user.wallet_address, profile,
password_hash: db_user.password_hash, };
private_key: db_user.private_key, transaction.commit().await?;
profile, Ok(user)
};
Ok(user)
},
Err(err) => {
// TODO: catch user already exists error
log::info!("{}", err);
Err(DatabaseError::AlreadyExists("user"))?
},
}
} }
pub async fn get_user_by_wallet_address( pub async fn get_user_by_wallet_address(