#![allow(missing_docs)]
use std::future::Future;
use std::pin::Pin;
use crate::error::{Error, Result};
use super::Model;
pub(crate) fn db() -> Result<crate::database::Database> {
crate::database::require_db()
}
pub(crate) fn database() -> Result<crate::database::Database> {
crate::database::require_db()
}
pub(crate) async fn all<M>() -> Result<Vec<M>>
where
M: Model + Sized,
{
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::find_all::<M, _>(conn.connection()).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::find_all::<M, _>(tx.as_ref()).await
}
}
}
pub(crate) async fn count<M>() -> Result<u64>
where
M: Model + Sized,
{
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::count::<M, _>(conn.connection(), None).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::count::<M, _>(tx.as_ref(), None).await
}
}
}
pub(crate) async fn exists_any<M>() -> Result<bool>
where
M: Model + Sized,
{
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::exists_any::<M, _>(conn.connection()).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::exists_any::<M, _>(tx.as_ref()).await
}
}
}
pub(crate) async fn insert_all<M>(models: Vec<M>) -> Result<Vec<M>>
where
M: Model + Sized,
<<M as crate::internal::InternalModel>::Entity as crate::internal::EntityTrait>::Model:
crate::internal::IntoActiveModel<<M as crate::internal::InternalModel>::ActiveModel>,
{
if models.is_empty() {
return Ok(Vec::new());
}
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::insert_many::<M, _>(conn.connection(), models).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::insert_many::<M, _>(tx.as_ref(), models).await
}
}
}
pub(crate) async fn transaction<F, T>(f: F) -> Result<T>
where
F: for<'c> FnOnce(
&'c crate::database::Transaction,
) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'c>>
+ Send,
T: Send,
{
crate::database::__current_db()?.transaction(f).await
}
pub(crate) async fn first<M>() -> Result<Option<M>>
where
M: Model + Sized,
{
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::first::<M, _>(conn.connection()).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::first::<M, _>(tx.as_ref()).await
}
}
}
pub(crate) async fn last<M>() -> Result<Option<M>>
where
M: Model + Sized,
{
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::last::<M, _>(conn.connection()).await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::last::<M, _>(tx.as_ref()).await
}
}
}
pub(crate) async fn paginate<M>(page: u64, per_page: u64) -> Result<Vec<M>>
where
M: Model + Sized,
{
if page == 0 {
return Err(Error::validation("page", "must be at least 1"));
}
if per_page == 0 {
return Err(Error::validation("per_page", "must be greater than 0"));
}
let offset = (page - 1) * per_page;
match crate::database::__current_connection()? {
crate::database::ConnectionRef::Database(conn) => {
crate::internal::QueryExecutor::paginate::<M, _>(conn.connection(), per_page, offset)
.await
}
crate::database::ConnectionRef::Transaction(tx) => {
crate::internal::QueryExecutor::paginate::<M, _>(tx.as_ref(), per_page, offset).await
}
}
}
pub(crate) async fn reload<M>(model: &M) -> Result<M>
where
M: Model + Sized,
{
let primary_key = model.primary_key();
let id_display = M::primary_key_display(&primary_key);
M::find(primary_key).await?.ok_or_else(|| {
Error::not_found(format!(
"{} with {} no longer exists",
M::table_name(),
id_display
))
})
}
pub(crate) fn is_new<M>(model: &M) -> bool
where
M: Model,
{
M::primary_key_is_new(&model.primary_key())
}