children_count of member is added

This commit is contained in:
병준 박 2022-09-16 10:34:04 +00:00
parent b31b42cbbc
commit aab4804573
4 changed files with 94 additions and 4 deletions

View File

@ -36,7 +36,7 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
tokio-cron-scheduler = { version = "0" } tokio-cron-scheduler = { version = "0" }
uuid = { version = "0", features = ["serde", "v4", "v5"] } uuid = { version = "0", features = ["serde", "v4", "v5"] }
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.96-snapshot" } beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.97-snapshot" }
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.82-snapshot" } beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.83-snapshot" }
[build-dependencies] [build-dependencies]

View File

@ -7,6 +7,31 @@ use beteran_common_rust as bcr;
use diesel::{result::Error, sql_query, RunQueryDsl}; use diesel::{result::Error, sql_query, RunQueryDsl};
use std::fmt::Write; use std::fmt::Write;
static MEMBER_CHILDREN_COUNT_QUERY: &str = "
WITH RECURSIVE cte AS (
SELECT
id, parent_member_id, 1::integer recursion_level
FROM
members
WHERE
parent_member_id = $1
UNION ALL
SELECT
m.id, m.parent_member_id, cte.recursion_level +1
FROM
members m
JOIN cte ON cte.id = m.parent_member_id
)
SELECT
count(recursion_level) AS count_of_children
FROM
cte
group by
recursion_level
order by
recursion_level asc
";
static MEMBER_PARENTS_QUERY: &str = " static MEMBER_PARENTS_QUERY: &str = "
WITH RECURSIVE rec AS ( WITH RECURSIVE rec AS (
@ -548,6 +573,7 @@ impl Composition {
Ok(Some(models::from_member_model( Ok(Some(models::from_member_model(
&_m, &_m,
self.select_parent(conn, _m.parent_member_id)?, self.select_parent(conn, _m.parent_member_id)?,
self.select_children_count(conn, _m.parent_member_id)?,
))) )))
} }
@ -584,9 +610,63 @@ impl Composition {
Ok(Some(models::from_member_model( Ok(Some(models::from_member_model(
&_m, &_m,
self.select_parent(conn, _m.parent_member_id)?, self.select_parent(conn, _m.parent_member_id)?,
self.select_children_count(conn, _m.parent_member_id)?,
))) )))
} }
///
pub fn select_children_count(
&self,
conn: &diesel::PgConnection,
parent_member_id: Option<uuid::Uuid>,
) -> Result<Vec<i64>, Error> {
use diesel::sql_types::BigInt;
#[derive(QueryableByName)]
struct Count {
#[sql_type = "BigInt"]
count_of_children: i64,
}
let parent_member_id = match parent_member_id {
Some(i) => i,
None => {
return Ok(vec![]);
}
};
let query = format!(
"
{}
",
MEMBER_CHILDREN_COUNT_QUERY
);
let count_of_children = match sql_query(query)
.bind::<diesel::sql_types::Uuid, _>(parent_member_id)
.get_results::<Count>(conn)
{
Ok(m) => m,
Err(e) => match e {
diesel::result::Error::NotFound => vec![],
_ => {
return Err(e);
}
},
};
if count_of_children.is_empty() {
return Ok(vec![]);
}
let mut p: Vec<i64> = vec![];
for c in count_of_children {
p.push(c.count_of_children);
}
Ok(p)
}
/// ///
pub fn select_parent( pub fn select_parent(
&self, &self,
@ -626,7 +706,11 @@ impl Composition {
let mut p: Option<models::MemberModel> = None; let mut p: Option<models::MemberModel> = None;
for m in members { for m in members {
p = Some(models::from_member_model(&m, p)); p = Some(models::from_member_model(
&m,
p,
self.select_children_count(conn, m.parent_member_id)?,
));
} }
Ok(p) Ok(p)
@ -920,6 +1004,7 @@ impl Composition {
list.push(models::from_member_model( list.push(models::from_member_model(
&_m, &_m,
self.select_parent(conn, _m.parent_member_id)?, self.select_parent(conn, _m.parent_member_id)?,
self.select_children_count(conn, _m.parent_member_id)?,
)); ));
} }

View File

@ -212,6 +212,8 @@ pub struct MemberModel {
/// ///
pub parent_member: Option<Box<MemberModel>>, pub parent_member: Option<Box<MemberModel>>,
/// ///
pub children_count: Vec<i64>,
///
pub child_member_count: i64, pub child_member_count: i64,
/// ///
pub mobile_phone_number: Option<String>, pub mobile_phone_number: Option<String>,
@ -235,7 +237,7 @@ pub struct MemberModel {
pub deleted_at: Option<i64>, pub deleted_at: Option<i64>,
} }
pub fn from_member_model(_m: &_MemberModel, p: Option<MemberModel>) -> MemberModel { pub fn from_member_model(_m: &_MemberModel, p: Option<MemberModel>, c: Vec<i64>) -> MemberModel {
MemberModel { MemberModel {
id: _m.id, id: _m.id,
site: _m.site.clone(), site: _m.site.clone(),
@ -246,6 +248,7 @@ pub fn from_member_model(_m: &_MemberModel, p: Option<MemberModel>) -> MemberMod
password: _m.password.clone(), password: _m.password.clone(),
nickname: _m.nickname.clone(), nickname: _m.nickname.clone(),
parent_member: p.map(Box::new), parent_member: p.map(Box::new),
children_count: c,
child_member_count: _m.child_member_count, child_member_count: _m.child_member_count,
mobile_phone_number: _m.mobile_phone_number.clone(), mobile_phone_number: _m.mobile_phone_number.clone(),
state: _m.state, state: _m.state,

View File

@ -71,6 +71,7 @@ impl From<&compositions::member::models::MemberModel> for bpr::models::member::M
.as_ref() .as_ref()
.map(|v| Box::<bpr::models::member::MemberModel>::from(v)), .map(|v| Box::<bpr::models::member::MemberModel>::from(v)),
child_member_count: d.child_member_count as u64, child_member_count: d.child_member_count as u64,
children_count: d.children_count.iter().map(|v| *v as u64).collect(),
username: d.username.clone(), username: d.username.clone(),
nickname: d.nickname.clone(), nickname: d.nickname.clone(),
mobile_phone_number: d.mobile_phone_number.clone(), mobile_phone_number: d.mobile_phone_number.clone(),
@ -115,6 +116,7 @@ impl From<&Box<compositions::member::models::MemberModel>>
.as_ref() .as_ref()
.map(|v| Box::<bpr::models::member::MemberModel>::from(v)), .map(|v| Box::<bpr::models::member::MemberModel>::from(v)),
child_member_count: d.child_member_count as u64, child_member_count: d.child_member_count as u64,
children_count: d.children_count.iter().map(|v| *v as u64).collect(),
username: d.username.clone(), username: d.username.clone(),
nickname: d.nickname.clone(), nickname: d.nickname.clone(),
mobile_phone_number: d.mobile_phone_number.clone(), mobile_phone_number: d.mobile_phone_number.clone(),