WIP: Linked (#89)
This commit is contained in:
parent
8cfa14233d
commit
31941d3af6
@ -1,6 +1,6 @@
|
||||
use std::str::FromStr;
|
||||
use crate::{EntityName, IdenStatic, Iterable};
|
||||
use sea_query::{DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ColumnDef {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{DbErr, EntityTrait, QueryFilter, QueryResult, Related, Select};
|
||||
use crate::{DbErr, EntityTrait, Linked, QueryFilter, QueryResult, Related, Select};
|
||||
pub use sea_query::Value;
|
||||
use std::fmt::Debug;
|
||||
|
||||
@ -16,6 +16,13 @@ pub trait ModelTrait: Clone + Debug {
|
||||
{
|
||||
<Self::Entity as Related<R>>::find_related().belongs_to(self)
|
||||
}
|
||||
|
||||
fn find_linked<L>(&self, _: L) -> Select<L::ToEntity>
|
||||
where
|
||||
L: Linked<FromEntity = Self::Entity>,
|
||||
{
|
||||
L::find_linked()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FromQueryResult {
|
||||
|
@ -1,9 +1,9 @@
|
||||
pub use crate::{
|
||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
||||
RelationTrait, Select, Value,
|
||||
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, Linked,
|
||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related,
|
||||
RelationDef, RelationTrait, Select, Value,
|
||||
};
|
||||
|
||||
#[cfg(feature = "with-json")]
|
||||
|
@ -28,6 +28,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Linked {
|
||||
type FromEntity: EntityTrait;
|
||||
|
||||
type ToEntity: EntityTrait;
|
||||
|
||||
fn link() -> Vec<RelationDef>;
|
||||
|
||||
fn find_linked() -> Select<Self::ToEntity> {
|
||||
let mut select = Select::new();
|
||||
for rel in Self::link() {
|
||||
select = select.join(JoinType::InnerJoin, rel);
|
||||
}
|
||||
select
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RelationDef {
|
||||
pub rel_type: RelationType,
|
||||
pub from_tbl: TableRef,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{EntityTrait, QuerySelect, Related, Select, SelectTwo, SelectTwoMany};
|
||||
use crate::{EntityTrait, Linked, QuerySelect, Related, Select, SelectTwo, SelectTwoMany};
|
||||
pub use sea_query::JoinType;
|
||||
|
||||
impl<E> Select<E>
|
||||
@ -57,6 +57,19 @@ where
|
||||
{
|
||||
self.left_join(r).select_with(r)
|
||||
}
|
||||
|
||||
/// Left Join with a Linked Entity and select both Entity.
|
||||
pub fn find_also_linked<L, T>(self, _: L) -> SelectTwo<E, T>
|
||||
where
|
||||
L: Linked<FromEntity = E, ToEntity = T>,
|
||||
T: EntityTrait,
|
||||
{
|
||||
let mut slf = self;
|
||||
for rel in L::link() {
|
||||
slf = slf.join(JoinType::LeftJoin, rel);
|
||||
}
|
||||
slf.select_also(T::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -220,4 +233,44 @@ mod tests {
|
||||
.join(" ")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn join_10() {
|
||||
let cake_model = cake::Model {
|
||||
id: 12,
|
||||
name: "".to_owned(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
cake_model
|
||||
.find_linked(cake::CakeToFilling)
|
||||
.build(DbBackend::MySql)
|
||||
.to_string(),
|
||||
[
|
||||
r#"SELECT `filling`.`id`, `filling`.`name`"#,
|
||||
r#"FROM `filling`"#,
|
||||
r#"INNER JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`"#,
|
||||
r#"INNER JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`"#,
|
||||
]
|
||||
.join(" ")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn join_11() {
|
||||
assert_eq!(
|
||||
cake::Entity::find()
|
||||
.find_also_linked(cake::CakeToFilling)
|
||||
.build(DbBackend::MySql)
|
||||
.to_string(),
|
||||
[
|
||||
r#"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,"#,
|
||||
r#"`filling`.`id` AS `B_id`, `filling`.`name` AS `B_name`"#,
|
||||
r#"FROM `cake`"#,
|
||||
r#"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`"#,
|
||||
r#"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`"#,
|
||||
]
|
||||
.join(" ")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -73,4 +73,19 @@ impl Related<super::filling::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CakeToFilling;
|
||||
|
||||
impl Linked for CakeToFilling {
|
||||
type FromEntity = Entity;
|
||||
|
||||
type ToEntity = super::filling::Entity;
|
||||
|
||||
fn link() -> Vec<RelationDef> {
|
||||
vec![
|
||||
super::cake_filling::Relation::Cake.def().rev(),
|
||||
super::cake_filling::Relation::Filling.def(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user