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 { pub count: u64, pub num_pages: u64, pub list: Vec, } pub async fn paginate( db: &DatabaseConnection, page: Option, size: Option, column: Option, order: Option, ) -> Result, 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( db: &DatabaseConnection, page: Option, size: Option, column: Option, order: Option, filters: Option>, ) -> Result)>, DbErr> where E: EntityTrait + Related, 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::default()) .order_by(col, ord) } else { selector = E::find().find_also_related::(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) }