use std::collections::HashMap;
use std::str::FromStr;
use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, PaginatorTrait, QueryOrder, Select};
use serde::{Deserialize, Serialize};
use crate::cutil::extract::Extract;
use crate::cutil::meta::R;
use crate::cutil::paged::Paged;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pos {
pub page_index: u64,
pub(crate) page_size: u64,
pub sort_direction: String,
pub sort_properties: Vec<String>,
}
impl Pos {
pub fn default() -> Self {
Pos {
page_index: 0,
page_size: 10,
sort_direction: "desc".to_string(),
sort_properties: vec![],
}
}
pub fn first() -> Self {
Pos {
page_index: 0,
page_size: 1,
sort_direction: "desc".to_string(),
sort_properties: vec![],
}
}
pub fn new(page_index: u64, page_size: u64, sort_direction: String, sort_properties: Vec<String>) -> Self {
Pos {
page_index,
page_size,
sort_direction,
sort_properties,
}
}
pub fn from(params: HashMap<String, String>) -> Self {
let page_index = params.extract_u64_default("page_index", 0);
let page_size = params.extract_u64_default("page_size", 10);
let sort_direction = params.extract_string_default("sort_direction", "desc");
let sort_properties: Vec<String> = params.extract_vec("sort_properties");
Pos {
page_index,
page_size,
sort_direction,
sort_properties,
}
}
pub async fn paged<M, E, D>(&self, conn: &DatabaseConnection, mut query: Select<E>) -> R<Paged<D>>
where
M: FromQueryResult + Send + Sync,
E: EntityTrait,
D: FromQueryResult + Send + Sync,
{
for property in &self.sort_properties {
if let Ok(column) = E::Column::from_str(property) {
query = match self.sort_direction.to_lowercase().as_str() {
"asc" => query.order_by_asc(column),
_ => query.order_by_desc(column),
};
}
}
let page_size = if self.page_size == 0 { 1 } else { self.page_size };
let query = query.into_model::<D>();
let paginator = query.paginate(conn, page_size);
let items: Vec<D> = paginator.fetch_page(self.page_index).await?;
let num = paginator.num_items_and_pages().await?;
let paged = Paged {
page_index: self.page_index,
page_size,
page_count: num.number_of_pages,
items,
item_count: num.number_of_items,
};
Ok(paged)
}
}