mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2024-12-18 05:56:35 +00:00
Using two types to fetch.
This commit is contained in:
parent
e9d4b14dcf
commit
d7999e7241
1 changed files with 31 additions and 7 deletions
|
@ -1,7 +1,10 @@
|
||||||
use actix_web::{web, HttpResponse, ResponseError};
|
use crate::domain::SubscriberEmail;
|
||||||
use sqlx::PgPool;
|
use crate::email_client::EmailClient;
|
||||||
use crate::routes::error_chain_fmt;
|
use crate::routes::error_chain_fmt;
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
|
use actix_web::{web, HttpResponse, ResponseError};
|
||||||
|
use anyhow::Context;
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct BodyData {
|
pub struct BodyData {
|
||||||
|
@ -38,29 +41,50 @@ impl ResponseError for PublishError {
|
||||||
pub async fn publish_newsletter(
|
pub async fn publish_newsletter(
|
||||||
body: web::Json<BodyData>,
|
body: web::Json<BodyData>,
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
|
email_client: web::Data<EmailClient>,
|
||||||
) -> Result<HttpResponse, PublishError> {
|
) -> Result<HttpResponse, PublishError> {
|
||||||
let subscribers = get_confirmed_subscribers(&pool).await?;
|
let subscribers = get_confirmed_subscribers(&pool).await?;
|
||||||
|
for subscriber in subscribers {
|
||||||
|
email_client
|
||||||
|
.send_email(
|
||||||
|
subscriber.email,
|
||||||
|
&body.title,
|
||||||
|
&body.content.html,
|
||||||
|
&body.content.text,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("Failed to send newsletter issue to {}", subscriber.email))?;
|
||||||
|
}
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConfirmedSubscriber {
|
struct ConfirmedSubscriber {
|
||||||
name: String,
|
email: SubscriberEmail,
|
||||||
email: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(name = "Adding a new subscriber", skip(pool))]
|
#[tracing::instrument(name = "Adding a new subscriber", skip(pool))]
|
||||||
async fn get_confirmed_subscribers(
|
async fn get_confirmed_subscribers(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
) -> Result<Vec<ConfirmedSubscriber>, anyhow::Error> {
|
) -> Result<Vec<ConfirmedSubscriber>, anyhow::Error> {
|
||||||
|
struct Row {
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
let rows = sqlx::query_as!(
|
let rows = sqlx::query_as!(
|
||||||
ConfirmedSubscriber,
|
Row,
|
||||||
r#"
|
r#"
|
||||||
SELECT email, name
|
SELECT email
|
||||||
FROM subscriptions
|
FROM subscriptions
|
||||||
WHERE status = 'confirmed'
|
WHERE status = 'confirmed'
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(rows)
|
let confirmed_subscribers = rows
|
||||||
|
.into_iter()
|
||||||
|
.map(|r| ConfirmedSubscriber {
|
||||||
|
email: SubscriberEmail::parse(r.email).unwrap(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(confirmed_subscribers)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue