You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fast-insiders/server/src/db/paginate.rs

103 lines
2.4 KiB

use sea_orm::{error::DbErr, FromQueryResult};
use sea_orm::{prelude::*, Order, QueryOrder};
use sea_orm_rocket::Connection;
use sea_query::expr::SimpleExpr;
use serde::{Deserialize, Serialize};
use super::Db;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginatedResponse<M> {
pub count: u64,
pub num_pages: u64,
pub list: Vec<M>,
}
pub async fn paginate<E, M, C>(
conn: Connection<'_, Db>,
page: Option<u64>,
size: Option<u64>,
column: Option<C>,
order: Option<Order>,
) -> Result<PaginatedResponse<M>, DbErr>
where
E: EntityTrait,
M: Send + Sync + FromQueryResult,
C: ColumnTrait,
{
let db = conn.into_inner();
let s = size.unwrap_or(20).min(50);
let selector;
if let (Some(col), Some(ord)) = (column, order) {
selector = E::find().order_by(col, ord);
} else {
selector = E::find();
}
let pages = selector.into_model().paginate(db, s);
let count = pages.num_items().await?;
let num_pages = pages.num_pages().await?;
let p = page.unwrap_or(0).min(num_pages);
let list = pages.fetch_page(p).await?;
let res = PaginatedResponse {
count,
num_pages,
list,
};
Ok(res)
}
pub async fn paginate_also_related<E, R, T, K, C>(
conn: Connection<'_, Db>,
page: Option<u64>,
size: Option<u64>,
column: Option<C>,
order: Option<Order>,
filter: Option<SimpleExpr>,
) -> Result<PaginatedResponse<(T, Option<K>)>, DbErr>
where
E: EntityTrait + Related<R>,
R: EntityTrait,
T: Sync + Send + FromQueryResult,
K: Sync + Send + FromQueryResult,
C: ColumnTrait,
{
let db = conn.into_inner();
let s = size.unwrap_or(20).min(50);
let mut selector;
if let (Some(col), Some(ord)) = (column, order) {
selector = E::find()
.find_also_related::<R>(R::default())
.order_by(col, ord)
} else {
selector = E::find().find_also_related::<R>(R::default());
}
if let Some(fil) = filter {
selector = selector.filter(fil);
}
let pages = selector.into_model().paginate(db, s);
let count = pages.num_items().await?;
let num_pages = pages.num_pages().await?;
let p = page.unwrap_or(0).min(num_pages);
let list = pages.fetch_page(p).await?;
let res = PaginatedResponse {
count,
num_pages,
list,
};
Ok(res)
}