#48: Select model from raw sql

This commit is contained in:
Chris Tsang 2021-07-16 21:41:12 +08:00
parent 57097c0ede
commit c82b23795d

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
error::*, query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable, error::*, query::combine, DatabaseConnection, EntityTrait, FromQueryResult, Iterable,
JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectTwo, JsonValue, ModelTrait, Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectTwo,
SelectTwoMany, SelectTwoMany, Statement,
}; };
use sea_query::SelectStatement; use sea_query::SelectStatement;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -15,6 +15,15 @@ where
selector: S, selector: S,
} }
#[derive(Clone, Debug)]
pub struct SelectorRaw<S>
where
S: SelectorTrait,
{
stmt: Statement,
selector: S,
}
pub trait SelectorTrait { pub trait SelectorTrait {
type Item: Sized; type Item: Sized;
@ -67,6 +76,13 @@ impl<E> Select<E>
where where
E: EntityTrait, E: EntityTrait,
{ {
pub fn from_raw_sql(stmt: Statement) -> SelectorRaw<SelectModel<E::Model>> {
SelectorRaw {
stmt,
selector: SelectModel { model: PhantomData },
}
}
pub fn into_model<M>(self) -> Selector<SelectModel<M>> pub fn into_model<M>(self) -> Selector<SelectModel<M>>
where where
M: FromQueryResult, M: FromQueryResult,
@ -216,6 +232,28 @@ where
} }
} }
impl<S> SelectorRaw<S>
where
S: SelectorTrait,
{
pub async fn one(self, db: &DatabaseConnection) -> Result<Option<S::Item>, DbErr> {
let row = db.query_one(self.stmt).await?;
match row {
Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
None => Ok(None),
}
}
pub async fn all(self, db: &DatabaseConnection) -> Result<Vec<S::Item>, DbErr> {
let rows = db.query_all(self.stmt).await?;
let mut models = Vec::new();
for row in rows.into_iter() {
models.push(S::from_raw_query_result(row)?);
}
Ok(models)
}
}
fn consolidate_query_result<L, R>( fn consolidate_query_result<L, R>(
rows: Vec<(L::Model, Option<R::Model>)>, rows: Vec<(L::Model, Option<R::Model>)>,
) -> Vec<(L::Model, Vec<R::Model>)> ) -> Vec<(L::Model, Vec<R::Model>)>