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 sea_query::{DynIden, IntoIden};
use sea_query::{Alias, DynIden, Iden, IntoIden, SeaRc};
use std::fmt;
#[derive(Debug, Clone)]
pub enum Identity {
@ -8,6 +9,25 @@ pub enum Identity {
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 {
fn into_identity(self) -> Identity;
}
@ -19,6 +39,18 @@ where
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
where
T: IdenStatic,

View File

@ -1,6 +1,6 @@
use crate::{
error::*, query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable,
JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectTwo,
error::*, DatabaseConnection, EntityTrait, FromQueryResult, IdenStatic, Iterable, JsonValue,
ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo,
SelectTwoMany, Statement,
};
use sea_query::SelectStatement;
@ -66,8 +66,8 @@ where
fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
Ok((
M::from_query_result(&res, combine::SELECT_A)?,
N::from_query_result_optional(&res, combine::SELECT_B)?,
M::from_query_result(&res, SelectA.as_str())?,
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;
pub use sea_query::JoinType;
use sea_query::{Alias, ColumnRef, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr};
pub const SELECT_A: &str = "A_";
pub const SELECT_B: &str = "B_";
macro_rules! select_def {
( $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>
where
@ -37,7 +58,7 @@ where
where
F: EntityTrait,
{
self = self.apply_alias(SELECT_A);
self = self.apply_alias(SelectA.as_str());
SelectTwo::new(self.into_query())
}
@ -45,7 +66,7 @@ where
where
F: EntityTrait,
{
self = self.apply_alias(SELECT_A);
self = self.apply_alias(SelectA.as_str());
SelectTwoMany::new(self.into_query())
}
}
@ -102,7 +123,7 @@ where
S: QueryTrait<QueryStatement = SelectStatement>,
{
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 {
expr: col.into_simple_expr(),
alias: Some(SeaRc::new(Alias::new(&alias))),

View File

@ -1,11 +1,9 @@
use crate::{
ColumnTrait, EntityTrait, Identity, IntoSimpleExpr, Iterable, ModelTrait, PrimaryKeyToColumn,
RelationDef,
};
use sea_query::{
Alias, Expr, Iden, IntoCondition, SeaRc, SelectExpr, SelectStatement, SimpleExpr, TableRef,
ColumnTrait, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable, ModelTrait,
PrimaryKeyToColumn, RelationDef,
};
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 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""#
/// );
/// ```
fn column_as<C>(mut self, col: C, alias: &str) -> Self
fn column_as<C, I>(mut self, col: C, alias: I) -> Self
where
C: IntoSimpleExpr,
I: IntoIdentity,
{
self.query().expr(SelectExpr {
expr: col.into_simple_expr(),
alias: Some(SeaRc::new(Alias::new(alias))),
});
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(),
))),
alias: Some(SeaRc::new(alias.into_identity())),
});
self
}

View File

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

View File

@ -484,6 +484,7 @@ pub async fn having() {
))]
pub async fn linked() -> Result<(), DbErr> {
use common::bakery_chain::Order;
use sea_orm::{SelectA, SelectB};
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()
.find_also_linked(baker::BakedForCustomer)
.select_only()
.column_as_prefixed(baker::Column::Name, "A_", baker::Column::Name)
.column_as_prefixed(customer::Column::Name, "B_", customer::Column::Name)
.column_as(baker::Column::Name, (SelectA, baker::Column::Name))
.column_as(customer::Column::Name, (SelectB, customer::Column::Name))
.group_by(baker::Column::Id)
.group_by(customer::Column::Id)
.group_by(baker::Column::Name)