use std::fmt::Debug; use sqlx::prelude::*; use tracing::error; use crate::models::AppError; use super::DbPool; #[derive(Clone)] pub struct NewUserEntity { pub email: String, pub password: String, pub name: String, } impl Debug for NewUserEntity { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("NewUserEntity") .field("email", &self.email) .field("password", &"********") .field("name", &self.name) .finish() } } #[allow(dead_code)] #[derive(Debug, FromRow)] pub struct UserEntity { pub id: i32, pub name: String, pub email: String, pub status_id: i32, } pub async fn insert_new_user( pool: &DbPool, new_user: NewUserEntity, ) -> Result { let NewUserEntity { email, password, name, } = new_user.clone(); sqlx::query_as::<_, UserEntity>("INSERT INTO public.user (email, password, name) VALUES ($1, $2, $3) RETURNING id, email, name, status_id;") .bind(email) .bind(password) .bind(name) .fetch_one(pool).await .map_err(|err| { error!(?err, record = ?new_user, "Cannot insert new user record"); AppError::from(err) }) } #[derive(Debug, FromRow)] pub struct UserIdAndHashedPasswordEntity { pub id: i32, pub password: String, } pub async fn get_username_and_password_by_email( pool: &DbPool, email: String, ) -> Result { sqlx::query_as::<_, UserIdAndHashedPasswordEntity>( "SELECT id, password FROM public.user WHERE email = $1;", ) .bind(email) .fetch_one(pool) .await .map_err(|err| { error!(?err, "Unable to find user"); AppError::from(err) }) } pub async fn verify_user(pool: &DbPool, user_id: i32) -> Result<(), AppError> { sqlx::query("UPDATE public.user SET status_id = 1, updated_at = now() WHERE id = $1;") .bind(user_id) .execute(pool) .await .map_err(|err| { error!(?err, user_id, "Error verifying user"); AppError::from(err) }) .map(|_| ()) }