diff --git a/src/entity/model.rs b/src/entity/model.rs index eab2e533..acf21c0d 100644 --- a/src/entity/model.rs +++ b/src/entity/model.rs @@ -14,4 +14,11 @@ pub trait FromQueryResult { fn from_query_result(res: &QueryResult, pre: &str) -> Result where Self: Sized; + + fn from_query_result_opt(res: &QueryResult, pre: &str) -> Result, TypeErr> + where + Self: Sized, + { + Ok(Self::from_query_result(res, pre).ok()) + } } diff --git a/src/executor/select.rs b/src/executor/select.rs index b15c0c4b..4876b457 100644 --- a/src/executor/select.rs +++ b/src/executor/select.rs @@ -52,12 +52,12 @@ where M: FromQueryResult + Sized, N: FromQueryResult + Sized, { - type Item = (M, N); + type Item = (M, Option); fn from_raw_query_result(res: QueryResult) -> Result { Ok(( M::from_query_result(&res, combine::SELECT_A)?, - N::from_query_result(&res, combine::SELECT_B)?, + N::from_query_result_opt(&res, combine::SELECT_B)?, )) } } @@ -125,37 +125,10 @@ where } } - fn parse_query_result(rows: Vec<(E::Model, F::Model)>) -> Vec<(E::Model, Vec)> { - let mut acc = Vec::new(); - for (l_model, r_model) in rows { - if acc.is_empty() { - acc.push((l_model, vec![r_model])); - continue; - } - let (last_l, last_r) = acc.last_mut().unwrap(); - let mut l_equal = true; - for pk_col in ::iter() { - let col = pk_col.into_column(); - let curr_val = l_model.get(col); - let last_val = last_l.get(col); - if !curr_val.eq(&last_val) { - l_equal = false; - break; - } - } - if l_equal { - last_r.push(r_model); - } else { - acc.push((l_model, vec![r_model])); - } - } - acc - } - pub async fn one( self, db: &DatabaseConnection, - ) -> Result, QueryErr> { + ) -> Result)>, QueryErr> { self.into_model::().one(db).await } @@ -164,7 +137,7 @@ where db: &DatabaseConnection, ) -> Result)>, QueryErr> { let rows = self.into_model::().all(db).await?; - Ok(Self::parse_query_result(rows)) + Ok(parse_query_result::(rows)) } } @@ -202,3 +175,34 @@ where } } } + +fn parse_query_result(rows: Vec<(L::Model, Option)>) -> Vec<(L::Model, Vec)> +where + L: EntityTrait, +{ + let mut acc: Vec<(L::Model, Vec)> = Vec::new(); + for (l, r) in rows { + if let Some((last_l, last_r)) = acc.last_mut() { + let mut same_l = true; + for pk_col in ::iter() { + let col = pk_col.into_column(); + let val = l.get(col); + let last_val = last_l.get(col); + if !val.eq(&last_val) { + same_l = false; + break; + } + } + if same_l && r.is_some() { + last_r.push(r.unwrap()); + continue; + } + } + if r.is_some() { + acc.push((l, vec![r.unwrap()])); + } else { + acc.push((l, vec![])); + } + } + acc +} \ No newline at end of file