add SelectColumns
only modify select columns
add `PartialModelTrait` for a part of model
re-export `PartialModelTrait`
cargo fmt
add fn`into_partial_model` on `Select`&`SelectTwo`
add `DerivePartialModel` to impl `PartialModel`
add macro `DerivePartialModel` to `sea-orm`
disambiguate `SelectColumns` function
fix macro error
cargo fmt && cargo clippy
move `SelectColumns` from helper.rs to traits.rs
cargo fmt
Reduce nest hell of load attribute argument fetch
✅ test `DerivePartialModel` input parse
`DerivePartialModel` not derive with generic
fix `DerivePartialModel` code generate error
remove unused use
cargo fmt
add `into_partial_model` for `SelectTwoMany`
This commit is contained in:
parent
f876927f53
commit
744e063222
@ -9,6 +9,7 @@ mod from_query_result;
|
||||
mod into_active_model;
|
||||
mod migration;
|
||||
mod model;
|
||||
mod partial_model;
|
||||
mod primary_key;
|
||||
mod relation;
|
||||
mod try_getable_from_json;
|
||||
@ -24,6 +25,7 @@ pub use from_query_result::*;
|
||||
pub use into_active_model::*;
|
||||
pub use migration::*;
|
||||
pub use model::*;
|
||||
pub use partial_model::*;
|
||||
pub use primary_key::*;
|
||||
pub use relation::*;
|
||||
pub use try_getable_from_json::*;
|
||||
|
269
sea-orm-macros/src/derives/partial_model.rs
Normal file
269
sea-orm-macros/src/derives/partial_model.rs
Normal file
@ -0,0 +1,269 @@
|
||||
use heck::ToUpperCamelCase;
|
||||
use proc_macro2::Span;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::format_ident;
|
||||
use quote::quote;
|
||||
use quote::quote_spanned;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::token::Comma;
|
||||
use syn::Expr;
|
||||
|
||||
use syn::Meta;
|
||||
|
||||
use self::util::GetAsKVMeta;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Error {
|
||||
InputNotStruct,
|
||||
EntityNotSpecific,
|
||||
NotSupportGeneric(Span),
|
||||
BothFromColAndFromExpr(Span),
|
||||
Syn(syn::Error),
|
||||
}
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum ColumnAs {
|
||||
/// column in the model
|
||||
Col(syn::Ident),
|
||||
/// alias from a column in model
|
||||
ColAlias { col: syn::Ident, field: String },
|
||||
/// from a expr
|
||||
Expr { expr: syn::Expr, field_name: String },
|
||||
}
|
||||
|
||||
struct DerivePartialModel {
|
||||
entity_ident: Option<syn::Ident>,
|
||||
ident: syn::Ident,
|
||||
fields: Vec<ColumnAs>,
|
||||
}
|
||||
|
||||
impl DerivePartialModel {
|
||||
fn new(input: syn::DeriveInput) -> Result<Self, Error> {
|
||||
if !input.generics.params.is_empty() {
|
||||
return Err(Error::NotSupportGeneric(input.generics.params.span()));
|
||||
}
|
||||
|
||||
let syn::Data::Struct(syn::DataStruct{fields:syn::Fields::Named(syn::FieldsNamed{named:fields,..}),..},..)= input.data else{
|
||||
return Err(Error::InputNotStruct);
|
||||
};
|
||||
|
||||
let mut entity_ident = None;
|
||||
|
||||
for attr in input.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {
|
||||
for meta in list {
|
||||
entity_ident = meta
|
||||
.get_as_kv("entity")
|
||||
.map(|s| syn::parse_str::<syn::Ident>(&s).map_err(Error::Syn))
|
||||
.transpose()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut column_as_list = Vec::with_capacity(fields.len());
|
||||
|
||||
for field in fields {
|
||||
let field_span = field.span();
|
||||
|
||||
let mut from_col = None;
|
||||
let mut from_expr = None;
|
||||
|
||||
for attr in field.attrs.iter() {
|
||||
if !attr.path.is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
|
||||
{
|
||||
for meta in list.iter() {
|
||||
from_col = meta
|
||||
.get_as_kv("from_col")
|
||||
.map(|s| format_ident!("{}", s.to_upper_camel_case()));
|
||||
from_expr = meta
|
||||
.get_as_kv("from_expr")
|
||||
.map(|s| syn::parse_str::<Expr>(&s).map_err(Error::Syn))
|
||||
.transpose()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let field_name = field.ident.unwrap();
|
||||
|
||||
let col_as = match (from_col, from_expr) {
|
||||
(None, None) => {
|
||||
if entity_ident.is_none() {
|
||||
return Err(Error::EntityNotSpecific);
|
||||
}
|
||||
ColumnAs::Col(format_ident!(
|
||||
"{}",
|
||||
field_name.to_string().to_upper_camel_case()
|
||||
))
|
||||
}
|
||||
(None, Some(expr)) => ColumnAs::Expr {
|
||||
expr,
|
||||
field_name: field_name.to_string(),
|
||||
},
|
||||
(Some(col), None) => {
|
||||
if entity_ident.is_none() {
|
||||
return Err(Error::EntityNotSpecific);
|
||||
}
|
||||
|
||||
let field = field_name.to_string();
|
||||
ColumnAs::ColAlias { col, field }
|
||||
}
|
||||
(Some(_), Some(_)) => return Err(Error::BothFromColAndFromExpr(field_span)),
|
||||
};
|
||||
column_as_list.push(col_as);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
entity_ident,
|
||||
ident: input.ident,
|
||||
fields: column_as_list,
|
||||
})
|
||||
}
|
||||
|
||||
fn expand(&self) -> syn::Result<TokenStream> {
|
||||
Ok(self.impl_partial_model_trait())
|
||||
}
|
||||
|
||||
fn impl_partial_model_trait(&self) -> TokenStream {
|
||||
let select_ident = format_ident!("select");
|
||||
let DerivePartialModel {
|
||||
entity_ident,
|
||||
ident,
|
||||
fields,
|
||||
} = self;
|
||||
let select_col_code_gen = fields.iter().map(|col_as| match col_as {
|
||||
ColumnAs::Col(ident) => {
|
||||
let entity = entity_ident.as_ref().unwrap();
|
||||
let col_value = quote!( <#entity as sea_orm::EntityTrait>::Column:: #ident);
|
||||
quote!(let #select_ident = sea_orm::SelectColumns::select_column(#select_ident, #col_value);)
|
||||
},
|
||||
ColumnAs::ColAlias { col, field } => {
|
||||
let entity = entity_ident.as_ref().unwrap();
|
||||
let col_value = quote!( <#entity as sea_orm::EntityTrait>::Column:: #col);
|
||||
quote!(let #select_ident = sea_orm::SelectColumns::select_column_as(#select_ident, #col_value, #field);)
|
||||
},
|
||||
ColumnAs::Expr { expr, field_name } => {
|
||||
quote!(let #select_ident = sea_orm::SelectColumns::select_column_as(#select_ident, #expr, #field_name);)
|
||||
},
|
||||
});
|
||||
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl sea_orm::PartialModelTrait for #ident{
|
||||
fn select_cols<S: sea_orm::SelectColumns>(#select_ident: S) -> S{
|
||||
#(#select_col_code_gen)*
|
||||
#select_ident
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_derive_partial_model(input: syn::DeriveInput) -> syn::Result<TokenStream> {
|
||||
let ident_span = input.ident.span();
|
||||
|
||||
match DerivePartialModel::new(input) {
|
||||
Ok(partial_model) => partial_model.expand(),
|
||||
Err(Error::NotSupportGeneric(span)) => Ok(quote_spanned! {
|
||||
span => compile_error!("you can only derive `DerivePartialModel` on named struct");
|
||||
}),
|
||||
Err(Error::BothFromColAndFromExpr(span)) => Ok(quote_spanned! {
|
||||
span => compile_error!("you can only use one of `from_col` or `from_expr`");
|
||||
}),
|
||||
Err(Error::EntityNotSpecific) => Ok(quote_spanned! {
|
||||
ident_span => compile_error!("you need specific which entity you are using")
|
||||
}),
|
||||
Err(Error::InputNotStruct) => Ok(quote_spanned! {
|
||||
ident_span => compile_error!("you can only derive `DerivePartialModel` on named struct");
|
||||
}),
|
||||
Err(Error::Syn(err)) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
mod util {
|
||||
use syn::{Lit, Meta, MetaNameValue};
|
||||
|
||||
pub(super) trait GetAsKVMeta {
|
||||
fn get_as_kv(&self, k: &str) -> Option<String>;
|
||||
}
|
||||
|
||||
impl GetAsKVMeta for Meta {
|
||||
fn get_as_kv(&self, k: &str) -> Option<String> {
|
||||
let Meta::NameValue(MetaNameValue{path, lit:Lit::Str(lit), ..}) = self else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if path.is_ident(k) {
|
||||
Some(lit.value())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use quote::format_ident;
|
||||
use syn::DeriveInput;
|
||||
|
||||
use crate::derives::partial_model::ColumnAs;
|
||||
|
||||
use super::DerivePartialModel;
|
||||
|
||||
#[cfg(test)]
|
||||
type StdResult<T> = Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
#[cfg(test)]
|
||||
const CODE_SNIPPET: &str = r#"
|
||||
#[sea_orm(entity = "Entity")]
|
||||
struct PartialModel{
|
||||
default_field: i32,
|
||||
#[sea_orm(from_col = "bar")]
|
||||
alias_field: i32,
|
||||
#[sea_orm(from_expr = "Expr::val(1).add(1)")]
|
||||
expr_field : i32
|
||||
}
|
||||
"#;
|
||||
#[test]
|
||||
fn test_load_macro_input() -> StdResult<()> {
|
||||
let input = syn::parse_str::<DeriveInput>(CODE_SNIPPET)?;
|
||||
|
||||
let middle = DerivePartialModel::new(input).unwrap();
|
||||
|
||||
assert_eq!(middle.entity_ident, Some(format_ident!("Entity")));
|
||||
assert_eq!(middle.ident, format_ident!("PartialModel"));
|
||||
assert_eq!(middle.fields.len(), 3);
|
||||
assert_eq!(
|
||||
middle.fields[0],
|
||||
ColumnAs::Col(format_ident!("DefaultField"))
|
||||
);
|
||||
assert_eq!(
|
||||
middle.fields[1],
|
||||
ColumnAs::ColAlias {
|
||||
col: format_ident!("Bar"),
|
||||
field: "alias_field".to_string()
|
||||
},
|
||||
);
|
||||
assert_eq!(
|
||||
middle.fields[2],
|
||||
ColumnAs::Expr {
|
||||
expr: syn::parse_str("Expr::val(1).add(1)").unwrap(),
|
||||
field_name: "expr_field".to_string()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
use syn::{parse_macro_input, DeriveInput, Error};
|
||||
|
||||
#[cfg(feature = "derive")]
|
||||
@ -677,6 +678,80 @@ pub fn derive_from_json_query_result(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
/// The DerivePartialModel derive macro will implement `sea_orm::PartialModelTrait` for simplify partial model queries.
|
||||
///
|
||||
/// ## Usage
|
||||
///
|
||||
/// ```rust
|
||||
/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
|
||||
/// use serde::{Deserialize, Serialize};
|
||||
///
|
||||
/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
|
||||
/// #[sea_orm(table_name = "posts")]
|
||||
/// pub struct Model {
|
||||
/// #[sea_orm(primary_key)]
|
||||
/// pub id: i32,
|
||||
/// pub title: String,
|
||||
/// #[sea_orm(column_type = "Text")]
|
||||
/// pub text: String,
|
||||
/// }
|
||||
/// # #[derive(Copy, Clone, Debug, EnumIter)]
|
||||
/// # pub enum Relation {}
|
||||
/// #
|
||||
/// # impl RelationTrait for Relation {
|
||||
/// # fn def(&self) -> RelationDef {
|
||||
/// # panic!("No Relation");
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl ActiveModelBehavior for ActiveModel {}
|
||||
///
|
||||
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
|
||||
/// #[sea_orm(entity = "Entity")]
|
||||
/// struct SelectResult {
|
||||
/// title: String,
|
||||
/// #[sea_orm(from_col = "text")]
|
||||
/// content: String,
|
||||
/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
|
||||
/// sum: i32,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If all fields in the partial model is `from_expr`, the `entity` can be ignore.
|
||||
/// ```
|
||||
/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
|
||||
///
|
||||
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
|
||||
/// struct SelectResult {
|
||||
/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
|
||||
/// sum: i32,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// A field cannot have attributes `from_col` and `from_expr` at the same time.
|
||||
/// Or, it will result in a compile error.
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use sea_orm::{entity::prelude::*, FromQueryResult, DerivePartialModel, sea_query::Expr};
|
||||
///
|
||||
/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
|
||||
/// #[sea_orm(entity = "Entity")]
|
||||
/// struct SelectResult {
|
||||
/// #[sea_orm(from_expr = "Expr::val(1).add(1)", from_col = "foo")]
|
||||
/// sum: i32
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(feature = "derive")]
|
||||
#[proc_macro_derive(DerivePartialModel, attributes(sea_orm))]
|
||||
pub fn derive_partial_model(input: TokenStream) -> TokenStream {
|
||||
let derive_input = parse_macro_input!(input);
|
||||
|
||||
match derives::expand_derive_partial_model(derive_input) {
|
||||
Ok(token_stream) => token_stream.into(),
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "derive")]
|
||||
#[proc_macro_attribute]
|
||||
|
@ -103,6 +103,7 @@ mod column;
|
||||
mod identity;
|
||||
mod link;
|
||||
mod model;
|
||||
mod partial_model;
|
||||
/// Re-export common types from the entity
|
||||
pub mod prelude;
|
||||
mod primary_key;
|
||||
@ -115,6 +116,7 @@ pub use column::*;
|
||||
pub use identity::*;
|
||||
pub use link::*;
|
||||
pub use model::*;
|
||||
pub use partial_model::*;
|
||||
// pub use prelude::*;
|
||||
pub use primary_key::*;
|
||||
pub use relation::*;
|
||||
|
7
src/entity/partial_model.rs
Normal file
7
src/entity/partial_model.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::{FromQueryResult, SelectColumns};
|
||||
|
||||
/// A trait for a part of [Model](super::model::ModelTrait)
|
||||
pub trait PartialModelTrait: FromQueryResult {
|
||||
/// Select specific columns this [PartialModel] needs
|
||||
fn select_cols<S: SelectColumns>(select: S) -> S;
|
||||
}
|
@ -2,8 +2,8 @@ pub use crate::{
|
||||
error::*, sea_query::BlobSize, ActiveEnum, ActiveModelBehavior, ActiveModelTrait, ColumnDef,
|
||||
ColumnTrait, ColumnType, ColumnTypeTrait, ConnectionTrait, CursorTrait, DatabaseConnection,
|
||||
DbConn, EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked,
|
||||
LoaderTrait, ModelTrait, PaginatorTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter,
|
||||
QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||
LoaderTrait, ModelTrait, PaginatorTrait, PartialModelTrait, PrimaryKeyToColumn,
|
||||
PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||
};
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
error::*, ConnectionTrait, EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait,
|
||||
PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo, SelectTwoMany, Statement,
|
||||
StreamTrait, TryGetableMany,
|
||||
PartialModelTrait, PrimaryKeyToColumn, QueryResult, QuerySelect, Select, SelectA, SelectB,
|
||||
SelectTwo, SelectTwoMany, Statement, StreamTrait, TryGetableMany,
|
||||
};
|
||||
use futures::{Stream, TryStreamExt};
|
||||
use sea_query::SelectStatement;
|
||||
@ -154,6 +154,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)
|
||||
pub fn into_partial_model<M>(self) -> Selector<SelectModel<M>>
|
||||
where
|
||||
M: PartialModelTrait,
|
||||
{
|
||||
M::select_cols(crate::QuerySelect::select_only(self)).into_model::<M>()
|
||||
}
|
||||
|
||||
/// Get a selectable Model as a [JsonValue] for SQL JSON operations
|
||||
#[cfg(feature = "with-json")]
|
||||
pub fn into_json(self) -> Selector<SelectModel<JsonValue>> {
|
||||
@ -416,6 +424,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a conversion into a [SelectTwoModel] with [PartialModel](PartialModelTrait)
|
||||
pub fn into_partial_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>
|
||||
where
|
||||
M: PartialModelTrait,
|
||||
N: PartialModelTrait,
|
||||
{
|
||||
let select = crate::QuerySelect::select_only(self);
|
||||
let select = M::select_cols(select);
|
||||
let select = N::select_cols(select);
|
||||
select.into_model::<M, N>()
|
||||
}
|
||||
|
||||
/// Convert the Models into JsonValue
|
||||
#[cfg(feature = "with-json")]
|
||||
pub fn into_json(self) -> Selector<SelectTwoModel<JsonValue, JsonValue>> {
|
||||
@ -469,6 +489,17 @@ where
|
||||
selector: SelectTwoModel { model: PhantomData },
|
||||
}
|
||||
}
|
||||
/// Performs a conversion to [Selector] with partial model
|
||||
fn into_partial_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>
|
||||
where
|
||||
M: PartialModelTrait,
|
||||
N: PartialModelTrait,
|
||||
{
|
||||
let select = self.select_only();
|
||||
let select = M::select_cols(select);
|
||||
let select = N::select_cols(select);
|
||||
select.into_model()
|
||||
}
|
||||
|
||||
/// Convert the results to JSON
|
||||
#[cfg(feature = "with-json")]
|
||||
@ -490,6 +521,19 @@ where
|
||||
self.into_model().stream(db).await
|
||||
}
|
||||
|
||||
/// Stream the result of the operation with PartialModel
|
||||
pub async fn stream_partial_model<'a: 'b, 'b, C, M, N>(
|
||||
self,
|
||||
db: &'a C,
|
||||
) -> Result<impl Stream<Item = Result<(M, Option<N>), DbErr>> + 'b + Send, DbErr>
|
||||
where
|
||||
C: ConnectionTrait + StreamTrait + Send,
|
||||
M: PartialModelTrait + Send + 'b,
|
||||
N: PartialModelTrait + Send + 'b,
|
||||
{
|
||||
self.into_partial_model().stream(db).await
|
||||
}
|
||||
|
||||
/// Get all Models from the select operation
|
||||
///
|
||||
/// > `SelectTwoMany::one()` method has been dropped (#486)
|
||||
|
@ -350,8 +350,8 @@ pub use schema::*;
|
||||
pub use sea_orm_macros::{
|
||||
DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn,
|
||||
DeriveCustomColumn, DeriveEntity, DeriveEntityModel, DeriveIntoActiveModel,
|
||||
DeriveMigrationName, DeriveModel, DerivePrimaryKey, DeriveRelation, FromJsonQueryResult,
|
||||
FromQueryResult,
|
||||
DeriveMigrationName, DeriveModel, DerivePartialModel, DerivePrimaryKey, DeriveRelation,
|
||||
FromJsonQueryResult, FromQueryResult,
|
||||
};
|
||||
|
||||
pub use sea_query;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{DbBackend, Statement};
|
||||
use crate::{ColumnTrait, DbBackend, IntoIdentity, IntoSimpleExpr, QuerySelect, Statement};
|
||||
use sea_query::QueryStatementBuilder;
|
||||
|
||||
/// A Trait for any type performing queries on a Model or ActiveModel
|
||||
@ -55,3 +55,36 @@ pub trait QueryTrait {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Select specific column for partial model queries
|
||||
pub trait SelectColumns {
|
||||
/// Add a select column
|
||||
///
|
||||
/// For more detail, please visit [QuerySelect::column]
|
||||
fn select_column<C: ColumnTrait>(self, col: C) -> Self;
|
||||
|
||||
/// Add a select column with alias
|
||||
///
|
||||
/// For more detail, please visit [QuerySelect::column_as]
|
||||
fn select_column_as<C, I>(self, col: C, alias: I) -> Self
|
||||
where
|
||||
C: IntoSimpleExpr,
|
||||
I: IntoIdentity;
|
||||
}
|
||||
|
||||
impl<S> SelectColumns for S
|
||||
where
|
||||
S: QuerySelect,
|
||||
{
|
||||
fn select_column<C: ColumnTrait>(self, col: C) -> Self {
|
||||
QuerySelect::column(self, col)
|
||||
}
|
||||
|
||||
fn select_column_as<C, I>(self, col: C, alias: I) -> Self
|
||||
where
|
||||
C: IntoSimpleExpr,
|
||||
I: IntoIdentity,
|
||||
{
|
||||
QuerySelect::column_as(self, col, alias)
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,100 @@
|
||||
use sea_orm::{FromQueryResult, TryGetable};
|
||||
mod from_query_result {
|
||||
use sea_orm::{FromQueryResult, TryGetable};
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct SimpleTest {
|
||||
#[derive(FromQueryResult)]
|
||||
struct SimpleTest {
|
||||
_foo: i32,
|
||||
_bar: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct GenericTest<T> {
|
||||
#[derive(FromQueryResult)]
|
||||
struct GenericTest<T> {
|
||||
_foo: i32,
|
||||
_bar: T,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct DoubleGenericTest<T, F> {
|
||||
#[derive(FromQueryResult)]
|
||||
struct DoubleGenericTest<T, F> {
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct BoundsGenericTest<T: Copy + Clone + 'static> {
|
||||
#[derive(FromQueryResult)]
|
||||
struct BoundsGenericTest<T: Copy + Clone + 'static> {
|
||||
_foo: T,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct WhereGenericTest<T>
|
||||
where
|
||||
#[derive(FromQueryResult)]
|
||||
struct WhereGenericTest<T>
|
||||
where
|
||||
T: Copy + Clone + 'static,
|
||||
{
|
||||
{
|
||||
_foo: T,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {
|
||||
#[derive(FromQueryResult)]
|
||||
struct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {
|
||||
_foo: T,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct MixedGenericTest<T: Clone, F>
|
||||
where
|
||||
#[derive(FromQueryResult)]
|
||||
struct MixedGenericTest<T: Clone, F>
|
||||
where
|
||||
F: Copy + Clone + 'static,
|
||||
{
|
||||
{
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
}
|
||||
|
||||
mod partial_model {
|
||||
use entity::{Column, Entity};
|
||||
use sea_orm::{ColumnTrait, DerivePartialModel, FromQueryResult};
|
||||
use sea_query::Expr;
|
||||
mod entity {
|
||||
use sea_orm::{
|
||||
ActiveModelBehavior, DeriveEntityModel, DerivePrimaryKey, DeriveRelation, EntityTrait,
|
||||
EnumIter, PrimaryKeyTrait,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "foo_table")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
id: i32,
|
||||
foo: i32,
|
||||
bar: String,
|
||||
foo2: bool,
|
||||
bar2: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, DeriveRelation, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult, DerivePartialModel)]
|
||||
#[sea_orm(entity = "Entity")]
|
||||
struct SimpleTest {
|
||||
_foo: i32,
|
||||
_bar: String,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult, DerivePartialModel)]
|
||||
#[sea_orm(entity = "Entity")]
|
||||
struct FieldFromDiffNameColumnTest {
|
||||
#[sea_orm(from_col = "foo2")]
|
||||
_foo: i32,
|
||||
#[sea_orm(from_col = "bar2")]
|
||||
_bar: String,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult, DerivePartialModel)]
|
||||
struct FieldFromExpr {
|
||||
#[sea_orm(from_expr = "Column::Bar2.sum()")]
|
||||
_foo: f64,
|
||||
#[sea_orm(from_expr = "Expr::col(Column::Id).equals(Column::Foo)")]
|
||||
_bar: bool,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user