use crate::query::combine; use crate::{ Connection, Database, EntityTrait, FromQueryResult, QueryErr, Select, SelectTwo, Statement, }; use sea_query::{QueryBuilder, SelectStatement}; use std::marker::PhantomData; #[cfg(feature = "with-json")] use super::select_json::{SelectJson, SelectTwoJson}; #[derive(Clone, Debug)] pub struct SelectModel where M: FromQueryResult, { query: SelectStatement, model: PhantomData, } #[derive(Clone, Debug)] pub struct SelectTwoModel where M: FromQueryResult, N: FromQueryResult, { query: SelectStatement, model: PhantomData<(M, N)>, } impl Select where E: EntityTrait, { pub fn into_model(self) -> SelectModel where M: FromQueryResult, { SelectModel { query: self.query, model: PhantomData, } } #[cfg(feature = "with-json")] pub fn as_json(self) -> SelectJson { SelectJson { query: self.query } } pub async fn one(self, db: &Database) -> Result { self.into_model::().one(db).await } pub async fn all(self, db: &Database) -> Result, QueryErr> { self.into_model::().all(db).await } } impl SelectTwo where E: EntityTrait, F: EntityTrait, { fn into_model(self) -> SelectTwoModel where M: FromQueryResult, N: FromQueryResult, { SelectTwoModel { query: self.query, model: PhantomData, } } #[cfg(feature = "with-json")] pub fn as_json(self) -> SelectTwoJson { SelectTwoJson { query: self.query } } pub async fn one(self, db: &Database) -> Result<(E::Model, F::Model), QueryErr> { self.into_model::().one(db).await } pub async fn all(self, db: &Database) -> Result, QueryErr> { self.into_model::().all(db).await } } impl SelectModel where M: FromQueryResult, { pub fn build(&self, builder: B) -> Statement where B: QueryBuilder, { self.query.build(builder).into() } pub async fn one(mut self, db: &Database) -> Result { let builder = db.get_query_builder_backend(); self.query.limit(1); let row = db.get_connection().query_one(self.build(builder)).await?; Ok(M::from_query_result(&row, "")?) } pub async fn all(self, db: &Database) -> Result, QueryErr> { let builder = db.get_query_builder_backend(); let rows = db.get_connection().query_all(self.build(builder)).await?; let mut models = Vec::new(); for row in rows.into_iter() { models.push(M::from_query_result(&row, "")?); } Ok(models) } } impl SelectTwoModel where M: FromQueryResult, N: FromQueryResult, { pub fn build(&self, builder: B) -> Statement where B: QueryBuilder, { self.query.build(builder).into() } pub async fn one(mut self, db: &Database) -> Result<(M, N), QueryErr> { let builder = db.get_query_builder_backend(); self.query.limit(1); let row = db.get_connection().query_one(self.build(builder)).await?; Ok(( M::from_query_result(&row, combine::SELECT_A)?, N::from_query_result(&row, combine::SELECT_B)?, )) } pub async fn all(self, db: &Database) -> Result, QueryErr> { let builder = db.get_query_builder_backend(); let rows = db.get_connection().query_all(self.build(builder)).await?; let mut models = Vec::new(); for row in rows.into_iter() { models.push(( M::from_query_result(&row, combine::SELECT_A)?, N::from_query_result(&row, combine::SELECT_B)?, )); } Ok(models) } }