Revert SeaORM prelude
Add `stream_partial_model` to `Select<E>` and `SelectTwo<E,F>` Minor refactoring fmt Add `into_partial_model` to `Cursor<S>` refactoring Add test cases Fix test cases More test cases Move partial_model tests
This commit is contained in:
parent
744e063222
commit
e6b6629733
@ -43,7 +43,7 @@ impl DerivePartialModel {
|
||||
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{
|
||||
let syn::Data::Struct(syn::DataStruct{fields:syn::Fields::Named(syn::FieldsNamed{named:fields,..}),..},..) = input.data else{
|
||||
return Err(Error::InputNotStruct);
|
||||
};
|
||||
|
||||
|
@ -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, PartialModelTrait, PrimaryKeyToColumn,
|
||||
PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||
LoaderTrait, ModelTrait, PaginatorTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter,
|
||||
QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||
};
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Identity, IntoIdentity, QueryOrder,
|
||||
Select, SelectModel, SelectorTrait,
|
||||
ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Identity, IntoIdentity,
|
||||
PartialModelTrait, QueryOrder, QuerySelect, Select, SelectModel, SelectorTrait,
|
||||
};
|
||||
use sea_query::{
|
||||
Condition, DynIden, Expr, IntoValueTuple, Order, SeaRc, SelectStatement, SimpleExpr, Value,
|
||||
@ -234,6 +234,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)
|
||||
pub fn into_partial_model<M>(self) -> Cursor<SelectModel<M>>
|
||||
where
|
||||
M: PartialModelTrait,
|
||||
{
|
||||
M::select_cols(QuerySelect::select_only(self)).into_model::<M>()
|
||||
}
|
||||
|
||||
/// Construct a [Cursor] that fetch JSON value
|
||||
#[cfg(feature = "with-json")]
|
||||
pub fn into_json(self) -> Cursor<SelectModel<JsonValue>> {
|
||||
@ -247,6 +255,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> QuerySelect for Cursor<S>
|
||||
where
|
||||
S: SelectorTrait,
|
||||
{
|
||||
type QueryStatement = SelectStatement;
|
||||
|
||||
fn query(&mut self) -> &mut SelectStatement {
|
||||
&mut self.query
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> QueryOrder for Cursor<S>
|
||||
where
|
||||
S: SelectorTrait,
|
||||
|
@ -159,7 +159,7 @@ where
|
||||
where
|
||||
M: PartialModelTrait,
|
||||
{
|
||||
M::select_cols(crate::QuerySelect::select_only(self)).into_model::<M>()
|
||||
M::select_cols(QuerySelect::select_only(self)).into_model::<M>()
|
||||
}
|
||||
|
||||
/// Get a selectable Model as a [JsonValue] for SQL JSON operations
|
||||
@ -405,6 +405,18 @@ 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>(
|
||||
self,
|
||||
db: &'a C,
|
||||
) -> Result<impl Stream<Item = Result<M, DbErr>> + 'b + Send, DbErr>
|
||||
where
|
||||
C: ConnectionTrait + StreamTrait + Send,
|
||||
M: PartialModelTrait + Send + 'b,
|
||||
{
|
||||
self.into_partial_model().stream(db).await
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, F> SelectTwo<E, F>
|
||||
@ -430,7 +442,7 @@ where
|
||||
M: PartialModelTrait,
|
||||
N: PartialModelTrait,
|
||||
{
|
||||
let select = crate::QuerySelect::select_only(self);
|
||||
let select = QuerySelect::select_only(self);
|
||||
let select = M::select_cols(select);
|
||||
let select = N::select_cols(select);
|
||||
select.into_model::<M, N>()
|
||||
@ -471,6 +483,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
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, F> SelectTwoMany<E, F>
|
||||
@ -489,6 +514,7 @@ 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
|
||||
|
@ -2,7 +2,9 @@ pub mod common;
|
||||
|
||||
pub use common::{features::*, setup::*, TestContext};
|
||||
use pretty_assertions::assert_eq;
|
||||
use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection};
|
||||
use sea_orm::{
|
||||
entity::prelude::*, entity::*, DatabaseConnection, DerivePartialModel, FromQueryResult,
|
||||
};
|
||||
|
||||
#[sea_orm_macros::test]
|
||||
#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))]
|
||||
@ -11,6 +13,7 @@ async fn main() -> Result<(), DbErr> {
|
||||
create_tables(&ctx.db).await?;
|
||||
insert_collection(&ctx.db).await?;
|
||||
update_collection(&ctx.db).await?;
|
||||
select_collection(&ctx.db).await?;
|
||||
ctx.delete().await;
|
||||
|
||||
Ok(())
|
||||
@ -149,3 +152,27 @@ pub async fn update_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn select_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
use collection::*;
|
||||
|
||||
#[derive(DerivePartialModel, FromQueryResult, Debug, PartialEq)]
|
||||
#[sea_orm(entity = "Entity")]
|
||||
struct PartialSelectResult {
|
||||
name: String,
|
||||
}
|
||||
|
||||
let result = Entity::find_by_id(1)
|
||||
.into_partial_model::<PartialSelectResult>()
|
||||
.one(db)
|
||||
.await?;
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Some(PartialSelectResult {
|
||||
name: "Collection 1".into(),
|
||||
})
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ pub mod common;
|
||||
|
||||
pub use common::{features::*, setup::*, TestContext};
|
||||
use pretty_assertions::assert_eq;
|
||||
use sea_orm::{entity::prelude::*, FromQueryResult};
|
||||
use sea_orm::{entity::prelude::*, DerivePartialModel, FromQueryResult};
|
||||
use serde_json::json;
|
||||
|
||||
#[sea_orm_macros::test]
|
||||
@ -202,7 +202,7 @@ pub async fn cursor_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
|
||||
// Fetch custom struct
|
||||
|
||||
#[derive(FromQueryResult, Debug, PartialEq)]
|
||||
#[derive(FromQueryResult, Debug, PartialEq, Clone)]
|
||||
struct Row {
|
||||
id: i32,
|
||||
}
|
||||
@ -233,5 +233,44 @@ pub async fn cursor_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
[json!({ "id": 6 }), json!({ "id": 7 })]
|
||||
);
|
||||
|
||||
#[derive(DerivePartialModel, FromQueryResult, Debug, PartialEq, Clone)]
|
||||
#[sea_orm(entity = "Entity")]
|
||||
struct PartialRow {
|
||||
#[sea_orm(from_col = "id")]
|
||||
id: i32,
|
||||
#[sea_orm(from_expr = "sea_query::Expr::col(Column::Id).add(1000)")]
|
||||
id_shifted: i32,
|
||||
}
|
||||
|
||||
let mut cursor = cursor.into_partial_model::<PartialRow>();
|
||||
|
||||
assert_eq!(
|
||||
cursor.first(2).all(db).await?,
|
||||
[
|
||||
PartialRow {
|
||||
id: 6,
|
||||
id_shifted: 1006,
|
||||
},
|
||||
PartialRow {
|
||||
id: 7,
|
||||
id_shifted: 1007,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
cursor.first(3).all(db).await?,
|
||||
[
|
||||
PartialRow {
|
||||
id: 6,
|
||||
id_shifted: 1006,
|
||||
},
|
||||
PartialRow {
|
||||
id: 7,
|
||||
id_shifted: 1007,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,100 +1,58 @@
|
||||
mod from_query_result {
|
||||
use sea_orm::{FromQueryResult, TryGetable};
|
||||
use sea_orm::{FromQueryResult, TryGetable};
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct SimpleTest {
|
||||
_foo: i32,
|
||||
_bar: String,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct GenericTest<T> {
|
||||
_foo: i32,
|
||||
_bar: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct DoubleGenericTest<T, F> {
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct BoundsGenericTest<T: Copy + Clone + 'static> {
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct WhereGenericTest<T>
|
||||
where
|
||||
T: Copy + Clone + 'static,
|
||||
{
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct MixedGenericTest<T: Clone, F>
|
||||
where
|
||||
F: Copy + Clone + 'static,
|
||||
{
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
#[derive(FromQueryResult)]
|
||||
struct SimpleTest {
|
||||
_foo: i32,
|
||||
_bar: String,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
#[derive(FromQueryResult)]
|
||||
struct GenericTest<T: TryGetable> {
|
||||
_foo: i32,
|
||||
_bar: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct DoubleGenericTest<T: TryGetable, F: TryGetable> {
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct BoundsGenericTest<T: TryGetable + Copy + Clone + 'static> {
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct WhereGenericTest<T>
|
||||
where
|
||||
T: TryGetable + Copy + Clone + 'static,
|
||||
{
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {
|
||||
_foo: T,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct MixedGenericTest<T: TryGetable + Clone, F>
|
||||
where
|
||||
F: TryGetable + Copy + Clone + 'static,
|
||||
{
|
||||
_foo: T,
|
||||
_bar: F,
|
||||
}
|
||||
|
||||
trait MyTrait {
|
||||
type Item: TryGetable;
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult)]
|
||||
struct TraitAssociateTypeTest<T>
|
||||
where
|
||||
T: MyTrait,
|
||||
{
|
||||
_foo: T::Item,
|
||||
}
|
||||
|
47
tests/partial_model_tests.rs
Normal file
47
tests/partial_model_tests.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use entity::{Column, Entity};
|
||||
use sea_orm::{ColumnTrait, DerivePartialModel, FromQueryResult};
|
||||
use sea_query::Expr;
|
||||
|
||||
mod entity {
|
||||
use sea_orm::prelude::*;
|
||||
|
||||
#[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,
|
||||
}
|
@ -4,7 +4,8 @@ pub use chrono::offset::Utc;
|
||||
pub use common::{bakery_chain::*, setup::*, TestContext};
|
||||
pub use rust_decimal::prelude::*;
|
||||
pub use rust_decimal_macros::dec;
|
||||
pub use sea_orm::{entity::*, query::*, DbErr, FromQueryResult};
|
||||
pub use sea_orm::{entity::*, query::*, DbErr, DerivePartialModel, FromQueryResult};
|
||||
pub use sea_query::{Alias, Expr, Func, SimpleExpr};
|
||||
pub use uuid::Uuid;
|
||||
|
||||
// Run the test locally:
|
||||
@ -66,6 +67,7 @@ pub async fn left_join() {
|
||||
.filter(baker::Column::Name.contains("Baker 1"));
|
||||
|
||||
let result = select
|
||||
.clone()
|
||||
.into_model::<SelectResult>()
|
||||
.one(&ctx.db)
|
||||
.await
|
||||
@ -74,6 +76,28 @@ pub async fn left_join() {
|
||||
assert_eq!(result.name.as_str(), "Baker 1");
|
||||
assert_eq!(result.bakery_name, Some("SeaSide Bakery".to_string()));
|
||||
|
||||
#[derive(DerivePartialModel, FromQueryResult, Debug, PartialEq)]
|
||||
#[sea_orm(entity = "Baker")]
|
||||
struct PartialSelectResult {
|
||||
name: String,
|
||||
#[sea_orm(from_expr = "Expr::col((bakery::Entity, bakery::Column::Name))")]
|
||||
bakery_name: Option<String>,
|
||||
#[sea_orm(
|
||||
from_expr = r#"SimpleExpr::FunctionCall(Func::upper(Expr::col((bakery::Entity, bakery::Column::Name))))"#
|
||||
)]
|
||||
bakery_name_upper: Option<String>,
|
||||
}
|
||||
|
||||
let result = select
|
||||
.into_partial_model::<PartialSelectResult>()
|
||||
.one(&ctx.db)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(result.name.as_str(), "Baker 1");
|
||||
assert_eq!(result.bakery_name, Some("SeaSide Bakery".to_string()));
|
||||
assert_eq!(result.bakery_name_upper, Some("SEASIDE BAKERY".to_string()));
|
||||
|
||||
let select = baker::Entity::find()
|
||||
.left_join(bakery::Entity)
|
||||
.select_only()
|
||||
|
Loading…
x
Reference in New Issue
Block a user