1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-06-21 00:45:18 +00:00

Get the list of conversations of the user

This commit is contained in:
2020-06-04 19:01:35 +02:00
parent e92b3ef821
commit 620328b33b
8 changed files with 218 additions and 5 deletions

View File

@ -4,10 +4,12 @@
use crate::data::new_conversation::NewConversation;
use crate::data::error::{ResultBoxError, ExecError};
use crate::helpers::database::InsertQuery;
use crate::helpers::database::{InsertQuery};
use crate::constants::database_tables_names::{CONV_LIST_TABLE, CONV_USERS_TABLE};
use crate::utils::date_utils::time;
use crate::data::user::UserID;
use crate::data::conversation::Conversation;
use crate::helpers::database;
/// Create a new conversation. This method returns the ID of the created conversation
pub fn create(conv: &NewConversation) -> ResultBoxError<u64> {
@ -45,4 +47,51 @@ pub fn add_member(conv_id: u64, user_id: UserID, following: bool) -> ResultBoxEr
.insert()?;
Ok(())
}
/// Get the list of conversations of a specific user
pub fn get_list_user(user_id: UserID) -> ResultBoxError<Vec<Conversation>> {
database::QueryInfo::new(CONV_LIST_TABLE)
.alias("l")
// Join with conversation members table
.join(CONV_USERS_TABLE, "u", "l.id = u.conv_id")
// Specify selected fields
.add_field("*")
.add_field("l.id as id")
.add_field("l.user_id as owner_id")
// Filter query
.cond_user_id("u.user_id", user_id)
// Sort results
.set_order("l.last_active DESC")
// Execute query
.exec(db_to_conversation_info)
}
/// Get the list of members of a conversation
pub fn get_list_members(conv_id: u64) -> ResultBoxError<Vec<UserID>> {
database::QueryInfo::new(CONV_USERS_TABLE)
.cond_u64("conv_id", conv_id)
.add_field("user_id")
.exec(|res|res.get_user_id("user_id"))
}
/// Turn a database entry into a ConversationInfo object
fn db_to_conversation_info(row: &database::RowResult) -> ResultBoxError<Conversation> {
let conv_id = row.get_u64("id")?;
Ok(Conversation {
id: conv_id,
owner_id: row.get_user_id("owner_id")?,
name: row.get_optional_str("name")?,
members: get_list_members(conv_id)?,
can_everyone_add_members: row.get_legacy_bool("can_everyone_add_members")?,
last_active: row.get_u64("last_active")?,
time_create: row.get_u64("time_add")?,
following: row.get_legacy_bool("following")?,
saw_last_message: row.get_legacy_bool("saw_last_message")?,
})
}

View File

@ -50,10 +50,20 @@ pub fn get_connection() -> Result<mysql::PooledConn, Box<dyn Error>> {
Ok(pool.get_conn()?)
}
/// Structure used to implement JOIN on queries
struct QueryJoin {
table: String,
table_alias: String,
condition: String,
}
pub struct QueryInfo {
/// Fetched table
pub table: String,
pub table_alias: Option<String>,
/// Joins
joins: Vec<QueryJoin>,
/// Query limits
pub conditions: collections::HashMap<String, String>,
@ -61,6 +71,9 @@ pub struct QueryInfo {
/// Limit of the query (0 = no limit)
pub limit: u64,
/// Order of the query
pub order: Option<String>,
/// Queried arguments
///
/// If this attribute is empty, all the columns of the table set are fetched
@ -72,12 +85,30 @@ impl QueryInfo {
pub fn new(table: &str) -> QueryInfo {
QueryInfo {
table: table.to_string(),
table_alias: None,
joins: Vec::new(),
conditions: collections::HashMap::new(),
limit: 0,
order: None,
fields: Vec::new(),
}
}
/// Main fetched table alias
pub fn alias(mut self, table_alias: &str) -> QueryInfo {
self.table_alias = Some(table_alias.to_string());
self
}
pub fn join(mut self, table: &str, table_alias: &str, cond: &str) -> QueryInfo {
self.joins.push(QueryJoin {
table: table.to_string(),
table_alias: table_alias.to_string(),
condition: cond.to_string(),
});
self
}
pub fn cond(mut self, key: &str, val: &str) -> QueryInfo {
self.conditions.insert(key.to_string(), val.to_string());
self
@ -109,6 +140,12 @@ impl QueryInfo {
self
}
/// Set results ordering
pub fn set_order(mut self, order: &str) -> QueryInfo {
self.order = Some(order.to_string());
self
}
/// Execute query
pub fn exec<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(self, process_function: F)
-> Result<Vec<E>, Box<dyn Error>> {
@ -187,6 +224,11 @@ impl<'a> RowResult<'a> {
}
}
/// Get the ID of a user included in the request
pub fn get_user_id(&self, name: &str) -> ResultBoxError<UserID> {
self.get_int64(name)
}
/// Find a string included in the request
pub fn get_str(&self, name: &str) -> Result<String, Box<dyn Error>> {
let value = self.row.get_opt(self.find_col(name)?);
@ -273,6 +315,17 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
// Build query
let mut query = format!("SELECT {} FROM {} ", select_elements, info.table);
// Table alias (if any)
if let Some(alias) = info.table_alias {
query = query.add(format!(" {} ", alias).as_str());
}
// Join conditions
for j in info.joins {
query = query.add(
format!(" JOIN {} {} ON {} ", j.table, j.table_alias, j.condition).as_ref());
}
// WHERE clause
if !info.conditions.is_empty() {
@ -287,6 +340,11 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
query = query.add(&where_args);
}
// ORDER clause
if let Some(order) = info.order {
query = query.add(format!(" ORDER BY {} ", order).as_str());
}
// LIMIT clause
if info.limit > 0 {
query = query.add(&format!(" LIMIT {}", info.limit));
@ -294,7 +352,10 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
// Execute query
let mut con = get_connection()?;
let stmt = con.prep(&query)?;
let stmt = con.prep(&query).or_else(|err| {
println!("Error in SQL query: {}", &query);
Err(err)
})?;
let mut res = con.exec_iter(stmt, params)?;