sea_orm/executor/
select.rs

1use super::{
2    consolidate_query_result, consolidate_query_result_chain, consolidate_query_result_tee,
3};
4use crate::{
5    ConnectionTrait, DbBackend, EntityTrait, FromQueryResult, IdenStatic, PartialModelTrait,
6    QueryResult, QuerySelect, Select, SelectA, SelectB, SelectTwo, SelectTwoMany, Statement,
7    StreamTrait, TryGetableMany, error::*,
8};
9use futures_util::{Stream, TryStreamExt};
10use sea_query::SelectStatement;
11use std::{marker::PhantomData, pin::Pin};
12
13mod five;
14mod four;
15mod six;
16mod three;
17
18#[cfg(feature = "with-json")]
19use crate::JsonValue;
20
21/// Defines a type to do `SELECT` operations through a [SelectStatement] on a Model
22#[derive(Clone, Debug)]
23pub struct Selector<S>
24where
25    S: SelectorTrait,
26{
27    pub(crate) query: SelectStatement,
28    selector: PhantomData<S>,
29}
30
31/// Performs a raw `SELECT` operation on a model
32#[derive(Clone, Debug)]
33pub struct SelectorRaw<S>
34where
35    S: SelectorTrait,
36{
37    pub(crate) stmt: Statement,
38    pub(super) selector: PhantomData<S>,
39}
40
41/// A Trait for any type that can perform SELECT queries
42pub trait SelectorTrait {
43    #[allow(missing_docs)]
44    type Item: Sized;
45
46    /// The method to perform a query on a Model
47    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr>;
48}
49
50/// Get tuple from query result based on a list of column identifiers
51#[derive(Debug)]
52pub struct SelectGetableValue<T, C>
53where
54    T: TryGetableMany,
55    C: strum::IntoEnumIterator + sea_query::Iden,
56{
57    columns: PhantomData<C>,
58    model: PhantomData<T>,
59}
60
61/// Get tuple from query result based on column index
62#[derive(Debug)]
63pub struct SelectGetableTuple<T>
64where
65    T: TryGetableMany,
66{
67    model: PhantomData<T>,
68}
69
70/// Helper class to handle query result for 1 Model
71#[derive(Debug)]
72pub struct SelectModel<M>
73where
74    M: FromQueryResult,
75{
76    model: PhantomData<M>,
77}
78
79/// Helper class to handle query result for 2 Models
80#[derive(Clone, Debug)]
81pub struct SelectTwoModel<M, N>
82where
83    M: FromQueryResult,
84    N: FromQueryResult,
85{
86    model: PhantomData<(M, N)>,
87}
88
89/// Helper class to handle query result for 3 Models
90#[derive(Clone, Debug)]
91pub struct SelectThreeModel<M, N, O>
92where
93    M: FromQueryResult,
94    N: FromQueryResult,
95    O: FromQueryResult,
96{
97    model: PhantomData<(M, N, O)>,
98}
99
100/// Helper class to handle query result for 4 Models
101#[derive(Clone, Debug)]
102pub struct SelectFourModel<M, N, O, P>
103where
104    M: FromQueryResult,
105    N: FromQueryResult,
106    O: FromQueryResult,
107    P: FromQueryResult,
108{
109    model: PhantomData<(M, N, O, P)>,
110}
111
112/// Helper class to handle query result for 5 Models
113#[derive(Clone, Debug)]
114pub struct SelectFiveModel<M, N, O, P, Q>
115where
116    M: FromQueryResult,
117    N: FromQueryResult,
118    O: FromQueryResult,
119    P: FromQueryResult,
120    Q: FromQueryResult,
121{
122    model: PhantomData<(M, N, O, P, Q)>,
123}
124
125/// Helper class to handle query result for 6 Models
126#[derive(Clone, Debug)]
127pub struct SelectSixModel<M, N, O, P, Q, R>
128where
129    M: FromQueryResult,
130    N: FromQueryResult,
131    O: FromQueryResult,
132    P: FromQueryResult,
133    Q: FromQueryResult,
134    R: FromQueryResult,
135{
136    model: PhantomData<(M, N, O, P, Q, R)>,
137}
138
139impl<T, C> Default for SelectGetableValue<T, C>
140where
141    T: TryGetableMany,
142    C: strum::IntoEnumIterator + sea_query::Iden,
143{
144    fn default() -> Self {
145        Self {
146            columns: PhantomData,
147            model: PhantomData,
148        }
149    }
150}
151
152impl<T, C> SelectorTrait for SelectGetableValue<T, C>
153where
154    T: TryGetableMany,
155    C: strum::IntoEnumIterator + sea_query::Iden,
156{
157    type Item = T;
158
159    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
160        let cols: Vec<String> = C::iter().map(|col| col.to_string()).collect();
161        T::try_get_many(&res, "", &cols).map_err(Into::into)
162    }
163}
164
165impl<T> SelectorTrait for SelectGetableTuple<T>
166where
167    T: TryGetableMany,
168{
169    type Item = T;
170
171    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
172        T::try_get_many_by_index(&res).map_err(Into::into)
173    }
174}
175
176impl<M> SelectorTrait for SelectModel<M>
177where
178    M: FromQueryResult + Sized,
179{
180    type Item = M;
181
182    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
183        M::from_query_result(&res, "")
184    }
185}
186
187impl<M, N> SelectorTrait for SelectTwoModel<M, N>
188where
189    M: FromQueryResult + Sized,
190    N: FromQueryResult + Sized,
191{
192    type Item = (M, Option<N>);
193
194    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
195        Ok((
196            M::from_query_result(&res, SelectA.as_str())?,
197            N::from_query_result_optional(&res, SelectB.as_str())?,
198        ))
199    }
200}
201
202impl<E> Select<E>
203where
204    E: EntityTrait,
205{
206    /// Perform a Select operation on a Model using a [Statement]
207    #[allow(clippy::wrong_self_convention)]
208    pub fn from_raw_sql(self, stmt: Statement) -> SelectorRaw<SelectModel<E::Model>> {
209        SelectorRaw {
210            stmt,
211            selector: PhantomData,
212        }
213    }
214
215    /// Return a [Selector] from `Self` that wraps a [SelectModel]
216    pub fn into_model<M>(self) -> Selector<SelectModel<M>>
217    where
218        M: FromQueryResult,
219    {
220        Selector {
221            query: self.query,
222            selector: PhantomData,
223        }
224    }
225
226    /// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)
227    ///
228    /// ```
229    /// # #[cfg(feature = "macros")]
230    /// # {
231    /// use sea_orm::{
232    ///     entity::*,
233    ///     query::*,
234    ///     tests_cfg::cake::{self, Entity as Cake},
235    ///     DbBackend, DerivePartialModel,
236    /// };
237    /// use sea_query::{Expr, Func, SimpleExpr};
238    ///
239    /// #[derive(DerivePartialModel)]
240    /// #[sea_orm(entity = "Cake")]
241    /// struct PartialCake {
242    ///     name: String,
243    ///     #[sea_orm(
244    ///         from_expr = r#"SimpleExpr::FunctionCall(Func::upper(Expr::col((Cake, cake::Column::Name))))"#
245    ///     )]
246    ///     name_upper: String,
247    /// }
248    ///
249    /// assert_eq!(
250    ///     cake::Entity::find()
251    ///         .into_partial_model::<PartialCake>()
252    ///         .into_statement(DbBackend::Sqlite)
253    ///         .to_string(),
254    ///     r#"SELECT "cake"."name" AS "name", UPPER("cake"."name") AS "name_upper" FROM "cake""#
255    /// );
256    /// # }
257    /// ```
258    pub fn into_partial_model<M>(self) -> Selector<SelectModel<M>>
259    where
260        M: PartialModelTrait,
261    {
262        M::select_cols(QuerySelect::select_only(self)).into_model::<M>()
263    }
264
265    /// Get a selectable Model as a [JsonValue] for SQL JSON operations
266    #[cfg(feature = "with-json")]
267    pub fn into_json(self) -> Selector<SelectModel<JsonValue>> {
268        Selector {
269            query: self.query,
270            selector: PhantomData,
271        }
272    }
273
274    /// ```
275    /// # use sea_orm::{error::*, tests_cfg::*, *};
276    /// #
277    /// # #[smol_potat::main]
278    /// # #[cfg(all(feature = "mock", feature = "macros"))]
279    /// # pub async fn main() -> Result<(), DbErr> {
280    /// #
281    /// # let db = MockDatabase::new(DbBackend::Postgres)
282    /// #     .append_query_results([[
283    /// #         maplit::btreemap! {
284    /// #             "cake_name" => Into::<Value>::into("Chocolate Forest"),
285    /// #         },
286    /// #         maplit::btreemap! {
287    /// #             "cake_name" => Into::<Value>::into("New York Cheese"),
288    /// #         },
289    /// #     ]])
290    /// #     .into_connection();
291    /// #
292    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};
293    ///
294    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
295    /// enum QueryAs {
296    ///     CakeName,
297    /// }
298    ///
299    /// let res: Vec<String> = cake::Entity::find()
300    ///     .select_only()
301    ///     .column_as(cake::Column::Name, QueryAs::CakeName)
302    ///     .into_values::<_, QueryAs>()
303    ///     .all(&db)
304    ///     .await?;
305    ///
306    /// assert_eq!(
307    ///     res,
308    ///     ["Chocolate Forest".to_owned(), "New York Cheese".to_owned()]
309    /// );
310    ///
311    /// assert_eq!(
312    ///     db.into_transaction_log(),
313    ///     [Transaction::from_sql_and_values(
314    ///         DbBackend::Postgres,
315    ///         r#"SELECT "cake"."name" AS "cake_name" FROM "cake""#,
316    ///         []
317    ///     )]
318    /// );
319    /// #
320    /// # Ok(())
321    /// # }
322    /// ```
323    ///
324    /// ```
325    /// # use sea_orm::{error::*, tests_cfg::*, *};
326    /// #
327    /// # #[smol_potat::main]
328    /// # #[cfg(all(feature = "mock", feature = "macros"))]
329    /// # pub async fn main() -> Result<(), DbErr> {
330    /// #
331    /// # let db = MockDatabase::new(DbBackend::Postgres)
332    /// #     .append_query_results([[
333    /// #         maplit::btreemap! {
334    /// #             "cake_name" => Into::<Value>::into("Chocolate Forest"),
335    /// #             "num_of_cakes" => Into::<Value>::into(2i64),
336    /// #         },
337    /// #     ]])
338    /// #     .into_connection();
339    /// #
340    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};
341    ///
342    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
343    /// enum QueryAs {
344    ///     CakeName,
345    ///     NumOfCakes,
346    /// }
347    ///
348    /// let res: Vec<(String, i64)> = cake::Entity::find()
349    ///     .select_only()
350    ///     .column_as(cake::Column::Name, QueryAs::CakeName)
351    ///     .column_as(cake::Column::Id.count(), QueryAs::NumOfCakes)
352    ///     .group_by(cake::Column::Name)
353    ///     .into_values::<_, QueryAs>()
354    ///     .all(&db)
355    ///     .await?;
356    ///
357    /// assert_eq!(res, [("Chocolate Forest".to_owned(), 2i64)]);
358    ///
359    /// assert_eq!(
360    ///     db.into_transaction_log(),
361    ///     [Transaction::from_sql_and_values(
362    ///         DbBackend::Postgres,
363    ///         [
364    ///             r#"SELECT "cake"."name" AS "cake_name", COUNT("cake"."id") AS "num_of_cakes""#,
365    ///             r#"FROM "cake" GROUP BY "cake"."name""#,
366    ///         ]
367    ///         .join(" ")
368    ///         .as_str(),
369    ///         []
370    ///     )]
371    /// );
372    /// #
373    /// # Ok(())
374    /// # }
375    /// ```
376    pub fn into_values<T, C>(self) -> Selector<SelectGetableValue<T, C>>
377    where
378        T: TryGetableMany,
379        C: strum::IntoEnumIterator + sea_query::Iden,
380    {
381        Selector {
382            query: self.query,
383            selector: PhantomData,
384        }
385    }
386
387    /// ```
388    /// # use sea_orm::{error::*, tests_cfg::*, *};
389    /// #
390    /// # #[smol_potat::main]
391    /// # #[cfg(all(feature = "mock", feature = "macros"))]
392    /// # pub async fn main() -> Result<(), DbErr> {
393    /// #
394    /// # let db = MockDatabase::new(DbBackend::Postgres)
395    /// #     .append_query_results(vec![vec![
396    /// #         maplit::btreemap! {
397    /// #             "cake_name" => Into::<Value>::into("Chocolate Forest"),
398    /// #         },
399    /// #         maplit::btreemap! {
400    /// #             "cake_name" => Into::<Value>::into("New York Cheese"),
401    /// #         },
402    /// #     ]])
403    /// #     .into_connection();
404    /// #
405    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
406    ///
407    /// let res: Vec<String> = cake::Entity::find()
408    ///     .select_only()
409    ///     .column(cake::Column::Name)
410    ///     .into_tuple()
411    ///     .all(&db)
412    ///     .await?;
413    ///
414    /// assert_eq!(
415    ///     res,
416    ///     vec!["Chocolate Forest".to_owned(), "New York Cheese".to_owned()]
417    /// );
418    ///
419    /// assert_eq!(
420    ///     db.into_transaction_log(),
421    ///     vec![Transaction::from_sql_and_values(
422    ///         DbBackend::Postgres,
423    ///         r#"SELECT "cake"."name" FROM "cake""#,
424    ///         vec![]
425    ///     )]
426    /// );
427    /// #
428    /// # Ok(())
429    /// # }
430    /// ```
431    ///
432    /// ```
433    /// # use sea_orm::{error::*, tests_cfg::*, *};
434    /// #
435    /// # #[smol_potat::main]
436    /// # #[cfg(all(feature = "mock", feature = "macros"))]
437    /// # pub async fn main() -> Result<(), DbErr> {
438    /// #
439    /// # let db = MockDatabase::new(DbBackend::Postgres)
440    /// #     .append_query_results(vec![vec![
441    /// #         maplit::btreemap! {
442    /// #             "cake_name" => Into::<Value>::into("Chocolate Forest"),
443    /// #             "num_of_cakes" => Into::<Value>::into(2i64),
444    /// #         },
445    /// #     ]])
446    /// #     .into_connection();
447    /// #
448    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
449    ///
450    /// let res: Vec<(String, i64)> = cake::Entity::find()
451    ///     .select_only()
452    ///     .column(cake::Column::Name)
453    ///     .column(cake::Column::Id)
454    ///     .group_by(cake::Column::Name)
455    ///     .into_tuple()
456    ///     .all(&db)
457    ///     .await?;
458    ///
459    /// assert_eq!(res, vec![("Chocolate Forest".to_owned(), 2i64)]);
460    ///
461    /// assert_eq!(
462    ///     db.into_transaction_log(),
463    ///     vec![Transaction::from_sql_and_values(
464    ///         DbBackend::Postgres,
465    ///         vec![
466    ///             r#"SELECT "cake"."name", "cake"."id""#,
467    ///             r#"FROM "cake" GROUP BY "cake"."name""#,
468    ///         ]
469    ///         .join(" ")
470    ///         .as_str(),
471    ///         vec![]
472    ///     )]
473    /// );
474    /// #
475    /// # Ok(())
476    /// # }
477    /// ```
478    pub fn into_tuple<T>(self) -> Selector<SelectGetableTuple<T>>
479    where
480        T: TryGetableMany,
481    {
482        Selector {
483            query: self.query,
484            selector: PhantomData,
485        }
486    }
487
488    /// Get one Model from the SELECT query
489    pub async fn one<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>
490    where
491        C: ConnectionTrait,
492    {
493        self.into_model().one(db).await
494    }
495
496    /// Get all Models from the SELECT query
497    pub async fn all<C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>
498    where
499        C: ConnectionTrait,
500    {
501        self.into_model().all(db).await
502    }
503
504    /// Stream the results of a SELECT operation on a Model
505    pub async fn stream<'a: 'b, 'b, C>(
506        self,
507        db: &'a C,
508    ) -> Result<impl Stream<Item = Result<E::Model, DbErr>> + 'b + Send, DbErr>
509    where
510        C: ConnectionTrait + StreamTrait + Send,
511    {
512        self.into_model().stream(db).await
513    }
514
515    /// Stream the result of the operation with PartialModel
516    pub async fn stream_partial_model<'a: 'b, 'b, C, M>(
517        self,
518        db: &'a C,
519    ) -> Result<impl Stream<Item = Result<M, DbErr>> + 'b + Send, DbErr>
520    where
521        C: ConnectionTrait + StreamTrait + Send,
522        M: PartialModelTrait + Send + 'b,
523    {
524        self.into_partial_model().stream(db).await
525    }
526}
527
528impl<E, F> SelectTwo<E, F>
529where
530    E: EntityTrait,
531    F: EntityTrait,
532{
533    /// Perform a conversion into a [SelectTwoModel]
534    pub fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>
535    where
536        M: FromQueryResult,
537        N: FromQueryResult,
538    {
539        Selector {
540            query: self.query,
541            selector: PhantomData,
542        }
543    }
544
545    /// Perform a conversion into a [SelectTwoModel] with [PartialModel](PartialModelTrait)
546    pub fn into_partial_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>
547    where
548        M: PartialModelTrait,
549        N: PartialModelTrait,
550    {
551        let select = QuerySelect::select_only(self);
552        let select = M::select_cols(select);
553        let select = N::select_cols(select);
554        select.into_model::<M, N>()
555    }
556
557    /// Convert the Models into JsonValue
558    #[cfg(feature = "with-json")]
559    pub fn into_json(self) -> Selector<SelectTwoModel<JsonValue, JsonValue>> {
560        Selector {
561            query: self.query,
562            selector: PhantomData,
563        }
564    }
565
566    /// Get one Model from the Select query
567    pub async fn one<C>(self, db: &C) -> Result<Option<(E::Model, Option<F::Model>)>, DbErr>
568    where
569        C: ConnectionTrait,
570    {
571        self.into_model().one(db).await
572    }
573
574    /// Get all Models from the Select query
575    pub async fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Option<F::Model>)>, DbErr>
576    where
577        C: ConnectionTrait,
578    {
579        self.into_model().all(db).await
580    }
581
582    /// Stream the results of a Select operation on a Model
583    pub async fn stream<'a: 'b, 'b, C>(
584        self,
585        db: &'a C,
586    ) -> Result<impl Stream<Item = Result<(E::Model, Option<F::Model>), DbErr>> + 'b, DbErr>
587    where
588        C: ConnectionTrait + StreamTrait + Send,
589    {
590        self.into_model().stream(db).await
591    }
592
593    /// Stream the result of the operation with PartialModel
594    pub async fn stream_partial_model<'a: 'b, 'b, C, M, N>(
595        self,
596        db: &'a C,
597    ) -> Result<impl Stream<Item = Result<(M, Option<N>), DbErr>> + 'b + Send, DbErr>
598    where
599        C: ConnectionTrait + StreamTrait + Send,
600        M: PartialModelTrait + Send + 'b,
601        N: PartialModelTrait + Send + 'b,
602    {
603        self.into_partial_model().stream(db).await
604    }
605}
606
607impl<E, F> SelectTwoMany<E, F>
608where
609    E: EntityTrait,
610    F: EntityTrait,
611{
612    /// Performs a conversion to [Selector]
613    fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>
614    where
615        M: FromQueryResult,
616        N: FromQueryResult,
617    {
618        Selector {
619            query: self.query,
620            selector: PhantomData,
621        }
622    }
623
624    /// Get all Models from the select operation and consolidate result based on left Model.
625    ///
626    /// > `SelectTwoMany::one()` method has been dropped (#486)
627    /// >
628    /// > You can get `(Entity, Vec<relatedEntity>)` by first querying a single model from Entity,
629    /// > then use [`ModelTrait::find_related`] on the model.
630    /// >
631    /// > See https://www.sea-ql.org/SeaORM/docs/basic-crud/select#lazy-loading for details.
632    pub async fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Vec<F::Model>)>, DbErr>
633    where
634        C: ConnectionTrait,
635    {
636        let rows = self.into_model().all(db).await?;
637        Ok(consolidate_query_result::<E, F>(rows))
638    }
639
640    // pub fn paginate()
641    // we could not implement paginate easily, if the number of children for a
642    // parent is larger than one page, then we will end up splitting it in two pages
643    // so the correct way is actually perform query in two stages
644    // paginate the parent model and then populate the children
645
646    // pub fn count()
647    // we should only count the number of items of the parent model
648}
649
650impl<S> Selector<S>
651where
652    S: SelectorTrait,
653{
654    /// Get the SQL statement
655    pub fn into_statement(self, builder: DbBackend) -> Statement {
656        builder.build(&self.query)
657    }
658
659    /// Get an item from the Select query
660    pub async fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>
661    where
662        C: ConnectionTrait,
663    {
664        self.query.limit(1);
665        let row = db.query_one(&self.query).await?;
666        match row {
667            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
668            None => Ok(None),
669        }
670    }
671
672    /// Get all items from the Select query
673    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>
674    where
675        C: ConnectionTrait,
676    {
677        let rows = db.query_all(&self.query).await?;
678        let mut models = Vec::new();
679        for row in rows.into_iter() {
680            models.push(S::from_raw_query_result(row)?);
681        }
682        Ok(models)
683    }
684
685    /// Stream the results of the Select operation
686    pub async fn stream<'a: 'b, 'b, C>(
687        self,
688        db: &'a C,
689    ) -> Result<Pin<Box<dyn Stream<Item = Result<S::Item, DbErr>> + 'b + Send>>, DbErr>
690    where
691        C: ConnectionTrait + StreamTrait + Send,
692        S: 'b,
693        S::Item: Send,
694    {
695        let stream = db.stream(&self.query).await?;
696        Ok(Box::pin(stream.and_then(|row| {
697            futures_util::future::ready(S::from_raw_query_result(row))
698        })))
699    }
700}
701
702impl<S> SelectorRaw<S>
703where
704    S: SelectorTrait,
705{
706    /// Select a custom Model from a raw SQL [Statement].
707    pub fn from_statement<M>(stmt: Statement) -> SelectorRaw<SelectModel<M>>
708    where
709        M: FromQueryResult,
710    {
711        SelectorRaw {
712            stmt,
713            selector: PhantomData,
714        }
715    }
716
717    /// ```
718    /// # use sea_orm::{error::*, tests_cfg::*, *};
719    /// #
720    /// # #[smol_potat::main]
721    /// # #[cfg(feature = "mock")]
722    /// # pub async fn main() -> Result<(), DbErr> {
723    /// #
724    /// # let db = MockDatabase::new(DbBackend::Postgres)
725    /// #     .append_query_results([[
726    /// #         maplit::btreemap! {
727    /// #             "name" => Into::<Value>::into("Chocolate Forest"),
728    /// #             "num_of_cakes" => Into::<Value>::into(1),
729    /// #         },
730    /// #         maplit::btreemap! {
731    /// #             "name" => Into::<Value>::into("New York Cheese"),
732    /// #             "num_of_cakes" => Into::<Value>::into(1),
733    /// #         },
734    /// #     ]])
735    /// #     .into_connection();
736    /// #
737    /// use sea_orm::{FromQueryResult, entity::*, query::*, tests_cfg::cake};
738    ///
739    /// #[derive(Debug, PartialEq, FromQueryResult)]
740    /// struct SelectResult {
741    ///     name: String,
742    ///     num_of_cakes: i32,
743    /// }
744    ///
745    /// let res: Vec<SelectResult> = cake::Entity::find()
746    ///     .from_raw_sql(Statement::from_sql_and_values(
747    ///         DbBackend::Postgres,
748    ///         r#"SELECT "cake"."name", count("cake"."id") AS "num_of_cakes" FROM "cake""#,
749    ///         [],
750    ///     ))
751    ///     .into_model::<SelectResult>()
752    ///     .all(&db)
753    ///     .await?;
754    ///
755    /// assert_eq!(
756    ///     res,
757    ///     [
758    ///         SelectResult {
759    ///             name: "Chocolate Forest".to_owned(),
760    ///             num_of_cakes: 1,
761    ///         },
762    ///         SelectResult {
763    ///             name: "New York Cheese".to_owned(),
764    ///             num_of_cakes: 1,
765    ///         },
766    ///     ]
767    /// );
768    ///
769    /// assert_eq!(
770    ///     db.into_transaction_log(),
771    ///     [Transaction::from_sql_and_values(
772    ///         DbBackend::Postgres,
773    ///         r#"SELECT "cake"."name", count("cake"."id") AS "num_of_cakes" FROM "cake""#,
774    ///         []
775    ///     ),]
776    /// );
777    /// #
778    /// # Ok(())
779    /// # }
780    /// ```
781    pub fn into_model<M>(self) -> SelectorRaw<SelectModel<M>>
782    where
783        M: FromQueryResult,
784    {
785        SelectorRaw {
786            stmt: self.stmt,
787            selector: PhantomData,
788        }
789    }
790
791    /// ```
792    /// # use sea_orm::{error::*, tests_cfg::*, *};
793    /// #
794    /// # #[smol_potat::main]
795    /// # #[cfg(feature = "mock")]
796    /// # pub async fn main() -> Result<(), DbErr> {
797    /// #
798    /// # let db = MockDatabase::new(DbBackend::Postgres)
799    /// #     .append_query_results([[
800    /// #         maplit::btreemap! {
801    /// #             "name" => Into::<Value>::into("Chocolate Forest"),
802    /// #             "num_of_cakes" => Into::<Value>::into(1),
803    /// #         },
804    /// #         maplit::btreemap! {
805    /// #             "name" => Into::<Value>::into("New York Cheese"),
806    /// #             "num_of_cakes" => Into::<Value>::into(1),
807    /// #         },
808    /// #     ]])
809    /// #     .into_connection();
810    /// #
811    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
812    ///
813    /// let res: Vec<serde_json::Value> = cake::Entity::find().from_raw_sql(
814    ///     Statement::from_sql_and_values(
815    ///         DbBackend::Postgres, r#"SELECT "cake"."id", "cake"."name" FROM "cake""#, []
816    ///     )
817    /// )
818    /// .into_json()
819    /// .all(&db)
820    /// .await?;
821    ///
822    /// assert_eq!(
823    ///     res,
824    ///     [
825    ///         serde_json::json!({
826    ///             "name": "Chocolate Forest",
827    ///             "num_of_cakes": 1,
828    ///         }),
829    ///         serde_json::json!({
830    ///             "name": "New York Cheese",
831    ///             "num_of_cakes": 1,
832    ///         }),
833    ///     ]
834    /// );
835    ///
836    /// assert_eq!(
837    ///     db.into_transaction_log(),
838    ///     [
839    ///     Transaction::from_sql_and_values(
840    ///             DbBackend::Postgres, r#"SELECT "cake"."id", "cake"."name" FROM "cake""#, []
841    ///     ),
842    /// ]);
843    /// #
844    /// # Ok(())
845    /// # }
846    /// ```
847    #[cfg(feature = "with-json")]
848    pub fn into_json(self) -> SelectorRaw<SelectModel<JsonValue>> {
849        SelectorRaw {
850            stmt: self.stmt,
851            selector: PhantomData,
852        }
853    }
854
855    /// Get the SQL statement
856    pub fn into_statement(self) -> Statement {
857        self.stmt
858    }
859
860    /// Get an item from the Select query
861    /// ```
862    /// # use sea_orm::{error::*, tests_cfg::*, *};
863    /// #
864    /// # #[smol_potat::main]
865    /// # #[cfg(feature = "mock")]
866    /// # pub async fn main() -> Result<(), DbErr> {
867    /// #
868    /// # let db = MockDatabase::new(DbBackend::Postgres)
869    /// #     .append_query_results([
870    /// #         [cake::Model {
871    /// #             id: 1,
872    /// #             name: "Cake".to_owned(),
873    /// #         }],
874    /// #     ])
875    /// #     .into_connection();
876    /// #
877    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};
878    ///
879    /// let id = 1;
880    ///
881    /// let _: Option<cake::Model> = cake::Entity::find()
882    ///     .from_raw_sql(raw_sql!(
883    ///         Postgres,
884    ///         r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE "id" = {id}"#
885    ///     ))
886    ///     .one(&db)
887    ///     .await?;
888    ///
889    /// assert_eq!(
890    ///     db.into_transaction_log(),
891    ///     [Transaction::from_sql_and_values(
892    ///         DbBackend::Postgres,
893    ///         r#"SELECT "cake"."id", "cake"."name" FROM "cake" WHERE "id" = $1"#,
894    ///         [1.into()]
895    ///     ),]
896    /// );
897    /// #
898    /// # Ok(())
899    /// # }
900    /// ```
901    pub async fn one<C>(self, db: &C) -> Result<Option<S::Item>, DbErr>
902    where
903        C: ConnectionTrait,
904    {
905        let row = db.query_one_raw(self.stmt).await?;
906        match row {
907            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),
908            None => Ok(None),
909        }
910    }
911
912    /// Get all items from the Select query
913    /// ```
914    /// # use sea_orm::{error::*, tests_cfg::*, *};
915    /// #
916    /// # #[smol_potat::main]
917    /// # #[cfg(feature = "mock")]
918    /// # pub async fn main() -> Result<(), DbErr> {
919    /// #
920    /// # let db = MockDatabase::new(DbBackend::Postgres)
921    /// #     .append_query_results([
922    /// #         [cake::Model {
923    /// #             id: 1,
924    /// #             name: "Cake".to_owned(),
925    /// #         }],
926    /// #     ])
927    /// #     .into_connection();
928    /// #
929    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};
930    ///
931    /// let _: Vec<cake::Model> = cake::Entity::find()
932    ///     .from_raw_sql(raw_sql!(
933    ///         Postgres,
934    ///         r#"SELECT "cake"."id", "cake"."name" FROM "cake""#
935    ///     ))
936    ///     .all(&db)
937    ///     .await?;
938    ///
939    /// assert_eq!(
940    ///     db.into_transaction_log(),
941    ///     [Transaction::from_sql_and_values(
942    ///         DbBackend::Postgres,
943    ///         r#"SELECT "cake"."id", "cake"."name" FROM "cake""#,
944    ///         []
945    ///     ),]
946    /// );
947    /// #
948    /// # Ok(())
949    /// # }
950    /// ```
951    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>
952    where
953        C: ConnectionTrait,
954    {
955        let rows = db.query_all_raw(self.stmt).await?;
956        let mut models = Vec::new();
957        for row in rows.into_iter() {
958            models.push(S::from_raw_query_result(row)?);
959        }
960        Ok(models)
961    }
962
963    /// Stream the results of the Select operation
964    pub async fn stream<'a: 'b, 'b, C>(
965        self,
966        db: &'a C,
967    ) -> Result<Pin<Box<dyn Stream<Item = Result<S::Item, DbErr>> + 'b + Send>>, DbErr>
968    where
969        C: ConnectionTrait + StreamTrait + Send,
970        S: 'b,
971        S::Item: Send,
972    {
973        let stream = db.stream_raw(self.stmt).await?;
974        Ok(Box::pin(stream.and_then(|row| {
975            futures_util::future::ready(S::from_raw_query_result(row))
976        })))
977    }
978}