Skip to main content

dinoco/methods/
find_first.rs

1use dinoco_engine::{DinocoAdapter, DinocoClient, Expression};
2
3use crate::{FindMany, IntoCountNode, IntoIncludeNode, Model, OrderBy, Projection, ProjectionModel};
4
5#[derive(Debug, Clone)]
6pub struct FindFirst<M, S = M> {
7    pub inner: FindMany<M, S>,
8}
9
10pub fn find_first<S>() -> FindFirst<S::Model, S>
11where
12    S: ProjectionModel + Projection<S::Model>,
13{
14    FindFirst { inner: crate::find_many::<S>().take(1) }
15}
16
17impl<M, S> FindFirst<M, S>
18where
19    M: Model,
20    S: Projection<M>,
21{
22    pub fn select<NS>(self) -> FindFirst<M, NS>
23    where
24        NS: Projection<M>,
25    {
26        FindFirst { inner: self.inner.select::<NS>() }
27    }
28
29    pub fn cond<F>(self, closure: F) -> Self
30    where
31        F: FnOnce(M::Where) -> Expression,
32    {
33        Self { inner: self.inner.cond(closure) }
34    }
35
36    pub fn take(self, value: usize) -> Self {
37        Self { inner: self.inner.take(value) }
38    }
39
40    pub fn skip(self, value: usize) -> Self {
41        Self { inner: self.inner.skip(value) }
42    }
43
44    pub fn order_by<F>(self, closure: F) -> Self
45    where
46        F: FnOnce(M::Where) -> OrderBy,
47    {
48        Self { inner: self.inner.order_by(closure) }
49    }
50
51    pub fn includes<F, I>(self, closure: F) -> Self
52    where
53        F: FnOnce(M::Include) -> I,
54        I: IntoIncludeNode,
55    {
56        Self { inner: self.inner.includes(closure) }
57    }
58
59    pub fn count<F, I>(self, closure: F) -> Self
60    where
61        F: FnOnce(M::Include) -> I,
62        I: IntoCountNode,
63    {
64        Self { inner: self.inner.count(closure) }
65    }
66
67    pub fn read_in_primary(self) -> Self {
68        Self { inner: self.inner.read_in_primary() }
69    }
70
71    #[doc(hidden)]
72    pub fn __enqueue(self, event: impl Into<String>) -> Self {
73        Self { inner: self.inner.__enqueue(event) }
74    }
75
76    #[doc(hidden)]
77    pub fn __enqueue_in(self, event: impl Into<String>, delay_ms: u64) -> Self {
78        Self { inner: self.inner.__enqueue_in(event, delay_ms) }
79    }
80
81    #[doc(hidden)]
82    pub fn __enqueue_at(self, event: impl Into<String>, execute_at: chrono::DateTime<chrono::Utc>) -> Self {
83        Self { inner: self.inner.__enqueue_at(event, execute_at) }
84    }
85
86    pub fn execute<'a, A>(
87        self,
88        client: &'a DinocoClient<A>,
89    ) -> impl std::future::Future<Output = dinoco_engine::DinocoResult<Option<S>>> + Send + 'a
90    where
91        A: DinocoAdapter,
92    {
93        async move {
94            let statement = self.inner.statement.limit(1);
95            let mut rows = crate::execute_many::<M, S, A>(
96                statement.clone(),
97                &self.inner.includes,
98                &self.inner.counts,
99                self.inner.read_mode,
100                client,
101            )
102            .await?;
103            let result = rows.drain(..).next();
104
105            if let Some(queue) = &self.inner.queue {
106                crate::queue::enqueue_find_statement(client, queue, statement, true).await?;
107            }
108
109            Ok(result)
110        }
111    }
112}