dinoco 0.0.7

A modern Rust ORM for schema-driven queries, migrations, and database operations.
Documentation
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)
        }
    }
}