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.
103 lines
2.4 KiB
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)
|
|
}
|