From 9107c9010a45ddc1f931b5df77489b788fefc277 Mon Sep 17 00:00:00 2001 From: Muhannad Alrusayni Date: Thu, 16 Sep 2021 11:47:31 +0300 Subject: [PATCH] add `into_model()` for `Statement` --- src/database/statement.rs | 71 ++++++++++++++++++++++++++++++++++++++- src/executor/select.rs | 14 ++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/database/statement.rs b/src/database/statement.rs index 12b07487..530325c4 100644 --- a/src/database/statement.rs +++ b/src/database/statement.rs @@ -1,4 +1,4 @@ -use crate::DbBackend; +use crate::{DbBackend, FromQueryResult, SelectModel, SelectorRaw}; use sea_query::{inject_parameters, MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder}; pub use sea_query::{Value, Values}; use std::fmt; @@ -43,6 +43,75 @@ impl Statement { db_backend, } } + + /// ``` + /// # #[cfg(feature = "mock")] + /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend}; + /// # + /// # let db = MockDatabase::new(DbBackend::Postgres) + /// # .append_query_results(vec![vec![ + /// # maplit::btreemap! { + /// # "name" => Into::::into("Chocolate Forest"), + /// # "num_of_cakes" => Into::::into(1), + /// # }, + /// # maplit::btreemap! { + /// # "name" => Into::::into("New York Cheese"), + /// # "num_of_cakes" => Into::::into(1), + /// # }, + /// # ]]) + /// # .into_connection(); + /// # + /// use sea_orm::{entity::*, query::*, tests_cfg::cake, FromQueryResult}; + /// + /// #[derive(Debug, PartialEq, FromQueryResult)] + /// struct SelectResult { + /// name: String, + /// num_of_cakes: i32, + /// } + /// + /// # let _: Result<(), DbErr> = smol::block_on(async { + /// # + /// let res: Vec = Statement::from_sql_and_values( + /// DbBackend::Postgres, + /// r#"SELECT "cake"."name", count("cake"."id") AS "num_of_cakes" FROM "cake""#, + /// vec![], + /// ) + /// .into_model::() + /// .all(&db) + /// .await?; + /// + /// assert_eq!( + /// res, + /// vec![ + /// SelectResult { + /// name: "Chocolate Forest".to_owned(), + /// num_of_cakes: 1, + /// }, + /// SelectResult { + /// name: "New York Cheese".to_owned(), + /// num_of_cakes: 1, + /// }, + /// ] + /// ); + /// # + /// # Ok(()) + /// # }); + /// + /// assert_eq!( + /// db.into_transaction_log(), + /// vec![Transaction::from_sql_and_values( + /// DbBackend::Postgres, + /// r#"SELECT "cake"."name", count("cake"."id") AS "num_of_cakes" FROM "cake""#, + /// vec![] + /// ),] + /// ); + /// ``` + pub fn into_model(self) -> SelectorRaw> + where + M: FromQueryResult, + { + SelectorRaw::>::from_statement(self) + } } impl fmt::Display for Statement { diff --git a/src/executor/select.rs b/src/executor/select.rs index ef30bb3d..961ec37b 100644 --- a/src/executor/select.rs +++ b/src/executor/select.rs @@ -263,6 +263,20 @@ impl SelectorRaw where S: SelectorTrait, { + // Create `SelectorRaw` from Statment. Executing this `SelectorRaw` will + // return a type `M` which implement `FromQueryResult`. + // + // Helper function used by `Statment.into_model()` + pub(crate) fn from_statement(stmt: Statement) -> SelectorRaw> + where + M: FromQueryResult, + { + SelectorRaw { + stmt, + selector: SelectModel { model: PhantomData }, + } + } + /// ``` /// # #[cfg(feature = "mock")] /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};