1
2use sqlx::{MySql, MySqlPool, QueryBuilder};
3use crate::params::QueryParams;
4use crate::whitelist::FieldWhitelist;
5use crate::builder::build_filter;
6
7pub struct PageResult<T> {
9 pub total: i64,
11 pub list: Vec<T>,
13}
14
15pub async fn query_page<T>(
26 pool: &MySqlPool,
27 base_sql: &str,
28 count_sql: &str,
29 params: QueryParams,
30 whitelist: FieldWhitelist,
31) -> Result<PageResult<T>, sqlx::Error>
32where
33 T: for<'r> sqlx::FromRow<'r, sqlx::mysql::MySqlRow> + Send + Unpin,
34{
35 let mut count_qb = QueryBuilder::<MySql>::new(count_sql);
36 if let Some(f) = ¶ms.filter {
37 count_qb.push(" WHERE ");
38 build_filter(&mut count_qb, f, &whitelist).map_err(|e| sqlx::Error::Protocol(e))?;
39 }
40 let total: i64 = count_qb.build_query_scalar().fetch_one(pool).await?;
41
42 let mut qb = QueryBuilder::<MySql>::new(base_sql);
43 if let Some(f) = ¶ms.filter {
44 qb.push(" WHERE ");
45 build_filter(&mut qb, f, &whitelist).map_err(|e| sqlx::Error::Protocol(e))?;
46 }
47 qb.push(" LIMIT ");
48 qb.push_bind(params.page_size);
49 qb.push(" OFFSET ");
50 qb.push_bind(params.page * params.page_size);
51
52 let list = qb.build_query_as::<T>().fetch_all(pool).await?;
53 Ok(PageResult { total, list })
54}