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.
104 lines
2.5 KiB
104 lines
2.5 KiB
use sea_orm::{
|
|
error::DbErr, prelude::*, sea_query::SimpleExpr, FromQueryResult, ItemsAndPagesNumber, Order,
|
|
QueryOrder,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[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>(
|
|
db: &DatabaseConnection,
|
|
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 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 ItemsAndPagesNumber {
|
|
number_of_items: count,
|
|
number_of_pages: num_pages,
|
|
} = pages.num_items_and_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)
|
|
}
|
|
|
|
/// Use for 1-1 relationships, retrieves the entity and the single related record
|
|
pub async fn paginate_also_related<E, R, T, K, C>(
|
|
db: &DatabaseConnection,
|
|
page: Option<u64>,
|
|
size: Option<u64>,
|
|
column: Option<C>,
|
|
order: Option<Order>,
|
|
filters: Option<Vec<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 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(fils) = filters {
|
|
for fil in fils {
|
|
selector = selector.filter(fil);
|
|
}
|
|
}
|
|
|
|
let pages = selector.into_model().paginate(db, s);
|
|
let ItemsAndPagesNumber {
|
|
number_of_items: count,
|
|
number_of_pages: num_pages,
|
|
} = pages.num_items_and_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)
|
|
}
|