Select to many
This commit is contained in:
parent
0afd226dbe
commit
19c0b0c35d
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
query::combine, DatabaseConnection, EntityTrait, FromQueryResult, JsonValue, Paginator,
|
||||
QueryErr, QueryResult, Select, SelectTwo, TypeErr,
|
||||
query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable, JsonValue,
|
||||
ModelTrait, Paginator, PrimaryKeyToColumn, QueryErr, QueryResult, Select, SelectTwo, TypeErr,
|
||||
};
|
||||
use sea_query::SelectStatement;
|
||||
use std::marker::PhantomData;
|
||||
@ -125,6 +125,33 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_query_result(rows: Vec<(E::Model, F::Model)>) -> Vec<(E::Model, Vec<F::Model>)> {
|
||||
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 <E::PrimaryKey as Iterable>::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,
|
||||
@ -132,8 +159,12 @@ where
|
||||
self.into_model::<E::Model, F::Model>().one(db).await
|
||||
}
|
||||
|
||||
pub async fn all(self, db: &DatabaseConnection) -> Result<Vec<(E::Model, F::Model)>, QueryErr> {
|
||||
self.into_model::<E::Model, F::Model>().all(db).await
|
||||
pub async fn all(
|
||||
self,
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<Vec<(E::Model, Vec<F::Model>)>, QueryErr> {
|
||||
let rows = self.into_model::<E::Model, F::Model>().all(db).await?;
|
||||
Ok(Self::parse_query_result(rows))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{EntityTrait, IntoSimpleExpr, Iterable, QueryTrait, Select, SelectTwo};
|
||||
use core::marker::PhantomData;
|
||||
pub use sea_query::JoinType;
|
||||
use sea_query::{Alias, ColumnRef, Iden, SeaRc, SelectExpr, SelectStatement, SimpleExpr};
|
||||
use sea_query::{Alias, ColumnRef, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr};
|
||||
|
||||
pub const SELECT_A: &str = "A_";
|
||||
pub const SELECT_B: &str = "B_";
|
||||
@ -48,11 +48,12 @@ where
|
||||
F: EntityTrait,
|
||||
{
|
||||
pub(crate) fn new(query: SelectStatement) -> Self {
|
||||
let myself = Self {
|
||||
Self {
|
||||
query,
|
||||
entity: PhantomData,
|
||||
};
|
||||
myself.prepare_select()
|
||||
}
|
||||
.prepare_select()
|
||||
.prepare_order_by()
|
||||
}
|
||||
|
||||
fn prepare_select(mut self) -> Self {
|
||||
@ -65,6 +66,13 @@ where
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn prepare_order_by(mut self) -> Self {
|
||||
for col in <E::PrimaryKey as Iterable>::iter() {
|
||||
self.query.order_by((E::default(), col), Order::Asc);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -97,6 +105,7 @@ mod tests {
|
||||
"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,",
|
||||
"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`",
|
||||
"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`",
|
||||
"ORDER BY `cake`.`id` ASC",
|
||||
].join(" ")
|
||||
);
|
||||
}
|
||||
@ -116,6 +125,7 @@ mod tests {
|
||||
"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`",
|
||||
"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`",
|
||||
"WHERE `cake`.`id` = 1 AND `fruit`.`id` = 2",
|
||||
"ORDER BY `cake`.`id` ASC",
|
||||
].join(" ")
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user