icydb_core/db/query/fluent/
delete.rs1use crate::{
7 db::{
8 DbSession, PersistedRow,
9 predicate::Predicate,
10 query::{
11 api::ResponseCardinalityExt,
12 explain::ExplainPlan,
13 expr::{FilterExpr, SortExpr},
14 intent::{CompiledQuery, PlannedQuery, Query, QueryError},
15 trace::QueryTracePlan,
16 },
17 response::EntityResponse,
18 },
19 traits::{EntityKind, EntityValue, SingletonEntity},
20 types::Id,
21};
22
23pub struct FluentDeleteQuery<'a, E>
32where
33 E: EntityKind,
34{
35 session: &'a DbSession<E::Canister>,
36 query: Query<E>,
37}
38
39impl<'a, E> FluentDeleteQuery<'a, E>
40where
41 E: PersistedRow,
42{
43 pub(crate) const fn new(session: &'a DbSession<E::Canister>, query: Query<E>) -> Self {
44 Self { session, query }
45 }
46
47 #[must_use]
53 pub const fn query(&self) -> &Query<E> {
54 &self.query
55 }
56
57 fn map_query(mut self, map: impl FnOnce(Query<E>) -> Query<E>) -> Self {
58 self.query = map(self.query);
59 self
60 }
61
62 fn try_map_query(
63 mut self,
64 map: impl FnOnce(Query<E>) -> Result<Query<E>, QueryError>,
65 ) -> Result<Self, QueryError> {
66 self.query = map(self.query)?;
67 Ok(self)
68 }
69
70 #[must_use]
78 pub fn by_id(self, id: Id<E>) -> Self {
79 self.map_query(|query| query.by_id(id.key()))
80 }
81
82 #[must_use]
86 pub fn by_ids<I>(self, ids: I) -> Self
87 where
88 I: IntoIterator<Item = Id<E>>,
89 {
90 self.map_query(|query| query.by_ids(ids.into_iter().map(|id| id.key())))
91 }
92
93 #[must_use]
99 pub fn filter(self, predicate: Predicate) -> Self {
100 self.map_query(|query| query.filter(predicate))
101 }
102
103 pub fn filter_expr(self, expr: FilterExpr) -> Result<Self, QueryError> {
105 self.try_map_query(|query| query.filter_expr(expr))
106 }
107
108 pub fn sort_expr(self, expr: SortExpr) -> Result<Self, QueryError> {
110 self.try_map_query(|query| query.sort_expr(expr))
111 }
112
113 #[must_use]
115 pub fn order_by(self, field: impl AsRef<str>) -> Self {
116 self.map_query(|query| query.order_by(field))
117 }
118
119 #[must_use]
121 pub fn order_by_desc(self, field: impl AsRef<str>) -> Self {
122 self.map_query(|query| query.order_by_desc(field))
123 }
124
125 #[must_use]
127 pub fn limit(self, limit: u32) -> Self {
128 self.map_query(|query| query.limit(limit))
129 }
130
131 pub fn explain(&self) -> Result<ExplainPlan, QueryError> {
137 self.session
138 .explain_query_with_visible_indexes(self.query())
139 }
140
141 pub fn plan_hash_hex(&self) -> Result<String, QueryError> {
143 self.session
144 .query_plan_hash_hex_with_visible_indexes(self.query())
145 }
146
147 pub fn trace(&self) -> Result<QueryTracePlan, QueryError> {
149 self.session.trace_query(self.query())
150 }
151
152 pub fn planned(&self) -> Result<PlannedQuery<E>, QueryError> {
154 self.session
155 .planned_query_with_visible_indexes(self.query())
156 }
157
158 pub fn plan(&self) -> Result<CompiledQuery<E>, QueryError> {
160 self.session
161 .compile_query_with_visible_indexes(self.query())
162 }
163
164 pub fn execute(&self) -> Result<EntityResponse<E>, QueryError>
172 where
173 E: EntityValue,
174 {
175 self.session.execute_query(self.query())
176 }
177
178 #[doc(hidden)]
180 pub fn execute_count_only(&self) -> Result<u32, QueryError>
181 where
182 E: EntityValue,
183 {
184 self.session.execute_delete_count(self.query())
185 }
186
187 pub fn is_empty(&self) -> Result<bool, QueryError>
189 where
190 E: EntityValue,
191 {
192 Ok(self.execute()?.is_empty())
193 }
194
195 pub fn count(&self) -> Result<u32, QueryError>
197 where
198 E: EntityValue,
199 {
200 Ok(self.execute()?.count())
201 }
202
203 pub fn require_one(&self) -> Result<(), QueryError>
205 where
206 E: EntityValue,
207 {
208 self.execute()?.require_one()?;
209 Ok(())
210 }
211
212 pub fn require_some(&self) -> Result<(), QueryError>
214 where
215 E: EntityValue,
216 {
217 self.execute()?.require_some()?;
218 Ok(())
219 }
220}
221
222impl<E> FluentDeleteQuery<'_, E>
223where
224 E: PersistedRow + SingletonEntity,
225 E::Key: Default,
226{
227 #[must_use]
229 pub fn only(self) -> Self {
230 self.map_query(Query::only)
231 }
232}