mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
feat: impl traits to add, get and mark read notifications for sqlx
postgres
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
-- Add migration script here
|
||||||
|
ALTER TABLE mcaptcha_notifications ALTER COLUMN heading TYPE varchar(100),
|
||||||
|
ALTER COLUMN heading SET NOT NULL;
|
||||||
24
db/db-sqlx-postgres/src/get_all_unread_notifications.sql
Normal file
24
db/db-sqlx-postgres/src/get_all_unread_notifications.sql
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
-- 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;
|
||||||
@@ -637,30 +637,98 @@ impl MCDatabase for Database {
|
|||||||
.map_err(|e| map_row_not_found_err(e, DBError::TrafficPatternNotFound))?;
|
.map_err(|e| map_row_not_found_err(e, DBError::TrafficPatternNotFound))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// create new notification
|
||||||
|
async fn create_notification(&self, p: &AddNotification) -> DBResult<()> {
|
||||||
|
let now = now_unix_time_stamp();
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO mcaptcha_notifications (
|
||||||
|
heading, message, tx, rx, received)
|
||||||
|
VALUES (
|
||||||
|
$1, $2,
|
||||||
|
(SELECT ID FROM mcaptcha_users WHERE name = $3),
|
||||||
|
(SELECT ID FROM mcaptcha_users WHERE name = $4),
|
||||||
|
$5
|
||||||
|
);",
|
||||||
|
p.heading,
|
||||||
|
p.message,
|
||||||
|
p.from,
|
||||||
|
p.to,
|
||||||
|
now
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(map_register_err)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get all unread notifications
|
||||||
|
async fn get_all_unread_notifications(
|
||||||
|
&self,
|
||||||
|
username: &str,
|
||||||
|
) -> DBResult<Vec<Notification>> {
|
||||||
|
let mut inner_notifications = sqlx::query_file_as!(
|
||||||
|
InnerNotification,
|
||||||
|
"./src/get_all_unread_notifications.sql",
|
||||||
|
&username
|
||||||
|
)
|
||||||
|
.fetch_all(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| map_row_not_found_err(e, DBError::AccountNotFound))?;
|
||||||
|
|
||||||
|
let mut notifications = Vec::with_capacity(inner_notifications.len());
|
||||||
|
|
||||||
|
inner_notifications
|
||||||
|
.drain(0..)
|
||||||
|
.for_each(|n| notifications.push(n.into()));
|
||||||
|
|
||||||
|
Ok(notifications)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// mark a notification read
|
||||||
|
async fn mark_notification_read(&self, username: &str, id: i32) -> DBResult<()> {
|
||||||
|
sqlx::query_file_as!(
|
||||||
|
Notification,
|
||||||
|
"./src/mark_notification_read.sql",
|
||||||
|
id,
|
||||||
|
&username
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| map_row_not_found_err(e, DBError::NotificationNotFound))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn now_unix_time_stamp() -> i64 {
|
fn now_unix_time_stamp() -> OffsetDateTime {
|
||||||
OffsetDateTime::now_utc().unix_timestamp()
|
OffsetDateTime::now_utc()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
#[derive(Debug, Clone, Default, PartialEq)]
|
||||||
//#[allow(non_snake_case)]
|
/// Represents notification
|
||||||
//struct InnerGistComment {
|
pub struct InnerNotification {
|
||||||
// ID: i64,
|
/// receiver name of the notification
|
||||||
// owner: String,
|
pub name: Option<String>,
|
||||||
// comment: Option<String>,
|
/// heading of the notification
|
||||||
// gist_public_id: String,
|
pub heading: Option<String>,
|
||||||
// created: i64,
|
/// message of the notification
|
||||||
//}
|
pub message: Option<String>,
|
||||||
//
|
/// when notification was received
|
||||||
//impl From<InnerGistComment> for GistComment {
|
pub received: Option<OffsetDateTime>,
|
||||||
// fn from(g: InnerGistComment) -> Self {
|
/// db assigned ID of the notification
|
||||||
// Self {
|
pub id: Option<i32>,
|
||||||
// id: g.ID,
|
}
|
||||||
// owner: g.owner,
|
|
||||||
// comment: g.comment.unwrap(),
|
impl From<InnerNotification> for Notification {
|
||||||
// gist_public_id: g.gist_public_id,
|
fn from(n: InnerNotification) -> Self {
|
||||||
// created: g.created,
|
Notification {
|
||||||
// }
|
name: n.name,
|
||||||
// }
|
heading: n.heading,
|
||||||
//}
|
message: n.message,
|
||||||
|
received: n.received.map(|t| t.unix_timestamp()),
|
||||||
|
id: n.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
14
db/db-sqlx-postgres/src/mark_notification_read.sql
Normal file
14
db/db-sqlx-postgres/src/mark_notification_read.sql
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- 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
|
||||||
|
);
|
||||||
@@ -33,6 +33,9 @@ async fn everyting_works() {
|
|||||||
const CAPTCHA_SECRET: &str = "postgrescaptchasecret";
|
const CAPTCHA_SECRET: &str = "postgrescaptchasecret";
|
||||||
const CAPTCHA_DESCRIPTION: &str = "postgrescaptchadescription";
|
const CAPTCHA_DESCRIPTION: &str = "postgrescaptchadescription";
|
||||||
const CAPTCHA_DURATION: i32 = 30;
|
const CAPTCHA_DURATION: i32 = 30;
|
||||||
|
// notification config
|
||||||
|
const HEADING: &str = "testing notifications get db postgres";
|
||||||
|
const MESSAGE: &str = "testing notifications get message db postgres";
|
||||||
|
|
||||||
// easy traffic pattern
|
// easy traffic pattern
|
||||||
const TRAFFIC_PATTERN: TrafficPattern = TrafficPattern {
|
const TRAFFIC_PATTERN: TrafficPattern = TrafficPattern {
|
||||||
@@ -56,6 +59,13 @@ async fn everyting_works() {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const add_notification: AddNotification = AddNotification {
|
||||||
|
from: NAME,
|
||||||
|
to: NAME,
|
||||||
|
message: MESSAGE,
|
||||||
|
heading: HEADING,
|
||||||
|
};
|
||||||
|
|
||||||
let url = env::var("POSTGRES_DATABASE_URL").unwrap();
|
let url = env::var("POSTGRES_DATABASE_URL").unwrap();
|
||||||
let pool_options = PgPoolOptions::new().max_connections(2);
|
let pool_options = PgPoolOptions::new().max_connections(2);
|
||||||
let connection_options = ConnectionOptions::Fresh(Fresh { pool_options, url });
|
let connection_options = ConnectionOptions::Fresh(Fresh { pool_options, url });
|
||||||
@@ -74,5 +84,5 @@ async fn everyting_works() {
|
|||||||
key: CAPTCHA_SECRET,
|
key: CAPTCHA_SECRET,
|
||||||
description: CAPTCHA_DESCRIPTION,
|
description: CAPTCHA_DESCRIPTION,
|
||||||
};
|
};
|
||||||
database_works(&db, &p, &c, &LEVELS, &TRAFFIC_PATTERN).await;
|
database_works(&db, &p, &c, &LEVELS, &TRAFFIC_PATTERN, &add_notification).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user