1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-11-02 00:24:04 +00:00

Add survey posts support

This commit is contained in:
2020-07-04 16:44:42 +02:00
parent 1e956cdcb5
commit 8d5013b00a
12 changed files with 237 additions and 13 deletions

View File

@@ -51,6 +51,13 @@ pub fn get_connection() -> Result<mysql::PooledConn, Box<dyn Error>> {
Ok(pool.get_conn()?)
}
/// Join type
#[derive(PartialEq)]
pub enum DatabaseQueryJoinType {
NORMAL,
LEFT,
}
/// Structure used to implement JOIN on queries
struct QueryJoin {
table: String,
@@ -64,6 +71,7 @@ pub struct QueryInfo {
pub table_alias: Option<String>,
/// Joins
joins_type: DatabaseQueryJoinType,
joins: Vec<QueryJoin>,
/// Query limits
@@ -75,6 +83,9 @@ pub struct QueryInfo {
/// Custom WHERE values
pub custom_where_ars: Vec<mysql::Value>,
/// Custom GROUP BY argument
group_by: Option<String>,
/// Limit of the query (0 = no limit)
pub limit: u64,
@@ -93,10 +104,12 @@ impl QueryInfo {
QueryInfo {
table: table.to_string(),
table_alias: None,
joins_type: DatabaseQueryJoinType::NORMAL,
joins: Vec::new(),
conditions: collections::HashMap::new(),
custom_where: None,
custom_where_ars: vec![],
group_by: None,
limit: 0,
order: None,
fields: Vec::new(),
@@ -109,6 +122,12 @@ impl QueryInfo {
self
}
/// Set join type
pub fn set_join_type(mut self, t: DatabaseQueryJoinType) -> QueryInfo {
self.joins_type = t;
self
}
pub fn join(mut self, table: &str, table_alias: &str, cond: &str) -> QueryInfo {
self.joins.push(QueryJoin {
table: table.to_string(),
@@ -194,9 +213,9 @@ impl QueryInfo {
self
}
/// Set the limit for the request
pub fn set_limit(mut self, value: u64) -> QueryInfo {
self.limit = value;
/// Set GROUP BY clause
pub fn set_group_by(mut self, group_by: &str) -> QueryInfo {
self.group_by = Some(group_by.to_string());
self
}
@@ -206,6 +225,12 @@ impl QueryInfo {
self
}
/// Set the limit for the request
pub fn set_limit(mut self, value: u64) -> QueryInfo {
self.limit = value;
self
}
/// Execute query
pub fn exec<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(self, process_function: F)
-> Result<Vec<E>, Box<dyn Error>> {
@@ -396,6 +421,10 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
}
// Join conditions
if info.joins_type == DatabaseQueryJoinType::LEFT {
query.push_str(" LEFT ");
}
for j in info.joins {
query = query.add(
format!(" JOIN {} {} ON {} ", j.table, j.table_alias, j.condition).as_ref());
@@ -427,6 +456,11 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
params.append(&mut custom_args);
}
// GROUP BY clause
if let Some(group_by) = info.group_by {
query.push_str(format!(" GROUP BY {} ", group_by).as_str())
}
// ORDER clause
if let Some(order) = info.order {
query = query.add(format!(" ORDER BY {} ", order).as_str());

View File

@@ -11,4 +11,5 @@ pub mod groups_helper;
pub mod posts_helper;
pub mod conversations_helper;
pub mod virtual_directory_helper;
pub mod movies_helper;
pub mod movies_helper;
pub mod survey_helper;

View File

@@ -5,7 +5,7 @@
use crate::constants::database_tables_names::POSTS_TABLE;
use crate::data::error::{ExecError, ResultBoxError};
use crate::data::post::{Post, PostFile, PostKind, PostPageKind, PostVisibilityLevel, PostWebLink};
use crate::data::post::PostKind::{POST_KIND_COUNTDOWN, POST_KIND_IMAGE, POST_KIND_MOVIE, POST_KIND_PDF, POST_KIND_WEBLINK};
use crate::data::post::PostKind::{POST_KIND_COUNTDOWN, POST_KIND_IMAGE, POST_KIND_MOVIE, POST_KIND_PDF, POST_KIND_SURVEY, POST_KIND_WEBLINK};
use crate::data::user::UserID;
use crate::helpers::{database, friends_helper};
use crate::utils::date_utils::time;
@@ -174,6 +174,8 @@ fn db_to_post(res: &database::RowResult) -> ResultBoxError<Post> {
"count_down" => post.kind = POST_KIND_COUNTDOWN(res.get_u64("time_end").unwrap_or(0)),
"sondage" => post.kind = POST_KIND_SURVEY,
_ => {}
}

View File

@@ -0,0 +1,63 @@
//! # Survey helper
//!
//! @author Pierre Hubert
use crate::constants::database_tables_names::{SURVEY_CHOICES_TABLE, SURVEY_INFO_TABLE, SURVEY_RESPONSE_TABLE};
use crate::data::error::ResultBoxError;
use crate::data::survey::{Survey, SurveyChoice};
use crate::data::user::UserID;
use crate::helpers::database;
/// Get information about a survey
pub fn get_info(post_id: u64) -> ResultBoxError<Survey> {
database::QueryInfo::new(SURVEY_INFO_TABLE)
.cond_u64("ID_texte", post_id)
.query_row(db_to_survey)
}
/// Get the choices of a survey
fn get_survey_choices(survey_id: u64) -> ResultBoxError<Vec<SurveyChoice>> {
database::QueryInfo::new(SURVEY_CHOICES_TABLE)
.alias("c")
.set_join_type(database::DatabaseQueryJoinType::LEFT)
.join(SURVEY_RESPONSE_TABLE, "r", "c.ID = r.ID_sondage_choix")
.cond_u64("c.ID_sondage", survey_id)
.set_group_by("c.ID")
.add_field("c.*")
.add_field("COUNT(r.ID) AS count_choice")
.exec(db_to_survey_choice)
}
/// Get the choice of a user for a survey
pub fn get_user_choice(survey_id: u64, user_id: &UserID) -> ResultBoxError<u64> {
Ok(database::QueryInfo::new(SURVEY_RESPONSE_TABLE)
.cond_u64("ID_sondage", survey_id)
.cond_user_id("ID_utilisateurs", user_id)
.exec(|r| r.get_u64("ID_sondage_choix"))?
.pop()
.unwrap_or(0))
}
/// Turn a database entry into a row object
fn db_to_survey(row: &database::RowResult) -> ResultBoxError<Survey> {
let survey_id = row.get_u64("ID")?;
Ok(Survey {
id: survey_id,
user_id: row.get_user_id("ID_utilisateurs")?,
time_create: row.get_date_as_time("date_creation")?,
post_id: row.get_u64("ID_texte")?,
question: row.get_str("question")?,
choices: get_survey_choices(survey_id)?,
allow_new_choices: row.get_legacy_bool("allow_new_choices")?,
})
}
/// Turn a database row into a survey choice
fn db_to_survey_choice(row: &database::RowResult) -> ResultBoxError<SurveyChoice> {
Ok(SurveyChoice {
id: row.get_u64("ID")?,
name: row.get_str("Choix")?,
count: row.get_u64("count_choice")?,
})
}