Derive FromQueryResult
This commit is contained in:
parent
07b58551af
commit
106bb20cb5
@ -49,4 +49,4 @@ Balance between compile-time checking and compilation speed.
|
|||||||
|
|
||||||
3. Avoid 'symbol soup'
|
3. Avoid 'symbol soup'
|
||||||
|
|
||||||
Avoid procedural macro if possible, use derive macro where appropriate.
|
Avoid function-like macros with DSL, use derive macros where appropriate. Be friendly with IDE tools.
|
@ -26,6 +26,16 @@ pub enum Relation {
|
|||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EntityTrait for Entity {
|
||||||
|
type Model = Model;
|
||||||
|
|
||||||
|
type Column = Column;
|
||||||
|
|
||||||
|
type PrimaryKey = PrimaryKey;
|
||||||
|
|
||||||
|
type Relation = Relation;
|
||||||
|
}
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
@ -26,6 +26,16 @@ pub enum PrimaryKey {
|
|||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {}
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl EntityTrait for Entity {
|
||||||
|
type Model = Model;
|
||||||
|
|
||||||
|
type Column = Column;
|
||||||
|
|
||||||
|
type PrimaryKey = PrimaryKey;
|
||||||
|
|
||||||
|
type Relation = Relation;
|
||||||
|
}
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use sea_orm::{ColumnTrait, Database, EntityTrait, QueryErr, QueryHelper};
|
use sea_orm::{ColumnTrait, Database, EntityTrait, QueryErr, QueryHelper, FromQueryResult};
|
||||||
|
|
||||||
mod example_cake;
|
mod example_cake;
|
||||||
mod example_fruit;
|
mod example_fruit;
|
||||||
@ -104,26 +104,12 @@ async fn find_one(db: &Database) -> Result<(), QueryErr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
|
async fn count_fruits_by_cake(db: &Database) -> Result<(), QueryErr> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, FromQueryResult)]
|
||||||
struct SelectResult {
|
struct SelectResult {
|
||||||
name: String,
|
name: String,
|
||||||
num_of_fruits: i32,
|
num_of_fruits: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
// TODO: implement with derive macro
|
|
||||||
use sea_orm::{FromQueryResult, QueryResult, TypeErr};
|
|
||||||
|
|
||||||
impl FromQueryResult for SelectResult {
|
|
||||||
fn from_query_result(row: &QueryResult, pre: &str) -> Result<Self, TypeErr> {
|
|
||||||
Ok(Self {
|
|
||||||
name: row.try_get(pre, "name")?,
|
|
||||||
num_of_fruits: row.try_get(pre, "num_of_fruits")?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print!("count fruits by cake: ");
|
print!("count fruits by cake: ");
|
||||||
|
|
||||||
let select = cake::Entity::find()
|
let select = cake::Entity::find()
|
||||||
|
@ -39,15 +39,5 @@ pub fn expend_derive_entity(ident: Ident, attrs: Vec<Attribute>) -> syn::Result<
|
|||||||
write!(s, "{}", self.as_str()).unwrap();
|
write!(s, "{}", self.as_str()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntityTrait for #ident {
|
|
||||||
type Model = Model;
|
|
||||||
|
|
||||||
type Column = Column;
|
|
||||||
|
|
||||||
type PrimaryKey = PrimaryKey;
|
|
||||||
|
|
||||||
type Relation = Relation;
|
|
||||||
}
|
|
||||||
))
|
))
|
||||||
}
|
}
|
42
sea-orm-macros/src/derives/from_query_result.rs
Normal file
42
sea-orm-macros/src/derives/from_query_result.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use proc_macro2::{Ident, TokenStream};
|
||||||
|
use syn::{Data, DataStruct, Field, Fields};
|
||||||
|
use quote::{format_ident, quote, quote_spanned};
|
||||||
|
|
||||||
|
pub fn expend_derive_from_query_result(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
||||||
|
let fields = match data {
|
||||||
|
Data::Struct(DataStruct {
|
||||||
|
fields: Fields::Named(named),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
named.named
|
||||||
|
},
|
||||||
|
_ => return Ok(quote_spanned! {
|
||||||
|
ident.span() => compile_error!("you can only derive DeriveModel on structs");
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let field: Vec<Ident> = fields
|
||||||
|
.into_iter()
|
||||||
|
.map(|Field { ident, .. }| {
|
||||||
|
format_ident!("{}", ident.unwrap().to_string())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let name: Vec<TokenStream> = field
|
||||||
|
.iter()
|
||||||
|
.map(|f| {
|
||||||
|
let s = f.to_string();
|
||||||
|
quote! { #s }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(quote!(
|
||||||
|
impl sea_orm::FromQueryResult for #ident {
|
||||||
|
fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> Result<Self, sea_orm::TypeErr> {
|
||||||
|
Ok(Self {
|
||||||
|
#(#field: row.try_get(pre, #name)?),*
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
mod entity;
|
mod entity;
|
||||||
|
mod from_query_result;
|
||||||
mod primary_key;
|
mod primary_key;
|
||||||
mod column;
|
mod column;
|
||||||
mod model;
|
mod model;
|
||||||
|
|
||||||
pub use entity::*;
|
pub use entity::*;
|
||||||
|
pub use from_query_result::*;
|
||||||
pub use primary_key::*;
|
pub use primary_key::*;
|
||||||
pub use column::*;
|
pub use column::*;
|
||||||
pub use model::*;
|
pub use model::*;
|
@ -10,7 +10,7 @@ pub fn derive_entity(input: TokenStream) -> TokenStream {
|
|||||||
let DeriveInput {
|
let DeriveInput {
|
||||||
ident, attrs, ..
|
ident, attrs, ..
|
||||||
} = parse_macro_input!(input);
|
} = parse_macro_input!(input);
|
||||||
|
|
||||||
match derives::expend_derive_entity(ident, attrs) {
|
match derives::expend_derive_entity(ident, attrs) {
|
||||||
Ok(ts) => ts.into(),
|
Ok(ts) => ts.into(),
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -22,7 +22,7 @@ pub fn derive_primary_key(input: TokenStream) -> TokenStream {
|
|||||||
let DeriveInput {
|
let DeriveInput {
|
||||||
ident, data, ..
|
ident, data, ..
|
||||||
} = parse_macro_input!(input);
|
} = parse_macro_input!(input);
|
||||||
|
|
||||||
match derives::expend_derive_primary_key(ident, data) {
|
match derives::expend_derive_primary_key(ident, data) {
|
||||||
Ok(ts) => ts.into(),
|
Ok(ts) => ts.into(),
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -34,7 +34,7 @@ pub fn derive_column(input: TokenStream) -> TokenStream {
|
|||||||
let DeriveInput {
|
let DeriveInput {
|
||||||
ident, data, ..
|
ident, data, ..
|
||||||
} = parse_macro_input!(input);
|
} = parse_macro_input!(input);
|
||||||
|
|
||||||
match derives::expend_derive_column(ident, data) {
|
match derives::expend_derive_column(ident, data) {
|
||||||
Ok(ts) => ts.into(),
|
Ok(ts) => ts.into(),
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -46,9 +46,21 @@ pub fn derive_model(input: TokenStream) -> TokenStream {
|
|||||||
let DeriveInput {
|
let DeriveInput {
|
||||||
ident, data, ..
|
ident, data, ..
|
||||||
} = parse_macro_input!(input);
|
} = parse_macro_input!(input);
|
||||||
|
|
||||||
match derives::expend_derive_model(ident, data) {
|
match derives::expend_derive_model(ident, data) {
|
||||||
Ok(ts) => ts.into(),
|
Ok(ts) => ts.into(),
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(FromQueryResult)]
|
||||||
|
pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
|
||||||
|
let DeriveInput {
|
||||||
|
ident, data, ..
|
||||||
|
} = parse_macro_input!(input);
|
||||||
|
|
||||||
|
match derives::expend_derive_from_query_result(ident, data) {
|
||||||
|
Ok(ts) => ts.into(),
|
||||||
|
Err(e) => e.to_compile_error().into(),
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
ColumnTrait, ColumnType, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
ColumnTrait, ColumnType, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
||||||
PrimaryKeyOfModel, PrimaryKeyTrait, QueryResult, Related, RelationDef, RelationTrait, Select,
|
PrimaryKeyOfModel, PrimaryKeyTrait, QueryResult, Related, RelationDef, RelationTrait, Select,
|
||||||
TypeErr, Value, DeriveEntity, DerivePrimaryKey, DeriveColumn, DeriveModel,
|
TypeErr, Value, DeriveEntity, DerivePrimaryKey, DeriveColumn, DeriveModel
|
||||||
};
|
};
|
||||||
|
@ -20,4 +20,5 @@ pub use sea_orm_macros::{
|
|||||||
DerivePrimaryKey,
|
DerivePrimaryKey,
|
||||||
DeriveColumn,
|
DeriveColumn,
|
||||||
DeriveModel,
|
DeriveModel,
|
||||||
|
FromQueryResult,
|
||||||
};
|
};
|
||||||
|
@ -26,6 +26,16 @@ pub enum Relation {
|
|||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EntityTrait for Entity {
|
||||||
|
type Model = Model;
|
||||||
|
|
||||||
|
type Column = Column;
|
||||||
|
|
||||||
|
type PrimaryKey = PrimaryKey;
|
||||||
|
|
||||||
|
type Relation = Relation;
|
||||||
|
}
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
@ -26,6 +26,16 @@ pub enum PrimaryKey {
|
|||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {}
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl EntityTrait for Entity {
|
||||||
|
type Model = Model;
|
||||||
|
|
||||||
|
type Column = Column;
|
||||||
|
|
||||||
|
type PrimaryKey = PrimaryKey;
|
||||||
|
|
||||||
|
type Relation = Relation;
|
||||||
|
}
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user