rust_cutil/cutil/
pos.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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)
  }
}