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 crate::{EntityName, IdenStatic, Iterable};
|
||||||
use sea_query::{DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
use sea_query::{DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ColumnDef {
|
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;
|
pub use sea_query::Value;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
@ -16,6 +16,13 @@ pub trait ModelTrait: Clone + Debug {
|
|||||||
{
|
{
|
||||||
<Self::Entity as Related<R>>::find_related().belongs_to(self)
|
<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 {
|
pub trait FromQueryResult {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||||
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, Linked,
|
||||||
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related,
|
||||||
RelationTrait, Select, Value,
|
RelationDef, RelationTrait, Select, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "with-json")]
|
#[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 struct RelationDef {
|
||||||
pub rel_type: RelationType,
|
pub rel_type: RelationType,
|
||||||
pub from_tbl: TableRef,
|
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;
|
pub use sea_query::JoinType;
|
||||||
|
|
||||||
impl<E> Select<E>
|
impl<E> Select<E>
|
||||||
@ -57,6 +57,19 @@ where
|
|||||||
{
|
{
|
||||||
self.left_join(r).select_with(r)
|
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)]
|
#[cfg(test)]
|
||||||
@ -220,4 +233,44 @@ mod tests {
|
|||||||
.join(" ")
|
.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 {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user