Skip to content

Commit

Permalink
WIP: Linked (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
billy1624 committed Aug 23, 2021
1 parent 8cfa142 commit 31941d3
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/entity/column.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
9 changes: 8 additions & 1 deletion src/entity/model.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions src/entity/prelude.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
16 changes: 16 additions & 0 deletions src/entity/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
55 changes: 54 additions & 1 deletion src/query/join.rs
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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(" ")
);
}
}
15 changes: 15 additions & 0 deletions src/tests_cfg/cake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

0 comments on commit 31941d3

Please sign in to comment.