1use std::ops::{Deref, DerefMut};
2
3use sqlx::postgres::PgPoolOptions;
4use sqlx::{Pool, Postgres};
5
6use crate::config::DbConfig;
7
8pub struct Writer(Pool<Postgres>);
9
10impl Writer {
11 pub async fn new(db_config: DbConfig) -> Result<Self, sqlx::Error> {
12 let pool = PgPoolOptions::new()
13 .min_connections(db_config.min_pool_size)
14 .max_connections(db_config.max_pool_size)
15 .test_before_acquire(true)
16 .connect(&db_config.connection_url())
17 .await?;
18 Ok(Self(pool))
19 }
20
21 pub fn pool(&self) -> &Pool<Postgres> {
22 &self.0
23 }
24}
25
26impl Deref for Writer {
27 type Target = Pool<Postgres>;
28
29 fn deref(&self) -> &Self::Target {
30 &self.0
31 }
32}
33
34impl DerefMut for Writer {
35 fn deref_mut(&mut self) -> &mut Self::Target {
36 &mut self.0
37 }
38}
39
40#[cfg(test)]
41mod writer_tests {
42
43 use std::error::Error;
44
45 use crate::config::DbConfig;
46 use crate::writer::Writer;
47
48 #[tokio::test]
49 async fn should_execute_command_in_writer_instance() -> Result<(), Box<dyn Error>> {
50 dotenv::from_filename(".writer.env").ok();
51 let db_config = DbConfig::from_env();
52 let writer = Writer::new(db_config.clone()).await?;
53 let row: (i32,) = sqlx::query_as("SELECT 1").fetch_one(&*writer).await?;
54 assert_eq!(row.0, 1);
55 Ok(())
56 }
57
58 #[tokio::test]
59 async fn should_create_table() -> Result<(), Box<dyn Error>> {
60 dotenv::from_filename(".writer.env").ok();
61 let db_config = DbConfig::from_env();
62 let writer = Writer::new(db_config.clone()).await?;
63 let _ = sqlx::query("CREATE TEMP TABLE temp_test (id INT)")
64 .execute(writer.pool())
65 .await;
66
67 let _ = sqlx::query("insert into temp_test values (10)")
68 .execute(writer.pool())
69 .await;
70
71 let row: (i32,) = sqlx::query_as("SELECT id from temp_test")
72 .fetch_one(writer.pool())
73 .await?;
74
75 assert_eq!(row.0, 10);
76 Ok(())
77 }
78}