icydb_core/db/query/session/
load.rs1use crate::{
2 db::{
3 DbSession,
4 query::{
5 Query, QueryError,
6 expr::{FilterExpr, SortExpr},
7 plan::{ExecutablePlan, ExplainPlan},
8 predicate::Predicate,
9 },
10 response::Response,
11 },
12 traits::{CanisterKind, EntityKind, EntityValue, SingletonEntity},
13 types::Id,
14};
15
16pub struct SessionLoadQuery<'a, C, E>
25where
26 C: CanisterKind,
27 E: EntityKind<Canister = C>,
28{
29 session: &'a DbSession<C>,
30 query: Query<E>,
31}
32
33impl<'a, C, E> SessionLoadQuery<'a, C, E>
34where
35 C: CanisterKind,
36 E: EntityKind<Canister = C>,
37{
38 pub(crate) const fn new(session: &'a DbSession<C>, query: Query<E>) -> Self {
39 Self { session, query }
40 }
41
42 #[must_use]
47 pub const fn query(&self) -> &Query<E> {
48 &self.query
49 }
50
51 #[must_use]
59 pub fn by_id(mut self, id: Id<E>) -> Self {
60 self.query = self.query.by_id(id.key());
61 self
62 }
63
64 #[must_use]
68 pub fn by_ids<I>(mut self, ids: I) -> Self
69 where
70 I: IntoIterator<Item = Id<E>>,
71 {
72 self.query = self.query.by_ids(ids.into_iter().map(|id| id.key()));
73 self
74 }
75
76 #[must_use]
81 pub fn filter(mut self, predicate: Predicate) -> Self {
82 self.query = self.query.filter(predicate);
83 self
84 }
85
86 pub fn filter_expr(mut self, expr: FilterExpr) -> Result<Self, QueryError> {
87 self.query = self.query.filter_expr(expr)?;
88 Ok(self)
89 }
90
91 pub fn sort_expr(mut self, expr: SortExpr) -> Result<Self, QueryError> {
92 self.query = self.query.sort_expr(expr)?;
93 Ok(self)
94 }
95
96 #[must_use]
97 pub fn order_by(mut self, field: impl AsRef<str>) -> Self {
98 self.query = self.query.order_by(field);
99 self
100 }
101
102 #[must_use]
103 pub fn order_by_desc(mut self, field: impl AsRef<str>) -> Self {
104 self.query = self.query.order_by_desc(field);
105 self
106 }
107
108 #[must_use]
113 pub fn limit(mut self, limit: u32) -> Self {
114 self.query = self.query.limit(limit);
115 self
116 }
117
118 #[must_use]
123 pub fn offset(mut self, offset: u32) -> Self {
124 self.query = self.query.offset(offset);
125 self
126 }
127
128 pub fn explain(&self) -> Result<ExplainPlan, QueryError> {
133 self.query.explain()
134 }
135
136 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
137 self.query.plan()
138 }
139
140 pub fn execute(&self) -> Result<Response<E>, QueryError>
146 where
147 E: EntityValue,
148 {
149 self.session.execute_query(self.query())
150 }
151
152 pub fn is_empty(&self) -> Result<bool, QueryError>
158 where
159 E: EntityValue,
160 {
161 Ok(self.execute()?.is_empty())
162 }
163
164 pub fn count(&self) -> Result<u32, QueryError>
166 where
167 E: EntityValue,
168 {
169 Ok(self.execute()?.count())
170 }
171
172 pub fn require_one(&self) -> Result<(), QueryError>
174 where
175 E: EntityValue,
176 {
177 self.execute()?.require_one().map_err(QueryError::Response)
178 }
179
180 pub fn require_some(&self) -> Result<(), QueryError>
182 where
183 E: EntityValue,
184 {
185 self.execute()?.require_some().map_err(QueryError::Response)
186 }
187}
188
189impl<C, E> SessionLoadQuery<'_, C, E>
190where
191 C: CanisterKind,
192 E: EntityKind<Canister = C> + SingletonEntity,
193 E::Key: Default,
194{
195 #[must_use]
196 pub fn only(mut self) -> Self {
197 self.query = self.query.only();
198 self
199 }
200}