Update query helper column_as

This commit is contained in:
Billy Chan 2021-09-03 11:23:29 +08:00
parent cd43ff7143
commit 541b94f15d
No known key found for this signature in database
GPG Key ID: A2D690CAC7DF3CC7
6 changed files with 74 additions and 48 deletions

View File

@ -1,5 +1,6 @@
use crate::{ColumnTrait, EntityTrait, IdenStatic}; use crate::{ColumnTrait, EntityTrait, IdenStatic};
use sea_query::{DynIden, IntoIden}; use sea_query::{Alias, DynIden, Iden, IntoIden, SeaRc};
use std::fmt;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Identity { pub enum Identity {
@ -8,6 +9,25 @@ pub enum Identity {
Ternary(DynIden, DynIden, DynIden), Ternary(DynIden, DynIden, DynIden),
} }
impl Iden for Identity {
fn unquoted(&self, s: &mut dyn fmt::Write) {
match self {
Identity::Unary(iden) => {
write!(s, "{}", iden.to_string()).unwrap();
}
Identity::Binary(iden1, iden2) => {
write!(s, "{}", iden1.to_string()).unwrap();
write!(s, "{}", iden2.to_string()).unwrap();
}
Identity::Ternary(iden1, iden2, iden3) => {
write!(s, "{}", iden1.to_string()).unwrap();
write!(s, "{}", iden2.to_string()).unwrap();
write!(s, "{}", iden3.to_string()).unwrap();
}
}
}
}
pub trait IntoIdentity { pub trait IntoIdentity {
fn into_identity(self) -> Identity; fn into_identity(self) -> Identity;
} }
@ -19,6 +39,18 @@ where
fn identity_of(self) -> Identity; fn identity_of(self) -> Identity;
} }
impl IntoIdentity for String {
fn into_identity(self) -> Identity {
self.as_str().into_identity()
}
}
impl IntoIdentity for &str {
fn into_identity(self) -> Identity {
Identity::Unary(SeaRc::new(Alias::new(self)))
}
}
impl<T> IntoIdentity for T impl<T> IntoIdentity for T
where where
T: IdenStatic, T: IdenStatic,

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
error::*, query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable, error::*, DatabaseConnection, EntityTrait, FromQueryResult, IdenStatic, Iterable, JsonValue,
JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectTwo, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo,
SelectTwoMany, Statement, SelectTwoMany, Statement,
}; };
use sea_query::SelectStatement; use sea_query::SelectStatement;
@ -66,8 +66,8 @@ where
fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> { fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
Ok(( Ok((
M::from_query_result(&res, combine::SELECT_A)?, M::from_query_result(&res, SelectA.as_str())?,
N::from_query_result_optional(&res, combine::SELECT_B)?, N::from_query_result_optional(&res, SelectB.as_str())?,
)) ))
} }
} }

View File

@ -1,10 +1,31 @@
use crate::{EntityTrait, IntoSimpleExpr, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany}; use crate::{
EntityTrait, IdenStatic, IntoSimpleExpr, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany,
};
use core::marker::PhantomData; use core::marker::PhantomData;
pub use sea_query::JoinType; pub use sea_query::JoinType;
use sea_query::{Alias, ColumnRef, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr}; use sea_query::{Alias, ColumnRef, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr};
pub const SELECT_A: &str = "A_"; macro_rules! select_def {
pub const SELECT_B: &str = "B_"; ( $ident: ident, $str: expr ) => {
#[derive(Debug, Clone, Copy)]
pub struct $ident;
impl Iden for $ident {
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
write!(s, "{}", self.as_str()).unwrap();
}
}
impl IdenStatic for $ident {
fn as_str(&self) -> &str {
$str
}
}
};
}
select_def!(SelectA, "A_");
select_def!(SelectB, "B_");
impl<E> Select<E> impl<E> Select<E>
where where
@ -37,7 +58,7 @@ where
where where
F: EntityTrait, F: EntityTrait,
{ {
self = self.apply_alias(SELECT_A); self = self.apply_alias(SelectA.as_str());
SelectTwo::new(self.into_query()) SelectTwo::new(self.into_query())
} }
@ -45,7 +66,7 @@ where
where where
F: EntityTrait, F: EntityTrait,
{ {
self = self.apply_alias(SELECT_A); self = self.apply_alias(SelectA.as_str());
SelectTwoMany::new(self.into_query()) SelectTwoMany::new(self.into_query())
} }
} }
@ -102,7 +123,7 @@ where
S: QueryTrait<QueryStatement = SelectStatement>, S: QueryTrait<QueryStatement = SelectStatement>,
{ {
for col in <F::Column as Iterable>::iter() { for col in <F::Column as Iterable>::iter() {
let alias = format!("{}{}", SELECT_B, col.to_string().as_str()); let alias = format!("{}{}", SelectB.as_str(), col.as_str());
selector.query().expr(SelectExpr { selector.query().expr(SelectExpr {
expr: col.into_simple_expr(), expr: col.into_simple_expr(),
alias: Some(SeaRc::new(Alias::new(&alias))), alias: Some(SeaRc::new(Alias::new(&alias))),

View File

@ -1,11 +1,9 @@
use crate::{ use crate::{
ColumnTrait, EntityTrait, Identity, IntoSimpleExpr, Iterable, ModelTrait, PrimaryKeyToColumn, ColumnTrait, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable, ModelTrait,
RelationDef, PrimaryKeyToColumn, RelationDef,
};
use sea_query::{
Alias, Expr, Iden, IntoCondition, SeaRc, SelectExpr, SelectStatement, SimpleExpr, TableRef,
}; };
pub use sea_query::{Condition, ConditionalStatement, DynIden, JoinType, Order, OrderedStatement}; pub use sea_query::{Condition, ConditionalStatement, DynIden, JoinType, Order, OrderedStatement};
use sea_query::{Expr, IntoCondition, SeaRc, SelectExpr, SelectStatement, SimpleExpr, TableRef};
// LINT: when the column does not appear in tables selected from // LINT: when the column does not appear in tables selected from
// LINT: when there is a group by clause, but some columns don't have aggregate functions // LINT: when there is a group by clause, but some columns don't have aggregate functions
@ -55,40 +53,14 @@ pub trait QuerySelect: Sized {
/// r#"SELECT COUNT("cake"."id") AS "count" FROM "cake""# /// r#"SELECT COUNT("cake"."id") AS "count" FROM "cake""#
/// ); /// );
/// ``` /// ```
fn column_as<C>(mut self, col: C, alias: &str) -> Self fn column_as<C, I>(mut self, col: C, alias: I) -> Self
where where
C: IntoSimpleExpr, C: IntoSimpleExpr,
I: IntoIdentity,
{ {
self.query().expr(SelectExpr { self.query().expr(SelectExpr {
expr: col.into_simple_expr(), expr: col.into_simple_expr(),
alias: Some(SeaRc::new(Alias::new(alias))), alias: Some(SeaRc::new(alias.into_identity())),
});
self
}
/// Add a select column with prefixed alias
/// ```
/// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};
///
/// assert_eq!(
/// cake::Entity::find()
/// .select_only()
/// .column_as_prefixed(cake::Column::Id.count(), "A_", cake::Column::Id)
/// .build(DbBackend::Postgres)
/// .to_string(),
/// r#"SELECT COUNT("cake"."id") AS "A_id" FROM "cake""#
/// );
/// ```
fn column_as_prefixed<C, I>(mut self, col: C, prefix: &str, alias: I) -> Self
where
C: IntoSimpleExpr,
I: Iden,
{
self.query().expr(SelectExpr {
expr: col.into_simple_expr(),
alias: Some(SeaRc::new(Alias::new(
vec![prefix, alias.to_string().as_str()].join("").as_str(),
))),
}); });
self self
} }

View File

@ -9,7 +9,7 @@ mod select;
mod traits; mod traits;
mod update; mod update;
// pub use combine::*; pub use combine::{SelectA, SelectB};
pub use delete::*; pub use delete::*;
pub use helper::*; pub use helper::*;
pub use insert::*; pub use insert::*;

View File

@ -484,6 +484,7 @@ pub async fn having() {
))] ))]
pub async fn linked() -> Result<(), DbErr> { pub async fn linked() -> Result<(), DbErr> {
use common::bakery_chain::Order; use common::bakery_chain::Order;
use sea_orm::{SelectA, SelectB};
let ctx = TestContext::new("test_linked").await; let ctx = TestContext::new("test_linked").await;
@ -665,8 +666,8 @@ pub async fn linked() -> Result<(), DbErr> {
let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find() let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find()
.find_also_linked(baker::BakedForCustomer) .find_also_linked(baker::BakedForCustomer)
.select_only() .select_only()
.column_as_prefixed(baker::Column::Name, "A_", baker::Column::Name) .column_as(baker::Column::Name, (SelectA, baker::Column::Name))
.column_as_prefixed(customer::Column::Name, "B_", customer::Column::Name) .column_as(customer::Column::Name, (SelectB, customer::Column::Name))
.group_by(baker::Column::Id) .group_by(baker::Column::Id)
.group_by(customer::Column::Id) .group_by(customer::Column::Id)
.group_by(baker::Column::Name) .group_by(baker::Column::Name)