rust_cutil/cutil/
pos.rs

1use std::collections::HashMap;
2use std::str::FromStr;
3
4use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, PaginatorTrait, QueryOrder, Select};
5use serde::{Deserialize, Serialize};
6
7use crate::cutil::extract::Extract;
8use crate::cutil::meta::R;
9use crate::cutil::paged::Paged;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Pos {
13  pub page_index: u64,
14  pub page_size: u64,
15  pub sort_direction: String,
16  pub sort_properties: Vec<String>,
17}
18
19impl Pos {
20  pub fn default() -> Self {
21    Pos {
22      page_index: 0,
23      page_size: 10,
24      sort_direction: "desc".to_string(),
25      sort_properties: vec![],
26    }
27  }
28  pub fn first() -> Self {
29    Pos {
30      page_index: 0,
31      page_size: 1,
32      sort_direction: "desc".to_string(),
33      sort_properties: vec![],
34    }
35  }
36
37  pub fn new(page_index: u64, page_size: u64, sort_direction: String, sort_properties: Vec<String>) -> Self {
38    Pos {
39      page_index,
40      page_size,
41      sort_direction,
42      sort_properties,
43    }
44  }
45  pub fn from(params: HashMap<String, String>) -> Self {
46    let page_index = params.extract_u64_default("page_index", 0);
47    let page_size = params.extract_u64_default("page_size", 10);
48    let sort_direction = params.extract_string_default("sort_direction", "desc");
49    let sort_properties: Vec<String> = params.extract_vec("sort_properties");
50
51    Pos {
52      page_index,
53      page_size,
54      sort_direction,
55      sort_properties,
56    }
57  }
58
59  pub async fn paged<M, E, D>(&self, conn: &DatabaseConnection, mut query: Select<E>) -> R<Paged<D>>
60  where
61    M: FromQueryResult + Send + Sync,
62    E: EntityTrait,
63    D: FromQueryResult + Send + Sync,
64  {
65    for property in &self.sort_properties {
66      if let Ok(column) = E::Column::from_str(property) {
67        query = match self.sort_direction.to_lowercase().as_str() {
68          "asc" => query.order_by_asc(column),
69          _ => query.order_by_desc(column),
70        };
71      }
72    }
73    let page_size = if self.page_size == 0 { 1 } else { self.page_size };
74    let query = query.into_model::<D>();
75    let paginator = query.paginate(conn, page_size);
76
77    let items: Vec<D> = paginator.fetch_page(self.page_index).await?;
78
79    let num = paginator.num_items_and_pages().await?;
80
81    let paged = Paged {
82      page_index: self.page_index,
83      page_size,
84      page_count: num.number_of_pages,
85      items,
86      item_count: num.number_of_items,
87    };
88    Ok(paged)
89  }
90}