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