2020-05-26 16:25:33 +00:00
|
|
|
//! # Friends helper
|
|
|
|
//!
|
|
|
|
//! @author Pierre Hubert
|
|
|
|
|
|
|
|
|
2020-06-30 07:50:31 +00:00
|
|
|
|
2020-06-29 13:45:26 +00:00
|
|
|
use crate::constants::database_tables_names::{FRIENDS_TABLE, USERS_TABLE};
|
2020-06-30 06:14:58 +00:00
|
|
|
use crate::data::error::{ExecError, ResultBoxError};
|
2020-06-29 13:45:26 +00:00
|
|
|
use crate::data::friend::Friend;
|
2020-06-30 07:50:31 +00:00
|
|
|
use crate::data::friendship_status::FriendshipStatus;
|
2020-06-29 13:45:26 +00:00
|
|
|
use crate::data::user::UserID;
|
2020-05-26 16:25:33 +00:00
|
|
|
use crate::helpers::database;
|
|
|
|
use crate::helpers::database::QueryInfo;
|
|
|
|
|
2020-06-30 06:14:58 +00:00
|
|
|
/// Structure used to get a friend information
|
|
|
|
pub struct GetFriendsQuery {
|
2020-07-06 08:01:54 +00:00
|
|
|
only_accepted: bool,
|
|
|
|
only_following: bool,
|
2021-01-23 13:52:05 +00:00
|
|
|
only_followers: bool,
|
2020-06-30 06:14:58 +00:00
|
|
|
target_user: UserID,
|
|
|
|
friend_id: Option<UserID>,
|
2021-01-23 13:52:05 +00:00
|
|
|
common_with_user: Option<UserID>,
|
2020-06-30 06:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl GetFriendsQuery {
|
|
|
|
/// Construct a new request
|
|
|
|
pub fn new(target_user: &UserID) -> GetFriendsQuery {
|
|
|
|
GetFriendsQuery {
|
2020-07-06 08:01:54 +00:00
|
|
|
only_accepted: false,
|
|
|
|
only_following: false,
|
2021-01-23 13:52:05 +00:00
|
|
|
only_followers: false,
|
2020-06-30 06:14:58 +00:00
|
|
|
target_user: target_user.clone(),
|
|
|
|
friend_id: None,
|
2021-01-23 13:52:05 +00:00
|
|
|
common_with_user: None,
|
2020-06-30 06:14:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-06 08:01:54 +00:00
|
|
|
pub fn set_only_accepted(mut self, accepted: bool) -> GetFriendsQuery {
|
|
|
|
self.only_accepted = accepted;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-01-23 13:52:05 +00:00
|
|
|
/// Specify whether only the friends followed by friend_id should be selected
|
2020-07-06 08:01:54 +00:00
|
|
|
pub fn set_only_following(mut self, following: bool) -> GetFriendsQuery {
|
|
|
|
self.only_following = following;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-01-23 13:52:05 +00:00
|
|
|
/// Specify whether only the friends following friend_id should be selected
|
|
|
|
pub fn set_only_followers(mut self, following: bool) -> GetFriendsQuery {
|
|
|
|
self.only_followers = following;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Specify whether all the returned friends should be common with a specified user
|
|
|
|
pub fn set_only_common_with(mut self, user: &UserID) -> GetFriendsQuery {
|
|
|
|
self.common_with_user = Some(user.clone());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-06-30 06:14:58 +00:00
|
|
|
/// Get the list of friends
|
|
|
|
pub fn exec(self) -> ResultBoxError<Vec<Friend>> {
|
|
|
|
get_list(&self)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get information about a single friendship
|
|
|
|
pub fn get_single_friend(mut self, friend_id: &UserID) -> ResultBoxError<Friend> {
|
|
|
|
self.friend_id = Some(friend_id.clone());
|
|
|
|
get_list(&self)?
|
|
|
|
.pop()
|
|
|
|
.ok_or(ExecError::boxed_new("Single friend not found!"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 13:45:26 +00:00
|
|
|
/// Get the list of friends of a user
|
2020-06-30 06:14:58 +00:00
|
|
|
fn get_list(friend_query: &GetFriendsQuery) -> ResultBoxError<Vec<Friend>> {
|
|
|
|
let mut query = database::QueryInfo::new(FRIENDS_TABLE)
|
2020-06-29 13:45:26 +00:00
|
|
|
.alias("f")
|
2020-06-30 06:14:58 +00:00
|
|
|
.cond_user_id("ID_personne", &friend_query.target_user)
|
2020-06-29 13:45:26 +00:00
|
|
|
.join(USERS_TABLE, "u", "f.ID_amis = u.ID")
|
|
|
|
.add_field("u.last_activity")
|
|
|
|
.add_field("f.ID_amis")
|
|
|
|
.add_field("f.actif")
|
|
|
|
.add_field("f.abonnement")
|
|
|
|
.add_field("f.autoriser_post_page")
|
2020-06-30 06:14:58 +00:00
|
|
|
.set_order("u.last_activity DESC");
|
|
|
|
|
|
|
|
if let Some(friend_id) = friend_query.friend_id.as_ref() {
|
|
|
|
query = query.cond_user_id("ID_amis", friend_id);
|
|
|
|
}
|
|
|
|
|
2020-07-06 08:01:54 +00:00
|
|
|
if friend_query.only_accepted {
|
|
|
|
query = query.cond_legacy_bool("f.actif", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if friend_query.only_following {
|
|
|
|
query = query.cond_legacy_bool("f.abonnement", true);
|
|
|
|
}
|
|
|
|
|
2021-01-23 13:52:05 +00:00
|
|
|
let mut custom_where = String::new();
|
|
|
|
|
|
|
|
if friend_query.only_followers {
|
|
|
|
custom_where = " EXISTS (SELECT * FROM amis d WHERE d.ID_personne = f.ID_amis AND d.ID_amis = f.ID_personne AND abonnement = 1) ".to_string();
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(user_id) = &friend_query.common_with_user {
|
|
|
|
if !custom_where.is_empty() {
|
|
|
|
custom_where.push_str(" AND ");
|
|
|
|
}
|
|
|
|
|
|
|
|
custom_where.push_str(" (f.ID_amis = ? OR EXISTS (SELECT * FROM amis d WHERE d.ID_personne = ? AND d.ID_amis = f.ID_amis AND actif = 1) ) ");
|
|
|
|
query = query.add_custom_where_argument_user_id(user_id);
|
|
|
|
query = query.add_custom_where_argument_user_id(user_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if !custom_where.is_empty() {
|
|
|
|
query = query.set_custom_where(&custom_where);
|
|
|
|
}
|
|
|
|
|
2020-06-30 06:14:58 +00:00
|
|
|
query.exec(db_to_friend)
|
2020-06-29 13:45:26 +00:00
|
|
|
}
|
|
|
|
|
2020-07-09 11:26:39 +00:00
|
|
|
/// get the list of friends that allows a given user to create posts on their page
|
|
|
|
pub fn get_list_that_allow_posts_from_user(user_id: &UserID) -> ResultBoxError<Vec<UserID>> {
|
|
|
|
database::QueryInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_legacy_bool("autoriser_post_page", true)
|
2020-07-09 11:29:59 +00:00
|
|
|
.cond_legacy_bool("actif", true)
|
2020-07-09 11:26:39 +00:00
|
|
|
.cond_user_id("ID_amis", user_id)
|
|
|
|
.add_field("ID_personne as user_id")
|
|
|
|
.exec(|r| r.get_user_id("user_id"))
|
|
|
|
}
|
|
|
|
|
2020-06-30 08:06:53 +00:00
|
|
|
/// Send a new friendship request
|
|
|
|
pub fn send_request(user_id: &UserID, target_user: &UserID) -> ResultBoxError {
|
|
|
|
database::InsertQuery::new(FRIENDS_TABLE)
|
|
|
|
.add_user_id("ID_personne", target_user)
|
|
|
|
.add_user_id("ID_amis", user_id)
|
|
|
|
.add_legacy_bool("actif", false)
|
|
|
|
.insert_drop_result()
|
|
|
|
}
|
|
|
|
|
2020-06-30 08:24:18 +00:00
|
|
|
/// Remove a friendship request
|
|
|
|
pub fn remove_request(user_id: &UserID, target_user: &UserID) -> ResultBoxError {
|
|
|
|
database::DeleteQuery::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", target_user)
|
|
|
|
.cond_user_id("ID_amis", user_id)
|
|
|
|
.cond_legacy_bool("actif", false)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-30 08:06:53 +00:00
|
|
|
/// Check out whether a user has sent a request to another user
|
2020-06-30 07:50:31 +00:00
|
|
|
pub fn sent_request(user_id: &UserID, target_user: &UserID) -> ResultBoxError<bool> {
|
|
|
|
database::QueryInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", target_user)
|
|
|
|
.cond_user_id("ID_amis", user_id)
|
|
|
|
.cond_legacy_bool("actif", false)
|
|
|
|
.exec_count()
|
|
|
|
.map(|f| f > 0)
|
|
|
|
}
|
|
|
|
|
2020-06-30 12:05:36 +00:00
|
|
|
/// Respond to a friendship request
|
|
|
|
pub fn respond_request(user_id: &UserID, friend_id: &UserID, accept: bool) -> ResultBoxError {
|
|
|
|
// Delete the request
|
|
|
|
remove_request(friend_id, user_id)?;
|
|
|
|
|
|
|
|
if accept {
|
|
|
|
database::InsertQuery::new(FRIENDS_TABLE)
|
|
|
|
.add_user_id("ID_personne", user_id)
|
|
|
|
.add_user_id("ID_amis", friend_id)
|
|
|
|
.add_legacy_bool("actif", true)
|
|
|
|
.insert_drop_result()?;
|
|
|
|
|
|
|
|
database::InsertQuery::new(FRIENDS_TABLE)
|
|
|
|
.add_user_id("ID_personne", friend_id)
|
|
|
|
.add_user_id("ID_amis", user_id)
|
|
|
|
.add_legacy_bool("actif", true)
|
|
|
|
.insert_drop_result()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-05-26 16:25:33 +00:00
|
|
|
/// Check out whether two users are friend or not
|
2020-06-25 08:08:34 +00:00
|
|
|
pub fn are_friend(user_one: &UserID, user_two: &UserID) -> ResultBoxError<bool> {
|
2020-05-26 16:25:33 +00:00
|
|
|
Ok(database::count(QueryInfo::new(FRIENDS_TABLE)
|
2020-06-25 08:08:34 +00:00
|
|
|
.cond_user_id("ID_personne", user_one)
|
|
|
|
.cond_user_id("ID_amis", user_two)
|
2020-05-26 16:25:33 +00:00
|
|
|
.cond_i64("actif", 1))? > 0)
|
2020-06-01 08:00:58 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 12:27:31 +00:00
|
|
|
/// Delete a friendship
|
|
|
|
pub fn remove_friendship(user_one: &UserID, user_two: &UserID) -> ResultBoxError {
|
|
|
|
database::DeleteQuery::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_one)
|
|
|
|
.cond_user_id("ID_amis", user_two)
|
|
|
|
.exec()?;
|
|
|
|
|
|
|
|
database::DeleteQuery::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_two)
|
|
|
|
.cond_user_id("ID_amis", user_one)
|
|
|
|
.exec()?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-06-01 08:00:58 +00:00
|
|
|
/// Count the number of friends of a user
|
2020-06-25 08:08:34 +00:00
|
|
|
pub fn count_friends(user_id: &UserID) -> ResultBoxError<usize> {
|
2020-06-01 08:00:58 +00:00
|
|
|
QueryInfo::new(FRIENDS_TABLE)
|
2020-06-25 08:08:34 +00:00
|
|
|
.cond_user_id("ID_amis", user_id)
|
2020-06-01 08:00:58 +00:00
|
|
|
.cond_u32("actif", 1)
|
|
|
|
.exec_count()
|
2020-06-01 14:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if a user can create posts on another friend's page
|
2020-06-25 08:08:34 +00:00
|
|
|
pub fn can_post_texts(user_id: &UserID, target_user: &UserID) -> ResultBoxError<bool> {
|
2020-06-01 14:57:14 +00:00
|
|
|
QueryInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", target_user)
|
|
|
|
.cond_user_id("ID_amis", user_id)
|
|
|
|
.add_field("autoriser_post_page")
|
|
|
|
.query_row(|res| res.get_legacy_bool("autoriser_post_page"))
|
|
|
|
.or(Ok(false))
|
2020-06-29 13:45:26 +00:00
|
|
|
}
|
|
|
|
|
2020-06-30 07:50:31 +00:00
|
|
|
/// Check out whether a user is following another user or not
|
|
|
|
pub fn is_following(user_id: &UserID, friend_id: &UserID) -> ResultBoxError<bool> {
|
|
|
|
database::QueryInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_id)
|
|
|
|
.cond_user_id("ID_amis", friend_id)
|
|
|
|
.cond_legacy_bool("actif", true)
|
|
|
|
.cond_legacy_bool("abonnement", true)
|
|
|
|
.exec_count()
|
|
|
|
.map(|f| f > 0)
|
|
|
|
}
|
|
|
|
|
2020-06-30 12:48:39 +00:00
|
|
|
/// Update following status of a friendship
|
|
|
|
pub fn set_following(user_id: &UserID, friend_id: &UserID, follow: bool) -> ResultBoxError {
|
|
|
|
database::UpdateInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_id)
|
|
|
|
.cond_user_id("ID_amis", friend_id)
|
|
|
|
.set_legacy_bool("abonnement", follow)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-30 12:54:45 +00:00
|
|
|
/// Specify whether a friend is allowed to create posts on current user's page or not
|
|
|
|
pub fn set_can_post_texts(user_id: &UserID, friend_id: &UserID, allow: bool) -> ResultBoxError {
|
|
|
|
database::UpdateInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_id)
|
|
|
|
.cond_user_id("ID_amis", friend_id)
|
|
|
|
.set_legacy_bool("autoriser_post_page", allow)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-30 07:50:31 +00:00
|
|
|
/// Get the status of a friendship
|
|
|
|
pub fn get_status(user_id: &UserID, friend_id: &UserID) -> ResultBoxError<FriendshipStatus> {
|
|
|
|
let mut status = FriendshipStatus {
|
|
|
|
are_friend: false,
|
|
|
|
sent_request: false,
|
|
|
|
received_request: false,
|
|
|
|
following: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
status.are_friend = are_friend(user_id, friend_id)?;
|
|
|
|
|
|
|
|
match status.are_friend {
|
|
|
|
false => {
|
|
|
|
status.sent_request = sent_request(user_id, friend_id)?;
|
|
|
|
status.received_request = sent_request(friend_id, user_id)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
true => {
|
|
|
|
status.following = is_following(user_id, friend_id)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(status)
|
|
|
|
}
|
|
|
|
|
2020-07-10 11:31:40 +00:00
|
|
|
/// Count the number of friendship requests of a user
|
|
|
|
pub fn count_requests(user_id: &UserID) -> ResultBoxError<u64> {
|
|
|
|
database::QueryInfo::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_id)
|
|
|
|
.cond_legacy_bool("actif", false)
|
|
|
|
.exec_count()
|
|
|
|
.map(|r| r as u64)
|
|
|
|
}
|
|
|
|
|
2021-01-21 17:56:35 +00:00
|
|
|
/// Delete all the friends of a given user
|
|
|
|
pub fn delete_all_user(user_id: &UserID) -> ResultBoxError {
|
|
|
|
database::DeleteQuery::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_personne", user_id)
|
|
|
|
.exec()?;
|
|
|
|
|
|
|
|
database::DeleteQuery::new(FRIENDS_TABLE)
|
|
|
|
.cond_user_id("ID_amis", user_id)
|
|
|
|
.exec()
|
|
|
|
}
|
|
|
|
|
2020-06-29 13:45:26 +00:00
|
|
|
/// Turn a database entry into a Friend structure
|
|
|
|
fn db_to_friend(row: &database::RowResult) -> ResultBoxError<Friend> {
|
|
|
|
Ok(Friend {
|
|
|
|
friend_id: row.get_user_id("ID_amis")?,
|
|
|
|
accepted: row.get_legacy_bool("actif")?,
|
|
|
|
following: row.get_legacy_bool("abonnement")?,
|
|
|
|
last_activity_time: row.get_u64("last_activity")?,
|
|
|
|
can_post_texts: row.get_legacy_bool("autoriser_post_page")?,
|
|
|
|
})
|
2020-05-26 16:25:33 +00:00
|
|
|
}
|