use std::sync::Arc; use super::{keys::Keys, users::Users}; use tokio::sync::Mutex; use tokio_postgres::{Client, NoTls}; const DBERR_UNIQUE: &str = "23505"; #[derive(Clone)] pub struct DB { client: Arc>, } impl DB { pub async fn new(host: String, user: String, database: String) -> Result { let (cl, conn) = tokio_postgres::connect( format!("host={host} user={user} dbname={database}").as_str(), NoTls, ) .await?; tokio::spawn(async move { if let Err(e) = conn.await { eprintln!("connection error: {}", e); } }); let client = Arc::new(Mutex::new(cl)); Ok(Self { client }) } pub fn users(&self) -> Users { Users::new(self.client.clone()) } pub fn keys(&self) -> Keys { Keys::new(self.client.clone()) } } #[derive(Debug)] pub enum DBError { Duplicate, NotFound, Other(tokio_postgres::Error), } impl From for DBError { fn from(err: tokio_postgres::Error) -> Self { if let Some(code) = err.code() && code.code() == DBERR_UNIQUE { return DBError::Duplicate; } DBError::Other(err) } }