From 201c412547eaf93300d25fa4f80393917edb2a29 Mon Sep 17 00:00:00 2001 From: Dibakar Sutra Dhar Date: Sun, 14 Apr 2024 15:36:50 +0600 Subject: [PATCH] postgres db connection --- .gitignore | 5 ++++- Cargo.toml | 1 + src/configuration.rs | 34 ++++++++++++++++++++++++++++++++++ src/main.rs | 7 +++++-- tests/health_check.rs | 18 +++++++++++++++++- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 567b1be..4dfab9a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,7 @@ Cargo.toml.orig # Ignore OS-specific files .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +.env +configuration.yaml \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 3764c10..3b53f45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ actix-web = "4" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } reqwest = "0.11" serde = {version = "1", features = ["derive"]} +config = "0.11" [dependencies.sqlx] version = "0.5.7" diff --git a/src/configuration.rs b/src/configuration.rs index e69de29..7999632 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -0,0 +1,34 @@ +#[derive(serde::Deserialize)] +pub struct Settings { + pub database: DatabaseSettings, + pub application_port: u16 +} + +#[derive(serde::Deserialize)] +pub struct DatabaseSettings { + pub username: String, + pub password: String, + pub port: u16, + pub host: String, + pub database_name: String +} + +pub fn get_configuration() -> Result { + // Initialise our configuration reader + let mut settings = config::Config::default(); + + // Add configuration values from a file name `configuration` + settings.merge(config::File::with_name("configuration"))?; + + // Try to convert the configuration values it read into out Settings type + settings.try_into() +} + +impl DatabaseSettings { + pub fn connection_string(&self) -> String { + format!( + "postgres://{}:{}@{}:{}/{}", + self.username, self.password, self.host, self.port, self.database_name + ) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8ee46b2..fefbab3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ use std::net::TcpListener; use newsletter::startup::run; +use newsletter::configuration::get_configuration; #[tokio::main] async fn main() -> std::io::Result<()> { - let listener = TcpListener::bind("127.0.0.1:0") - .expect("Failed to bind random port"); + // Panic if we can't read configuration + let configuration = get_configuration().expect("Failed to read configuration."); + let address = format!("127.0.0.1:{}", configuration.application_port); + let listener = TcpListener::bind(address)?; run(listener)?.await } \ No newline at end of file diff --git a/tests/health_check.rs b/tests/health_check.rs index 1c62f66..533d89a 100644 --- a/tests/health_check.rs +++ b/tests/health_check.rs @@ -1,5 +1,7 @@ use std::net::TcpListener; use newsletter::startup::run; +use sqlx::{PgConnection, Connection}; +use newsletter::configuration::get_configuration; fn spawn_app() -> String { let listener = TcpListener::bind("127.0.0.1:0") @@ -33,11 +35,16 @@ async fn health_check_works() { #[tokio::test] async fn subscribe_returns_200_for_valid_form_data() { let app_address = spawn_app(); + let configuration = get_configuration().expect("Failed to read configuration"); + let connection_string = configuration.database.connection_string(); + let mut connection = PgConnection::connect(&connection_string) + .await + .expect("Failed to connect to Postgres"); let client = reqwest::Client::new(); let body = "name=dibakar%20dhar&email=where_is_dibakar%40gmail.com"; let response = client - .post(&format!("{}/subscriptions", app_address)) + .post(&format!("{}/subscriptions", &app_address)) .header("Content-Type", "application/x-www-form-urlencoded") .body(body) .send() @@ -45,6 +52,15 @@ async fn subscribe_returns_200_for_valid_form_data() { .expect("Failed to execute request"); assert_eq!(200, response.status().as_u16()); + + let saved = sqlx::query!("SELECT email, name FROM subscriptions",) + .fetch_one(&mut connection) + .await + .expect("Failed to fetch saved subscription"); + + assert_eq!(saved.email, "where_is_dibakar@gmail.com"); + assert_eq!(saved.name, "dibakar dhar"); + } #[tokio::test]