icydb_core/db/query/
delete.rs

1use crate::{
2    db::{
3        primitives::{FilterExpr, FilterExt, FilterSlot, LimitExpr, LimitSlot},
4        query::{QueryError, QueryValidate},
5    },
6    traits::{EntityKind, FieldValue},
7};
8use candid::CandidType;
9use serde::{Deserialize, Serialize};
10
11///
12/// DeleteQuery
13///
14
15#[derive(CandidType, Clone, Debug, Default, Deserialize, Serialize)]
16pub struct DeleteQuery {
17    pub filter: Option<FilterExpr>,
18    pub limit: Option<LimitExpr>,
19}
20
21impl DeleteQuery {
22    // ─────────────────────────────────────────────
23    // CONSTRUCTORS
24    // ─────────────────────────────────────────────
25
26    /// Construct an empty delete query.
27    #[must_use]
28    pub fn new() -> Self {
29        Self::default()
30    }
31
32    // ─────────────────────────────────────────────
33    // ENTITY CONVENIENCE HELPERS
34    // ─────────────────────────────────────────────
35
36    /// Delete a single row by primary key value.
37    ///
38    /// Convenience wrapper; entity knowledge lives here only for ergonomics.
39    #[must_use]
40    pub fn one<E: EntityKind>(self, value: impl FieldValue) -> Self {
41        self.one_by_field(E::PRIMARY_KEY, value)
42    }
43
44    /// Delete a single row where the primary key is unit.
45    #[must_use]
46    pub fn only<E: EntityKind>(self) -> Self {
47        self.one_by_field(E::PRIMARY_KEY, ())
48    }
49
50    /// Delete multiple rows by an arbitrary field.
51    #[must_use]
52    pub fn many<E, I, V>(self, values: I) -> Self
53    where
54        E: EntityKind,
55        I: IntoIterator<Item = V>,
56        V: FieldValue,
57    {
58        self.filter(|f| f.in_iter(E::PRIMARY_KEY, values))
59    }
60
61    // ─────────────────────────────────────────────
62    // FIELD-BASED HELPERS (PRIMITIVES)
63    // ─────────────────────────────────────────────
64
65    /// Delete a single row by an arbitrary field value.
66    #[must_use]
67    pub fn one_by_field(self, field: impl AsRef<str>, value: impl FieldValue) -> Self {
68        self.filter(|f| f.eq(field, value))
69    }
70
71    /// Delete multiple rows by an arbitrary field.
72    #[must_use]
73    pub fn many_by_field<I, V>(self, field: impl AsRef<str>, values: I) -> Self
74    where
75        I: IntoIterator<Item = V>,
76        V: FieldValue,
77    {
78        self.filter(|f| f.in_iter(field, values))
79    }
80}
81
82// ─────────────────────────────────────────────
83// TRAIT IMPLEMENTATIONS
84// ─────────────────────────────────────────────
85
86impl FilterSlot for DeleteQuery {
87    fn filter_slot(&mut self) -> &mut Option<FilterExpr> {
88        &mut self.filter
89    }
90}
91
92impl LimitSlot for DeleteQuery {
93    fn limit_slot(&mut self) -> &mut Option<LimitExpr> {
94        &mut self.limit
95    }
96}
97
98impl<E: EntityKind> QueryValidate<E> for DeleteQuery {
99    fn validate(&self) -> Result<(), QueryError> {
100        if let Some(filter) = &self.filter {
101            QueryValidate::<E>::validate(filter)?;
102        }
103
104        if let Some(limit) = &self.limit {
105            QueryValidate::<E>::validate(limit)?;
106        }
107
108        Ok(())
109    }
110}