feat: migrate notifications add, mark_read and get to use db_* traits

This commit is contained in:
realaravinth
2022-05-26 20:03:05 +05:30
parent 44740535c2
commit aad49dbb94
8 changed files with 59 additions and 678 deletions

View File

@@ -173,22 +173,6 @@ async fn update(
data.dblib
.delete_traffic_pattern(&username, &msg.key)
.await?;
// sqlx::query!(
// "DELETE FROM mcaptcha_sitekey_user_provided_avg_traffic
// WHERE config_id = (
// SELECT config_id
// FROM
// mcaptcha_config
// WHERE
// key = ($1)
// AND
// user_id = (SELECT ID FROM mcaptcha_users WHERE name = $2)
// );",
// &msg.key,
// &username,
// )
// .execute(&data.db)
// .await?;
data.dblib
.add_traffic_pattern(&username, &msg.key, &pattern)

View File

@@ -22,8 +22,10 @@ use serde::{Deserialize, Serialize};
use crate::errors::*;
use crate::AppData;
#[derive(Serialize, Deserialize)]
pub struct AddNotification {
use db_core::AddNotification;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct AddNotificationRequest {
pub to: String,
pub heading: String,
pub message: String,
@@ -35,27 +37,22 @@ pub struct AddNotification {
wrap = "crate::api::v1::get_middleware()"
)]
pub async fn add_notification(
payload: web::Json<AddNotification>,
payload: web::Json<AddNotificationRequest>,
data: AppData,
id: Identity,
) -> ServiceResult<impl Responder> {
let sender = id.identity().unwrap();
// TODO handle error where payload.to doesnt exist
sqlx::query!(
"INSERT INTO mcaptcha_notifications (
heading, message, tx, rx)
VALUES (
$1, $2,
(SELECT ID FROM mcaptcha_users WHERE name = $3),
(SELECT ID FROM mcaptcha_users WHERE name = $4)
);",
&payload.heading,
&payload.message,
&sender,
&payload.to,
)
.execute(&data.db)
.await?;
let p = AddNotification {
from: &sender,
to: &payload.to,
message: &payload.message,
heading: &payload.heading,
};
data.dblib.create_notification(&p).await?;
Ok(HttpResponse::Ok())
}
@@ -88,7 +85,7 @@ pub mod tests {
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
let msg = AddNotification {
let msg = AddNotificationRequest {
to: NAME2.into(),
heading: "Test notification".into(),
message: "Testeing notifications with a dummy message".into(),

View File

@@ -18,20 +18,13 @@
use actix_identity::Identity;
use actix_web::{HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use sqlx::types::time::OffsetDateTime;
use crate::errors::*;
use crate::AppData;
pub struct Notification {
pub name: Option<String>,
pub heading: Option<String>,
pub message: Option<String>,
pub received: Option<OffsetDateTime>,
pub id: Option<i32>,
}
use db_core::Notification;
#[derive(Deserialize, Serialize)]
#[derive(Default, PartialEq, Clone, Deserialize, Serialize)]
pub struct NotificationResp {
pub name: String,
pub heading: String,
@@ -45,13 +38,26 @@ impl From<Notification> for NotificationResp {
NotificationResp {
name: n.name.unwrap(),
heading: n.heading.unwrap(),
received: n.received.unwrap().unix_timestamp(),
received: n.received.unwrap(),
id: n.id.unwrap(),
message: n.message.unwrap(),
}
}
}
impl NotificationResp {
pub fn from_notifications(mut n: Vec<Notification>) -> Vec<Self> {
let mut notifications = Vec::with_capacity(n.len());
n.drain(0..).for_each(|x| {
let y: NotificationResp = x.into();
notifications.push(y)
});
notifications
}
}
/// route handler that gets all unread notifications
#[my_codegen::get(
path = "crate::V1_API_ROUTES.notifications.get",
@@ -64,36 +70,9 @@ pub async fn get_notification(
let receiver = id.identity().unwrap();
// TODO handle error where payload.to doesnt exist
let mut notifications = runner::get_notification(&data, &receiver).await?;
let resp: Vec<NotificationResp> = notifications
.drain(0..)
.map(|x| {
let y: NotificationResp = x.into();
y
})
.collect();
Ok(HttpResponse::Ok().json(resp))
}
pub mod runner {
use super::*;
pub async fn get_notification(
data: &AppData,
receiver: &str,
) -> ServiceResult<Vec<Notification>> {
// TODO handle error where payload.to doesnt exist
let notifications = sqlx::query_file_as!(
Notification,
"src/api/v1/notifications/get_all_unread.sql",
&receiver
)
.fetch_all(&data.db)
.await?;
Ok(notifications)
}
let notifications = data.dblib.get_all_unread_notifications(&receiver).await?;
let notifications = NotificationResp::from_notifications(notifications);
Ok(HttpResponse::Ok().json(notifications))
}
#[cfg(test)]
@@ -102,7 +81,7 @@ pub mod tests {
use actix_web::test;
use super::*;
use crate::api::v1::notifications::add::AddNotification;
use crate::api::v1::notifications::add::AddNotificationRequest;
use crate::tests::*;
use crate::*;
@@ -130,7 +109,7 @@ pub mod tests {
let cookies2 = get_cookie!(signin_resp2);
let app = get_app!(data).await;
let msg = AddNotification {
let msg = AddNotificationRequest {
to: NAME2.into(),
heading: HEADING.into(),
message: MESSAGE.into(),

View File

@@ -1,24 +0,0 @@
-- gets all unread notifications a user has
SELECT
mcaptcha_notifications.id,
mcaptcha_notifications.heading,
mcaptcha_notifications.message,
mcaptcha_notifications.received,
mcaptcha_users.name
FROM
mcaptcha_notifications
INNER JOIN
mcaptcha_users
ON
mcaptcha_notifications.tx = mcaptcha_users.id
WHERE
mcaptcha_notifications.rx = (
SELECT
id
FROM
mcaptcha_users
WHERE
name = $1
)
AND
mcaptcha_notifications.read IS NULL;

View File

@@ -27,15 +27,6 @@ pub struct MarkReadReq {
pub id: i32,
}
#[derive(Deserialize, Serialize)]
pub struct NotificationResp {
pub name: String,
pub heading: String,
pub message: String,
pub received: i64,
pub id: i32,
}
/// route handler that marks a notification read
#[my_codegen::post(
path = "crate::V1_API_ROUTES.notifications.mark_read",
@@ -49,14 +40,10 @@ pub async fn mark_read(
let receiver = id.identity().unwrap();
// TODO handle error where payload.to doesnt exist
sqlx::query_file_as!(
Notification,
"src/api/v1/notifications/mark_read.sql",
payload.id,
&receiver
)
.execute(&data.db)
.await?;
// TODO get payload from path /api/v1/notifications/{id}/read"
data.dblib
.mark_notification_read(&receiver, payload.id)
.await?;
Ok(HttpResponse::Ok())
}
@@ -67,7 +54,8 @@ pub mod tests {
use actix_web::test;
use super::*;
use crate::api::v1::notifications::add::AddNotification;
use crate::api::v1::notifications::add::AddNotificationRequest;
use crate::api::v1::notifications::get::NotificationResp;
use crate::tests::*;
use crate::*;
@@ -94,7 +82,7 @@ pub mod tests {
let cookies2 = get_cookie!(signin_resp2);
let app = get_app!(data).await;
let msg = AddNotification {
let msg = AddNotificationRequest {
to: NAME2.into(),
heading: HEADING.into(),
message: MESSAGE.into(),

View File

@@ -1,14 +0,0 @@
-- mark a notification as read
UPDATE mcaptcha_notifications
SET read = TRUE
WHERE
mcaptcha_notifications.id = $1
AND
mcaptcha_notifications.rx = (
SELECT
id
FROM
mcaptcha_users
WHERE
name = $2
);

View File

@@ -20,9 +20,8 @@ use actix_web::{HttpResponse, Responder};
use sailfish::TemplateOnce;
use sqlx::types::time::OffsetDateTime;
use crate::api::v1::notifications::get::{self, runner};
use crate::date::Date;
use crate::errors::PageResult;
use crate::errors::{PageError, PageResult, ServiceError};
use crate::AppData;
#[derive(TemplateOnce)]
@@ -46,12 +45,12 @@ pub struct Notification {
pub id: i32,
}
impl From<get::Notification> for Notification {
fn from(n: get::Notification) -> Self {
impl From<db_core::Notification> for Notification {
fn from(n: db_core::Notification) -> Self {
Notification {
name: n.name.unwrap(),
heading: n.heading.unwrap(),
received: n.received.unwrap(),
received: OffsetDateTime::from_unix_timestamp(n.received.unwrap()),
id: n.id.unwrap(),
message: n.message.unwrap(),
}
@@ -74,7 +73,17 @@ pub async fn notifications(data: AppData, id: Identity) -> PageResult<impl Respo
let receiver = id.identity().unwrap();
// TODO handle error where payload.to doesnt exist
let mut notifications = runner::get_notification(&data, &receiver).await?;
// let mut notifications = runner::get_notification(&data, &receiver).await?;
let mut notifications = data
.dblib
.get_all_unread_notifications(&receiver)
.await
.map_err(|e| {
let se: ServiceError = e.into();
let pe: PageError = se.into();
pe
})?;
let notifications = notifications.drain(0..).map(|x| x.into()).collect();
let body = IndexPage::new(notifications).render_once().unwrap();