diff --git a/src/controllers/notifications_controller.rs b/src/controllers/notifications_controller.rs index b020825..d61d0f0 100644 --- a/src/controllers/notifications_controller.rs +++ b/src/controllers/notifications_controller.rs @@ -6,9 +6,28 @@ use crate::api_data::notification_api::NotificationAPI; use crate::api_data::res_count_all_unreads::ResCountAllUnread; use crate::api_data::res_number_unread_notifications::ResNumberUnreadNotifications; use crate::controllers::routes::RequestResult; +use crate::data::error::ResultBoxError; use crate::data::http_request_handler::HttpRequestHandler; +use crate::data::notification::PartialNotification; use crate::helpers::{conversations_helper, friends_helper, notifications_helper}; +impl HttpRequestHandler { + /// Get the id of a notification included in the request + pub fn post_notif_id(&mut self, name: &str) -> ResultBoxError { + let notif_id = self.post_u64(name)?; + + let notif = PartialNotification::new() + .set_id(notif_id) + .set_dest_user_id(self.user_id_ref()?); + + if !notifications_helper::similar_exists(¬if)? { + self.not_found("Specified notification not found!".to_string())?; + } + + Ok(notif_id) + } +} + /// Count the number of unread notifications pub fn count_unread(r: &mut HttpRequestHandler) -> RequestResult { let number = notifications_helper::count_unread(r.user_id_ref()?)?; @@ -32,4 +51,13 @@ pub fn get_list_unread(r: &mut HttpRequestHandler) -> RequestResult { let list = notifications_helper::get_list_unread(r.user_id_ref()?)?; r.set_response(NotificationAPI::for_list(&list)) +} + +/// Mark a notification as seen +pub fn mark_seen(r: &mut HttpRequestHandler) -> RequestResult { + let notif_id = r.post_notif_id("notifID")?; + let delete_similar = r.post_bool_opt("delete_similar", false); + + // TODO : continue implementation + r.success("continue implementation") } \ No newline at end of file diff --git a/src/controllers/routes.rs b/src/controllers/routes.rs index 3123acb..5586239 100644 --- a/src/controllers/routes.rs +++ b/src/controllers/routes.rs @@ -251,6 +251,8 @@ pub fn get_routes() -> Vec { Route::post("/notifications/get_list_unread", Box::new(notifications_controller::get_list_unread)), + Route::post("/notifications/mark_seen", Box::new(notifications_controller::mark_seen)), + // Movies controller Route::post("/movies/get_list", Box::new(movies_controller::get_list)), diff --git a/src/data/notification.rs b/src/data/notification.rs index 97c615f..1c8064a 100644 --- a/src/data/notification.rs +++ b/src/data/notification.rs @@ -151,4 +151,46 @@ pub struct Notification { pub visibility: NotifEventVisibility, pub container_id: Option, pub container_type: Option, +} + +pub struct PartialNotification { + pub id: Option, + pub time_create: Option, + pub seen: Option, + pub from_user_id: Option, + pub dest_user_id: Option, + pub on_elem_id: Option, + pub on_elem_type: Option, + pub kind: Option, + pub visibility: Option, + pub container_id: Option, + pub container_type: Option, +} + +impl PartialNotification { + pub fn new() -> PartialNotification { + PartialNotification { + id: None, + time_create: None, + seen: None, + from_user_id: None, + dest_user_id: None, + on_elem_id: None, + on_elem_type: None, + kind: None, + visibility: None, + container_id: None, + container_type: None, + } + } + + pub fn set_id(mut self, id: u64) -> PartialNotification { + self.id = Some(id); + self + } + + pub fn set_dest_user_id(mut self, id: &UserID) -> PartialNotification { + self.dest_user_id = Some(id.clone()); + self + } } \ No newline at end of file diff --git a/src/helpers/database.rs b/src/helpers/database.rs index 02e5eb5..3d1be84 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -75,7 +75,7 @@ pub struct QueryInfo { joins: Vec, /// Query limits - pub conditions: collections::HashMap, + pub conditions: collections::HashMap, /// Custom WHERE condition pub custom_where: Option, @@ -137,43 +137,50 @@ impl QueryInfo { self } + pub fn add_conditions(mut self, map: &HashMap) -> QueryInfo { + for (k,v) in map { + self.conditions.insert(k.to_string(), v.clone()); + } + self + } + pub fn cond(mut self, key: &str, val: &str) -> QueryInfo { - self.conditions.insert(key.to_string(), val.to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val)); self } pub fn cond_u32(mut self, key: &str, val: u32) -> QueryInfo { - self.conditions.insert(key.to_string(), val.to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val)); self } pub fn cond_u64(mut self, key: &str, val: u64) -> QueryInfo { - self.conditions.insert(key.to_string(), val.to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val)); self } pub fn cond_i64(mut self, key: &str, val: i64) -> QueryInfo { - self.conditions.insert(key.to_string(), val.to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val)); self } pub fn cond_user_id(mut self, key: &str, val: &UserID) -> QueryInfo { - self.conditions.insert(key.to_string(), val.id().to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val.id())); self } pub fn cond_group_id(mut self, key: &str, val: &GroupID) -> QueryInfo { - self.conditions.insert(key.to_string(), val.id().to_string()); + self.conditions.insert(key.to_string(), mysql::Value::from(val.id())); self } pub fn cond_legacy_bool(mut self, key: &str, val: bool) -> QueryInfo { let val = match val { - true => "1".to_string(), - false => "0".to_string() + true => 1, + false => 0 }; - self.conditions.insert(key.to_string(), val); + self.conditions.insert(key.to_string(), mysql::Value::from(val)); self } @@ -451,7 +458,7 @@ pub fn query ProcessRowResult>(info: QueryInfo, proce for (k, v) in &info.conditions { where_args.push(format!("{} = ?", k)); - params.push(mysql::Value::from(v)); + params.push(v.clone()); } let where_args = format!(" WHERE {} ", where_args.join(" AND ")); diff --git a/src/helpers/notifications_helper.rs b/src/helpers/notifications_helper.rs index 936a66b..8842b0d 100644 --- a/src/helpers/notifications_helper.rs +++ b/src/helpers/notifications_helper.rs @@ -2,12 +2,22 @@ //! //! @author Pierre Hubert +use std::collections::HashMap; + use crate::constants::database_tables_names::NOTIFICATIONS_TABLE; use crate::data::error::ResultBoxError; -use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification}; +use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification, PartialNotification}; use crate::data::user::UserID; use crate::helpers::database; +/// check out whether a similar notification exists for given specifications +pub fn similar_exists(n: &PartialNotification) -> ResultBoxError { + database::QueryInfo::new(NOTIFICATIONS_TABLE) + .add_conditions(¬if_to_db(n, false)) + .exec_count() + .map(|f| f > 0) +} + /// Count the number of unread notifications pub fn count_unread(user_id: &UserID) -> ResultBoxError { database::QueryInfo::new(NOTIFICATIONS_TABLE) @@ -42,4 +52,62 @@ fn db_to_notif(row: &database::RowResult) -> ResultBoxError { container_type: row.get_optional_str("from_container_type")? .map(|s| NotifElemType::from_db(&s)), }) +} + +/// Turn a notification into a database entry +fn notif_to_db(n: &PartialNotification, complete_information: bool) -> HashMap { + let mut map = HashMap::new(); + + if let Some(id) = n.id { + map.insert("id".to_string(), mysql::Value::UInt(id)); + } + + if let Some(seen) = n.seen { + map.insert("seen".to_string(), mysql::Value::Int(match seen { + true => 1, + false => 0, + })); + } + + if let Some(from_user_id) = &n.from_user_id { + map.insert("from_user_id".to_string(), mysql::Value::UInt(from_user_id.id())); + } + + if let Some(dest_user_id) = &n.dest_user_id { + map.insert("dest_user_id".to_string(), mysql::Value::UInt(dest_user_id.id())); + } + + if let Some(kind) = &n.kind { + map.insert("type".to_string(), mysql::Value::from(kind.to_db())); + } + + if let Some(on_elem_id) = n.on_elem_id { + map.insert("on_elem_id".to_string(), mysql::Value::from(on_elem_id)); + } + + if let Some(on_elem_type) = &n.on_elem_type { + map.insert("on_elem_type".to_string(), mysql::Value::from(on_elem_type.to_db())); + } + + + if complete_information { + if let Some(from_container_id) = n.container_id { + map.insert("from_container_id".to_string(), mysql::Value::from(from_container_id)); + } + + if let Some(from_container_type) = &n.container_type { + map.insert("from_container_type".to_string(), mysql::Value::from(from_container_type.to_db())); + } + + if let Some(time_create) = n.time_create { + map.insert("time_create".to_string(), mysql::Value::from(time_create)); + } + + if let Some(visibility) = &n.visibility { + map.insert("visibility".to_string(), mysql::Value::from(visibility.to_db())); + } + } + + + map } \ No newline at end of file