Refactor Query traits

This commit is contained in:
Chris Tsang 2021-06-08 22:10:27 +08:00
parent f26e95c9e3
commit b308486192
4 changed files with 81 additions and 80 deletions

View File

@ -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;

View File

@ -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<RelationDef>) -> 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<RelationDef>) -> 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<RelationDef>) -> 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<RelationDef>) -> 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"),
}
}

View File

@ -1,4 +1,4 @@
use crate::{EntityTrait, Related, Select, SelectHelper, SelectTwo};
use crate::{EntityTrait, QuerySelect, Related, Select, SelectTwo};
pub use sea_query::JoinType;
impl<E> Select<E>

View File

@ -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<E> SelectHelper for Select<E>
where
E: EntityTrait,
{
fn query(&mut self) -> &mut SelectStatement {
&mut self.query
}
macro_rules! impl_trait {
( $trait: ident ) => {
impl<E> $trait for Select<E>
where
E: EntityTrait,
{
type QueryStatement = SelectStatement;
fn query(&mut self) -> &mut SelectStatement {
&mut self.query
}
}
impl<E, F> $trait for SelectTwo<E, F>
where
E: EntityTrait,
F: EntityTrait,
{
type QueryStatement = SelectStatement;
fn query(&mut self) -> &mut SelectStatement {
&mut self.query
}
}
};
}
impl<E> QueryFilter for Select<E>
where
E: EntityTrait,
{
type QueryStatement = SelectStatement;
fn query(&mut self) -> &mut SelectStatement {
&mut self.query
}
}
impl<E, F> SelectHelper for SelectTwo<E, F>
where
E: EntityTrait,
F: EntityTrait,
{
fn query(&mut self) -> &mut SelectStatement {
&mut self.query
}
}
impl<E, F> QueryFilter for SelectTwo<E, F>
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<C> IntoSimpleExpr for C
where