icydb_core/db/query/
load.rs1use 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#[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 #[must_use]
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 #[must_use]
34 pub const fn is_empty(&self) -> bool {
35 self.filter.is_none() && self.limit.is_none() && self.sort.is_none()
36 }
37
38 #[must_use]
44 pub fn one<E: EntityKind>(self, value: impl FieldValue) -> Self {
45 self.one_by_field(E::PRIMARY_KEY, value)
46 }
47
48 #[must_use]
50 pub fn all() -> Self {
51 Self::default()
52 }
53
54 #[must_use]
56 pub fn many<E, I, V>(self, values: I) -> Self
57 where
58 E: EntityKind,
59 I: IntoIterator<Item = V>,
60 V: FieldValue,
61 {
62 self.filter(|f| f.in_iter(E::PRIMARY_KEY, values))
63 }
64
65 #[must_use]
71 pub fn one_by_field(self, field: impl AsRef<str>, value: impl FieldValue) -> Self {
72 self.filter(|f| f.eq(field, value))
73 }
74
75 #[must_use]
77 pub fn many_by_field<I, V>(self, field: impl AsRef<str>, values: I) -> Self
78 where
79 I: IntoIterator<Item = V>,
80 V: FieldValue,
81 {
82 self.filter(|f| f.in_iter(field, values))
83 }
84
85 #[must_use]
91 pub fn limit_1(self) -> Self {
92 self.offset(0).limit(1)
93 }
94}
95
96impl FilterSlot for LoadQuery {
101 fn filter_slot(&mut self) -> &mut Option<FilterExpr> {
102 &mut self.filter
103 }
104}
105
106impl LimitSlot for LoadQuery {
107 fn limit_slot(&mut self) -> &mut Option<LimitExpr> {
108 &mut self.limit
109 }
110}
111
112impl SortSlot for LoadQuery {
113 fn sort_slot(&mut self) -> &mut Option<SortExpr> {
114 &mut self.sort
115 }
116}
117
118impl<E: EntityKind> QueryValidate<E> for LoadQuery {
119 fn validate(&self) -> Result<(), QueryError> {
120 if let Some(filter) = &self.filter {
121 QueryValidate::<E>::validate(filter)?;
122 }
123 if let Some(limit) = &self.limit {
124 QueryValidate::<E>::validate(limit)?;
125 }
126 if let Some(sort) = &self.sort {
127 QueryValidate::<E>::validate(sort)?;
128 }
129
130 Ok(())
131 }
132}