use dinoco_engine::{DinocoAdapter, DinocoClient, Expression};
use crate::{FindMany, IntoCountNode, IntoIncludeNode, Model, OrderBy, Projection, ProjectionModel};
#[derive(Debug, Clone)]
pub struct FindFirst<M, S = M> {
pub inner: FindMany<M, S>,
}
pub fn find_first<S>() -> FindFirst<S::Model, S>
where
S: ProjectionModel + Projection<S::Model>,
{
FindFirst { inner: crate::find_many::<S>().take(1) }
}
impl<M, S> FindFirst<M, S>
where
M: Model,
S: Projection<M>,
{
pub fn select<NS>(self) -> FindFirst<M, NS>
where
NS: Projection<M>,
{
FindFirst { inner: self.inner.select::<NS>() }
}
pub fn cond<F>(self, closure: F) -> Self
where
F: FnOnce(M::Where) -> Expression,
{
Self { inner: self.inner.cond(closure) }
}
pub fn take(self, value: usize) -> Self {
Self { inner: self.inner.take(value) }
}
pub fn skip(self, value: usize) -> Self {
Self { inner: self.inner.skip(value) }
}
pub fn order_by<F>(self, closure: F) -> Self
where
F: FnOnce(M::Where) -> OrderBy,
{
Self { inner: self.inner.order_by(closure) }
}
pub fn includes<F, I>(self, closure: F) -> Self
where
F: FnOnce(M::Include) -> I,
I: IntoIncludeNode,
{
Self { inner: self.inner.includes(closure) }
}
pub fn count<F, I>(self, closure: F) -> Self
where
F: FnOnce(M::Include) -> I,
I: IntoCountNode,
{
Self { inner: self.inner.count(closure) }
}
pub fn read_in_primary(self) -> Self {
Self { inner: self.inner.read_in_primary() }
}
#[doc(hidden)]
pub fn __enqueue(self, event: impl Into<String>) -> Self {
Self { inner: self.inner.__enqueue(event) }
}
#[doc(hidden)]
pub fn __enqueue_in(self, event: impl Into<String>, delay_ms: u64) -> Self {
Self { inner: self.inner.__enqueue_in(event, delay_ms) }
}
#[doc(hidden)]
pub fn __enqueue_at(self, event: impl Into<String>, execute_at: chrono::DateTime<chrono::Utc>) -> Self {
Self { inner: self.inner.__enqueue_at(event, execute_at) }
}
pub fn execute<'a, A>(
self,
client: &'a DinocoClient<A>,
) -> impl std::future::Future<Output = dinoco_engine::DinocoResult<Option<S>>> + Send + 'a
where
A: DinocoAdapter,
{
async move {
let statement = self.inner.statement.limit(1);
let mut rows = crate::execute_many::<M, S, A>(
statement.clone(),
&self.inner.includes,
&self.inner.counts,
self.inner.read_mode,
client,
)
.await?;
let result = rows.drain(..).next();
if let Some(queue) = &self.inner.queue {
crate::queue::enqueue_find_statement(client, queue, statement, true).await?;
}
Ok(result)
}
}
}