siderite_orm/queryset/
rows.rs1use super::QuerySet;
5use super::fetch::{is_flat, unordered};
6use crate::backend::Row;
7use crate::decode::FromValues;
8use crate::error::{OrmError, QueryError};
9use crate::expr::Expr;
10use crate::model::Model;
11use crate::plan::{QueryPlan, SelectExpr};
12
13impl<M: Model> QuerySet<M> {
14 #[must_use]
23 pub fn project<S: Into<SelectExpr>>(mut self, fields: impl IntoIterator<Item = S>) -> Self {
24 let projection: Vec<SelectExpr> = fields
25 .into_iter()
26 .map(|field| {
27 let mut field: SelectExpr = field.into();
28 field.expr = self.resolve(field.expr);
29 field
30 })
31 .collect();
32 if self.default_ordering {
33 self.default_ordering = false;
34 self.plan.ordering.clear();
35 }
36 self.with_plan(|mut plan| {
37 plan.projection = projection;
38 plan
39 })
40 }
41
42 pub async fn rows(self) -> Result<Vec<Row>, OrmError> {
47 self.ready()?;
48 if self.empty {
49 return Ok(Vec::new());
50 }
51 Ok(self.db.fetch(&self.plan).await?.rows)
52 }
53
54 pub async fn values<S: Into<SelectExpr>>(
59 self,
60 fields: impl IntoIterator<Item = S>,
61 ) -> Result<Vec<Row>, OrmError> {
62 self.project(fields).rows().await
63 }
64
65 pub async fn values_list<T: FromValues, S: Into<SelectExpr>>(
72 self,
73 fields: impl IntoIterator<Item = S>,
74 ) -> Result<Vec<T>, OrmError> {
75 let rows = self.values(fields).await?;
76 Ok(rows.iter().map(T::from_values).collect::<Result<_, _>>()?)
77 }
78
79 pub async fn aggregate<S: Into<SelectExpr>>(
88 self,
89 aggregates: impl IntoIterator<Item = S>,
90 ) -> Result<Row, OrmError> {
91 self.ready()?;
92 let projection: Vec<SelectExpr> = aggregates
93 .into_iter()
94 .map(|a| {
95 let mut a: SelectExpr = a.into();
96 a.expr = self.resolve(a.expr);
97 a
98 })
99 .collect();
100 let mut plan = if is_flat(&self.plan) {
101 unordered(&self.plan)
102 } else {
103 QueryPlan::from_subquery(unordered(&self.plan), "aggregated")
104 };
105 if self.empty {
106 plan.filter = Some(Expr::Or(Vec::new()));
107 }
108 plan.projection = projection;
109 plan.grouping.clear();
110 plan.having = None;
111 let result = self.db.fetch(&plan.resolve_relations()).await?;
112 result.rows.into_iter().next().ok_or_else(|| {
113 QueryError::Decode {
114 column: "aggregate".into(),
115 reason: "no row returned".into(),
116 }
117 .into()
118 })
119 }
120
121 #[must_use]
124 pub fn subquery(self, field: impl Into<SelectExpr>) -> QueryPlan {
125 let qs = self.project([field]);
126 let mut plan = unordered(&qs.plan);
127 plan.origin = Some(qs.db.origin());
128 plan
129 }
130
131 #[must_use]
134 pub fn exists_expr(self) -> Expr {
135 let mut plan = unordered(&self.plan);
136 plan.projection = vec![SelectExpr::new(Expr::val(1), None)];
137 plan.origin = Some(self.db.origin());
138 Expr::exists(plan)
139 }
140}