diff --git a/src/controllers/conversations_controller.rs b/src/controllers/conversations_controller.rs index c5a6185..81bfe79 100644 --- a/src/controllers/conversations_controller.rs +++ b/src/controllers/conversations_controller.rs @@ -66,7 +66,14 @@ pub fn update_settings(r: &mut HttpRequestHandler) -> RequestResult { let conv_id = r.post_conv_id("conversationID")?; let is_moderator = conversations_helper::is_user_moderator(r.user_id()?, conv_id)?; - println!("conv id: {} / is moderator: {}", conv_id, is_moderator); + // Update following state, if required + if r.has_post_parameter("following") { + conversations_helper::set_following( + r.user_id()?, + conv_id, + r.post_bool("following")? + )?; + } - r.success("implement it") + r.success("Conversation information successfully updated!") } \ No newline at end of file diff --git a/src/helpers/conversations_helper.rs b/src/helpers/conversations_helper.rs index 95ab8d9..a62efeb 100644 --- a/src/helpers/conversations_helper.rs +++ b/src/helpers/conversations_helper.rs @@ -115,6 +115,15 @@ pub fn is_user_moderator(user_id: UserID, conv_id: u64) -> ResultBoxError .exec_count()? > 0) } +/// Set whether a user is following a conversation or not +pub fn set_following(user_id: UserID, conv_id: u64, following: bool) -> ResultBoxError<()> { + database::UpdateInfo::new(CONV_USERS_TABLE) + .cond_u64("conv_id", conv_id) + .cond_user_id("user_id", user_id) + .set_legacy_bool("following", following) + .exec() +} + /// Turn a database entry into a ConversationInfo object fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError { let conv_id = row.get_u64("id")?; diff --git a/src/helpers/database.rs b/src/helpers/database.rs index fefd8da..3faa786 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -528,5 +528,90 @@ pub fn delete(query: DeleteQuery) -> ResultBoxError<()> { query.conditions.values().collect::>(), )?; + Ok(()) +} + +pub struct UpdateInfo { + table: String, + cond: HashMap, + set: HashMap, +} + +impl UpdateInfo { + /// Prepare a new update query + pub fn new(table: &str) -> UpdateInfo { + UpdateInfo { + table: table.to_string(), + cond: HashMap::new(), + set: HashMap::new(), + } + } + + /// Filter with a user id + pub fn cond_user_id(mut self, name: &str, val: UserID) -> UpdateInfo { + self.cond.insert(name.to_string(), Value::Int(val)); + self + } + + /// Filter with an unsigned integer + pub fn cond_u64(mut self, name: &str, val: u64) -> UpdateInfo { + self.cond.insert(name.to_string(), Value::UInt(val)); + self + } + + /// Set a new legacy boolean + pub fn set_legacy_bool(mut self, name: &str, val: bool) -> UpdateInfo { + let num = match val { + false => 0, + true => 1, + }; + + self.set.insert(name.to_string(), Value::Int(num)); + self + } + + /// Execute the update + pub fn exec(self) -> ResultBoxError<()> { + update(self) + } +} + +/// Execute an update query +pub fn update(u: UpdateInfo) -> ResultBoxError<()> { + if u.cond.is_empty() { + Err(ExecError::boxed_new("Update without conditions blocked for security!"))?; + } + + if u.set.is_empty() { + Err(ExecError::boxed_new("Update with no change specified useless!"))?; + } + + + let mut query_sql = format!("UPDATE {} SET ", u.table); + let mut values = vec![]; + + // Prepare updates + let updates = u.set.keys() + .into_iter() + .map(|f| format!("{} = ?", f)) + .collect::>() + .join(", "); + u.set.values().into_iter().for_each(|f| values.push(f)); + + // Prepare conditions + let conditions = u.cond.keys() + .into_iter() + .map(|f| format!("{} = ?", f)) + .collect::>() + .join(" AND "); + u.cond.values().into_iter().for_each(|f| values.push(f)); + + query_sql = format!("{} {} WHERE {}", query_sql, updates, conditions); + + get_connection()?.exec_drop( + query_sql, + values, + )?; + Ok(()) } \ No newline at end of file