use std::ops::DerefMut; use super::{role::Role, user::User}; use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; #[derive(FromRow, Debug, Serialize, Deserialize, Clone)] pub struct Activity { pub id: i64, pub created_at: NaiveDateTime, pub text: String, pub relevant_for: String, pub keep_until: Option, } pub struct ActivityBuilder { text: String, relevant_for: String, keep_until: Option, } impl ActivityBuilder { #[must_use] pub fn new(text: &str) -> Self { Self { text: text.into(), relevant_for: String::new(), keep_until: None, } } #[must_use] pub fn relevant_for_user(self, user: &User) -> Self { Self { relevant_for: format!("{}user-{};", self.relevant_for, user.id), ..self } } #[must_use] pub fn relevant_for_role(self, role: &Role) -> Self { Self { relevant_for: format!("{}role-{};", self.relevant_for, role.id), ..self } } pub async fn save(self, db: &SqlitePool) { Activity::create(db, &self.text, &self.relevant_for, self.keep_until).await; } pub async fn save_tx(self, db: &mut Transaction<'_, Sqlite>) { Activity::create_with_tx(db, &self.text, &self.relevant_for, self.keep_until).await; } } impl Activity { pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option { sqlx::query_as!( Self, "SELECT id, created_at, text, relevant_for, keep_until FROM activity WHERE id like ?", id ) .fetch_one(db) .await .ok() } pub(super) async fn create_with_tx( db: &mut Transaction<'_, Sqlite>, text: &str, relevant_for: &str, keep_until: Option, ) { sqlx::query!( "INSERT INTO activity(text, relevant_for, keep_until) VALUES (?, ?, ?)", text, relevant_for, keep_until ) .execute(db.deref_mut()) .await .unwrap(); } pub(super) async fn create( db: &SqlitePool, text: &str, relevant_for: &str, keep_until: Option, ) { let mut tx = db.begin().await.unwrap(); Self::create_with_tx(&mut tx, text, relevant_for, keep_until).await; tx.commit().await.unwrap(); } pub async fn for_user(db: &SqlitePool, user: &User) -> Vec { let user_str = format!("user-{};", user.id); sqlx::query_as!( Self, " SELECT id, created_at, text, relevant_for, keep_until FROM activity WHERE relevant_for like CONCAT('%', ?, '%') ORDER BY created_at DESC; ", user_str ) .fetch_all(db) .await .unwrap() } }