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