pgdb_lib_rs/
lib.rs

1extern crate core;
2
3use std::fmt::{Debug, Display, Formatter};
4use sqlx::{PgPool, Pool, Postgres};
5use thiserror::Error;
6
7
8#[derive(Error, Debug)]
9pub enum DatabaseConnectionError {
10    #[error("Invalid Connection String ")]
11    InvalidConnectionString(dotenvy::Error),
12    #[error("Unable to connect to the database. ")]
13    ConnectionError(#[from] sqlx::Error),
14}
15
16
17#[derive(Clone)]
18pub struct Database {
19    underlying: Pool<Postgres>,
20}
21
22impl Database {
23    pub async fn new() -> Result<Self, DatabaseConnectionError> {
24        let database_url = dotenvy::var("DATABASE_URL").map_err(DatabaseConnectionError::InvalidConnectionString)?;
25        let pool = PgPool::connect(&database_url).await.map_err(DatabaseConnectionError::ConnectionError)?;
26        Ok(Database {
27            underlying: pool
28        })
29    }
30    // Pool internally uses a Clone, so this is not an expensive operation.
31    pub fn get_pool(&self) -> &Pool<Postgres>{
32        &self.underlying
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    #[test]
40    fn test_database_connection_get() {
41        tokio_test::block_on(async {
42            let db = Database::new().await.expect("Database connection expected");
43            let row: (i64,) = sqlx::query_as("SELECT $1")
44                .bind(150_i64)
45                .fetch_one(db.get_pool()).await.expect("error occured ");
46
47            assert_eq!(row.0, 150);
48        });
49    }
50}