dinoco/methods/
find_first.rs1use 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}