diff --git a/Cargo.lock b/Cargo.lock index c33124e..b38ecb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -547,6 +547,7 @@ dependencies = [ "futures", "image", "kamadak-exif", + "lazy_static", "mailchecker", "mysql", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index ab2ee6a..f2d0f9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,5 @@ rand = "0.7.3" chrono = "0.4.11" bytes = "0.5.4" image = "0.23.5" -kamadak-exif = "0.5.1" \ No newline at end of file +kamadak-exif = "0.5.1" +lazy_static = "1.4.0" \ No newline at end of file diff --git a/src/api_data/global_search_result_api.rs b/src/api_data/global_search_result_api.rs new file mode 100644 index 0000000..a92824b --- /dev/null +++ b/src/api_data/global_search_result_api.rs @@ -0,0 +1,36 @@ +//! # Global search result API +//! +//! @author Pierre + +use serde::Serialize; + +use crate::data::global_search_result::GlobalSearchResult; + +#[derive(Serialize)] +pub struct GlobalSearchResultAPI { + kind: String, + id: u64, +} + +impl GlobalSearchResultAPI { + /// Construct new entry + pub fn new(res: &GlobalSearchResult) -> GlobalSearchResultAPI { + match res { + GlobalSearchResult::User(user_id) => GlobalSearchResultAPI { + kind: "user".to_string(), + id: user_id.clone() as u64, + }, + GlobalSearchResult::Group(group_id) => GlobalSearchResultAPI { + kind: "group".to_string(), + id: group_id.id(), + }, + } + } + + /// Construct a list of results + pub fn for_list(l: &Vec) -> Vec { + l.iter() + .map(|f| Self::new(f)) + .collect() + } +} \ No newline at end of file diff --git a/src/api_data/mod.rs b/src/api_data/mod.rs index 60d2bbe..75d1494 100644 --- a/src/api_data/mod.rs +++ b/src/api_data/mod.rs @@ -21,4 +21,5 @@ pub mod res_find_private_conversations; pub mod conversation_message_api; pub mod conversations_refresh_api; pub mod res_count_unread_conversations; -pub mod list_unread_conversations_api; \ No newline at end of file +pub mod list_unread_conversations_api; +pub mod global_search_result_api; \ No newline at end of file diff --git a/src/controllers/search_controller.rs b/src/controllers/search_controller.rs index 219494f..a3648e9 100644 --- a/src/controllers/search_controller.rs +++ b/src/controllers/search_controller.rs @@ -2,9 +2,11 @@ //! //! @author Pierre Hubert +use crate::api_data::global_search_result_api::GlobalSearchResultAPI; use crate::controllers::routes::RequestResult; +use crate::data::global_search_result::GlobalSearchResult; use crate::data::http_request_handler::HttpRequestHandler; -use crate::helpers::user_helper; +use crate::helpers::{groups_helper, user_helper}; /// Search for user pub fn search_user(r: &mut HttpRequestHandler) -> RequestResult { @@ -18,5 +20,19 @@ pub fn search_user(r: &mut HttpRequestHandler) -> RequestResult { /// Perform a global search pub fn search_global(r: &mut HttpRequestHandler) -> RequestResult { - r.success("implement me") + let query = r.post_string("query")?; + let limit = 10; + + let mut list = user_helper::search_user(&query, limit)? + .iter() + .map(|f| GlobalSearchResult::User(f.clone())) + .collect::>(); + + list.append(&mut groups_helper::search_group(&query, limit)? + .iter() + .map(|f| GlobalSearchResult::Group(f.clone())) + .collect::>()); + + + r.set_response(GlobalSearchResultAPI::for_list(&list)) } \ No newline at end of file diff --git a/src/data/global_search_result.rs b/src/data/global_search_result.rs new file mode 100644 index 0000000..8e02df1 --- /dev/null +++ b/src/data/global_search_result.rs @@ -0,0 +1,9 @@ +//! # Global search result + +use crate::data::group_id::GroupID; +use crate::data::user::UserID; + +pub enum GlobalSearchResult { + User(UserID), + Group(GroupID), +} \ No newline at end of file diff --git a/src/data/group.rs b/src/data/group.rs new file mode 100644 index 0000000..4091e73 --- /dev/null +++ b/src/data/group.rs @@ -0,0 +1,11 @@ +//! # Group information +//! +//! Group visibility level + +#[allow(non_camel_case_types)] +#[derive(Eq, PartialEq, Hash)] +pub enum GroupVisibilityLevel { + OPEN_GROUP, + PRIVATE_GROUP, + SECRETE_GROUP, +} \ No newline at end of file diff --git a/src/data/group_id.rs b/src/data/group_id.rs new file mode 100644 index 0000000..1197296 --- /dev/null +++ b/src/data/group_id.rs @@ -0,0 +1,18 @@ +//! # Group ID +//! +//! @author Pierre Hubert + +#[derive(Clone, PartialEq, Eq)] +pub struct GroupID(u64); + +impl GroupID { + /// Initialize a new group ID object + pub fn new(id: u64) -> GroupID { + GroupID(id) + } + + /// Get the ID current stored in this structure + pub fn id(&self) -> u64 { + self.0 + } +} \ No newline at end of file diff --git a/src/data/mod.rs b/src/data/mod.rs index ed3a21c..fd84e8e 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -11,4 +11,7 @@ pub mod new_conversation; pub mod conversation; pub mod conversation_message; pub mod new_conversation_message; -pub mod unread_conversation; \ No newline at end of file +pub mod unread_conversation; +pub mod group_id; +pub mod group; +pub mod global_search_result; \ No newline at end of file diff --git a/src/helpers/database.rs b/src/helpers/database.rs index ee3269b..933c1da 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -11,6 +11,7 @@ use mysql::prelude::Queryable; use crate::data::config::DatabaseConfig; use crate::data::error::{ExecError, ResultBoxError}; use crate::data::user::UserID; +use crate::data::group_id::GroupID; /// Database access helper /// @@ -271,6 +272,11 @@ impl<'a> RowResult<'a> { self.get_int64(name) } + /// Get the ID of a group included in the response + pub fn get_group_id(&self, name: &str) -> ResultBoxError { + Ok(GroupID::new(self.get_u64(name)?)) + } + /// Find a string included in the request pub fn get_str(&self, name: &str) -> Result> { let value = self.row.get_opt(self.find_col(name)?); diff --git a/src/helpers/groups_helper.rs b/src/helpers/groups_helper.rs index c07f5a5..18eda0c 100644 --- a/src/helpers/groups_helper.rs +++ b/src/helpers/groups_helper.rs @@ -2,9 +2,21 @@ //! //! @author Pierre Hubert -use crate::data::error::ResultBoxError; -use crate::helpers::database; use crate::constants::database_tables_names::GROUPS_LIST_TABLE; +use crate::data::error::ResultBoxError; +use crate::data::group::GroupVisibilityLevel; +use crate::data::group_id::GroupID; +use crate::helpers::database; + +impl GroupVisibilityLevel { + pub fn to_db(&self) -> u64 { + match self { + GroupVisibilityLevel::OPEN_GROUP => 0, + GroupVisibilityLevel::PRIVATE_GROUP => 1, + GroupVisibilityLevel::SECRETE_GROUP => 2, + } + } +} /// Find a group id by virtual directory pub fn find_by_virtual_directory(dir: &str) -> ResultBoxError { @@ -12,4 +24,15 @@ pub fn find_by_virtual_directory(dir: &str) -> ResultBoxError { .cond("virtual_directory", dir) .add_field("id") .query_row(|res| res.get_u64("id")) +} + +/// Search for group +pub fn search_group(query: &str, limit: u64) -> ResultBoxError> { + database::QueryInfo::new(GROUPS_LIST_TABLE) + .set_custom_where("name LIKE ? AND visibility != ?") + .add_custom_where_argument_str(format!("%{}%", query).as_str()) + .add_custom_where_argument_u64(GroupVisibilityLevel::SECRETE_GROUP.to_db()) + .set_limit(limit) + .add_field("id") + .exec(|row| row.get_group_id("id")) } \ No newline at end of file