Skip to main content

sofie_db/
query.rs

1use std::marker::PhantomData;
2
3use sofie_core::Result;
4
5use crate::statement::{Criteria, SortKey};
6use crate::{Condition, Read, Sort, Source};
7
8pub struct Query<T: Source> {
9    pub(crate) criteria: Criteria,
10    marker: PhantomData<fn() -> T>,
11}
12
13impl<T: Source> Clone for Query<T> {
14    fn clone(&self) -> Self {
15        Self {
16            criteria: self.criteria.clone(),
17            marker: PhantomData,
18        }
19    }
20}
21
22impl<T: Source> Default for Query<T> {
23    fn default() -> Self {
24        Self {
25            criteria: Criteria::default(),
26            marker: PhantomData,
27        }
28    }
29}
30
31impl<T: Source> Query<T> {
32    #[must_use]
33    pub fn where_(mut self, condition: Condition<T::Base>) -> Self {
34        self.criteria.conditions.push(condition.kind);
35        self
36    }
37
38    #[must_use]
39    pub fn scope(self, scope: impl FnOnce(Self) -> Self) -> Self {
40        scope(self)
41    }
42
43    #[must_use]
44    pub fn order_by(mut self, sort: Sort<T::Base>) -> Self {
45        self.criteria.sorts.push(sort.key);
46        self
47    }
48
49    /// Ids are `UUIDv7`, so they sort by creation time.
50    #[must_use]
51    pub fn latest(mut self) -> Self {
52        self.criteria.sorts.push(SortKey::id(true));
53        self
54    }
55
56    #[must_use]
57    pub fn limit(mut self, limit: u64) -> Self {
58        self.criteria.limit = Some(limit);
59        self
60    }
61
62    pub async fn all(self, read: &Read) -> Result<Vec<T>> {
63        self.criteria.all(read).await
64    }
65
66    pub async fn first(self, read: &Read) -> Result<Option<T>> {
67        Ok(self.limit(1).all(read).await?.into_iter().next())
68    }
69
70    pub async fn count(self, read: &Read) -> Result<u64> {
71        self.criteria.count::<T::Base>(read).await
72    }
73
74    pub async fn exists(self, read: &Read) -> Result<bool> {
75        self.criteria.exists::<T::Base>(read).await
76    }
77
78    #[cfg(feature = "streams")]
79    pub fn stream(self, read: &Read) -> Result<crate::Stream<T>> {
80        crate::Stream::new(self.criteria, read)
81    }
82}
83
84#[cfg(feature = "soft-delete")]
85impl<T: Source> Query<T>
86where
87    T::Base: crate::SoftDeletes,
88{
89    #[must_use]
90    pub fn with_trashed(mut self) -> Self {
91        self.criteria.with_hidden = true;
92        self
93    }
94}