From b3084861927bf082050948f7a4a40413b957090e Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Tue, 8 Jun 2021 22:10:27 +0800 Subject: [PATCH] Refactor Query traits --- src/entity/relation.rs | 2 +- src/query/helper.rs | 88 ++++++++++++++++++++++++------------------ src/query/join.rs | 2 +- src/query/select.rs | 69 ++++++++++++++------------------- 4 files changed, 81 insertions(+), 80 deletions(-) diff --git a/src/entity/relation.rs b/src/entity/relation.rs index 807158b6..4cb2a3d5 100644 --- a/src/entity/relation.rs +++ b/src/entity/relation.rs @@ -1,4 +1,4 @@ -use crate::{EntityTrait, Identity, IntoIdentity, Iterable, Select, SelectHelper}; +use crate::{EntityTrait, Identity, IntoIdentity, Iterable, QuerySelect, Select}; use core::marker::PhantomData; use sea_query::{DynIden, IntoIden, JoinType}; use std::fmt::Debug; diff --git a/src/query/helper.rs b/src/query/helper.rs index e541284e..550dd676 100644 --- a/src/query/helper.rs +++ b/src/query/helper.rs @@ -3,9 +3,13 @@ use crate::{ RelationDef, }; use sea_query::{Alias, Expr, IntoCondition, SelectExpr, SelectStatement, SimpleExpr}; -pub use sea_query::{Condition, ConditionalStatement, DynIden, JoinType, Order, SeaRc}; +pub use sea_query::{ + Condition, ConditionalStatement, DynIden, JoinType, Order, OrderedStatement, SeaRc, +}; + +pub trait QuerySelect: Sized { + type QueryStatement; -pub trait SelectHelper: Sized { fn query(&mut self) -> &mut SelectStatement; /// Clear the selection list @@ -81,6 +85,45 @@ pub trait SelectHelper: Sized { self } + #[doc(hidden)] + fn join_join(mut self, join: JoinType, rel: RelationDef, via: Option) -> Self { + if let Some(via) = via { + self = self.join(join, via) + } + self.join(join, rel) + } + + #[doc(hidden)] + fn join_join_rev(mut self, join: JoinType, rel: RelationDef, via: Option) -> Self { + self = self.join_rev(join, rel); + if let Some(via) = via { + self = self.join_rev(join, via) + } + self + } + + /// Join via [`RelationDef`]. + fn join(mut self, join: JoinType, rel: RelationDef) -> Self { + self.query() + .join(join, rel.to_tbl.clone(), join_condition(rel)); + self + } + + /// Join via [`RelationDef`] but in reverse direction. + /// Assume when there exist a relation A to B. + /// You can reverse join B from A. + fn join_rev(mut self, join: JoinType, rel: RelationDef) -> Self { + self.query() + .join(join, rel.from_tbl.clone(), join_condition(rel)); + self + } +} + +pub trait QueryOrder: Sized { + type QueryStatement: OrderedStatement; + + fn query(&mut self) -> &mut SelectStatement; + /// Add an order_by expression /// ``` /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::MysqlQueryBuilder}; @@ -143,39 +186,6 @@ pub trait SelectHelper: Sized { .order_by_expr(col.into_simple_expr(), Order::Desc); self } - - #[doc(hidden)] - fn join_join(mut self, join: JoinType, rel: RelationDef, via: Option) -> Self { - if let Some(via) = via { - self = self.join(join, via) - } - self.join(join, rel) - } - - #[doc(hidden)] - fn join_join_rev(mut self, join: JoinType, rel: RelationDef, via: Option) -> Self { - self = self.join_rev(join, rel); - if let Some(via) = via { - self = self.join_rev(join, via) - } - self - } - - /// Join via [`RelationDef`]. - fn join(mut self, join: JoinType, rel: RelationDef) -> Self { - self.query() - .join(join, rel.to_tbl.clone(), join_condition(rel)); - self - } - - /// Join via [`RelationDef`] but in reverse direction. - /// Assume when there exist a relation A to B. - /// You can reverse join B from A. - fn join_rev(mut self, join: JoinType, rel: RelationDef) -> Self { - self.query() - .join(join, rel.from_tbl.clone(), join_condition(rel)); - self - } } pub trait QueryFilter: Sized { @@ -244,9 +254,11 @@ fn join_condition(rel: RelationDef) -> SimpleExpr { (Identity::Unary(o1), Identity::Unary(f1)) => { Expr::tbl(SeaRc::clone(&from_tbl), o1).equals(SeaRc::clone(&to_tbl), f1) } - (Identity::Binary(o1, o2), Identity::Binary(f1, f2)) => Expr::tbl(SeaRc::clone(&from_tbl), o1) - .equals(SeaRc::clone(&to_tbl), f1) - .and(Expr::tbl(SeaRc::clone(&from_tbl), o2).equals(SeaRc::clone(&to_tbl), f2)), + (Identity::Binary(o1, o2), Identity::Binary(f1, f2)) => { + Expr::tbl(SeaRc::clone(&from_tbl), o1) + .equals(SeaRc::clone(&to_tbl), f1) + .and(Expr::tbl(SeaRc::clone(&from_tbl), o2).equals(SeaRc::clone(&to_tbl), f2)) + } _ => panic!("Owner key and foreign key mismatch"), } } diff --git a/src/query/join.rs b/src/query/join.rs index 294707d0..4302b2e7 100644 --- a/src/query/join.rs +++ b/src/query/join.rs @@ -1,4 +1,4 @@ -use crate::{EntityTrait, Related, Select, SelectHelper, SelectTwo}; +use crate::{EntityTrait, QuerySelect, Related, Select, SelectTwo}; pub use sea_query::JoinType; impl Select diff --git a/src/query/select.rs b/src/query/select.rs index 82a008a7..af483908 100644 --- a/src/query/select.rs +++ b/src/query/select.rs @@ -1,4 +1,4 @@ -use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryTrait, SelectHelper}; +use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait}; use core::fmt::Debug; use core::marker::PhantomData; pub use sea_query::JoinType; @@ -27,47 +27,36 @@ pub trait IntoSimpleExpr { fn into_simple_expr(self) -> SimpleExpr; } -impl SelectHelper for Select -where - E: EntityTrait, -{ - fn query(&mut self) -> &mut SelectStatement { - &mut self.query - } +macro_rules! impl_trait { + ( $trait: ident ) => { + impl $trait for Select + where + E: EntityTrait, + { + type QueryStatement = SelectStatement; + + fn query(&mut self) -> &mut SelectStatement { + &mut self.query + } + } + + impl $trait for SelectTwo + where + E: EntityTrait, + F: EntityTrait, + { + type QueryStatement = SelectStatement; + + fn query(&mut self) -> &mut SelectStatement { + &mut self.query + } + } + }; } -impl QueryFilter for Select -where - E: EntityTrait, -{ - type QueryStatement = SelectStatement; - - fn query(&mut self) -> &mut SelectStatement { - &mut self.query - } -} - -impl SelectHelper for SelectTwo -where - E: EntityTrait, - F: EntityTrait, -{ - fn query(&mut self) -> &mut SelectStatement { - &mut self.query - } -} - -impl QueryFilter for SelectTwo -where - E: EntityTrait, - F: EntityTrait, -{ - type QueryStatement = SelectStatement; - - fn query(&mut self) -> &mut SelectStatement { - &mut self.query - } -} +impl_trait!(QuerySelect); +impl_trait!(QueryFilter); +impl_trait!(QueryOrder); impl IntoSimpleExpr for C where