icydb_core/db/query/
load.rs

1use crate::{
2    db::{
3        primitives::{FilterExpr, FilterSlot, LimitExpr, LimitSlot, SortExpr, SortSlot},
4        query::{QueryError, QueryValidate, prelude::*},
5    },
6    traits::{EntityKind, FieldValue},
7};
8use candid::CandidType;
9use serde::{Deserialize, Serialize};
10
11///
12/// LoadQuery
13///
14
15#[derive(CandidType, Clone, Debug, Default, Deserialize, Serialize)]
16pub struct LoadQuery {
17    pub filter: Option<FilterExpr>,
18    pub limit: Option<LimitExpr>,
19    pub sort: Option<SortExpr>,
20}
21
22impl LoadQuery {
23    /// Construct an empty load query.
24    #[must_use]
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    #[must_use]
30    pub const fn is_empty(&self) -> bool {
31        self.filter.is_none() && self.limit.is_none() && self.sort.is_none()
32    }
33
34    ///
35    /// CONSTRUCTORS
36    ///
37
38    /// Filter by a single primary key value.
39    #[must_use]
40    pub fn one<E: EntityKind>(self, value: impl FieldValue) -> Self {
41        self.filter(|f| f.eq(E::PRIMARY_KEY, value))
42    }
43
44    /// Filter by a set of primary key values.
45    #[must_use]
46    pub fn many<E: EntityKind>(self, values: impl IntoIterator<Item = impl FieldValue>) -> Self {
47        self.filter(move |f| f.in_iter(E::PRIMARY_KEY, values))
48    }
49
50    /// Read all rows (alias for `LoadQuery::default()`).
51    #[must_use]
52    pub fn all() -> Self {
53        Self::default()
54    }
55
56    ///
57    /// Convenience
58    ///
59
60    /// Set offset=0, limit=1 (useful for existence checks / fast-paths).
61    #[must_use]
62    pub fn limit_1(self) -> Self {
63        self.offset(0).limit(1)
64    }
65}
66
67impl FilterSlot for LoadQuery {
68    fn filter_slot(&mut self) -> &mut Option<FilterExpr> {
69        &mut self.filter
70    }
71}
72
73impl LimitSlot for LoadQuery {
74    fn limit_slot(&mut self) -> &mut Option<LimitExpr> {
75        &mut self.limit
76    }
77}
78
79impl SortSlot for LoadQuery {
80    fn sort_slot(&mut self) -> &mut Option<SortExpr> {
81        &mut self.sort
82    }
83}
84
85impl<E: EntityKind> QueryValidate<E> for LoadQuery {
86    fn validate(&self) -> Result<(), QueryError> {
87        if let Some(filter) = &self.filter {
88            QueryValidate::<E>::validate(filter)?;
89        }
90        if let Some(limit) = &self.limit {
91            QueryValidate::<E>::validate(limit)?;
92        }
93        if let Some(sort) = &self.sort {
94            QueryValidate::<E>::validate(sort)?;
95        }
96
97        Ok(())
98    }
99}