use sqlx::{MySql, MySqlPool, QueryBuilder};
use crate::params::QueryParams;
use crate::whitelist::FieldWhitelist;
use crate::builder::build_filter;
pub struct PageResult<T> {
pub total: i64,
pub list: Vec<T>,
}
pub async fn query_page<T>(
pool: &MySqlPool,
base_sql: &str,
count_sql: &str,
params: QueryParams,
whitelist: FieldWhitelist,
) -> Result<PageResult<T>, sqlx::Error>
where
T: for<'r> sqlx::FromRow<'r, sqlx::mysql::MySqlRow> + Send + Unpin,
{
let mut count_qb = QueryBuilder::<MySql>::new(count_sql);
if let Some(f) = ¶ms.filter {
count_qb.push(" WHERE ");
build_filter(&mut count_qb, f, &whitelist).map_err(|e| sqlx::Error::Protocol(e))?;
}
let total: i64 = count_qb.build_query_scalar().fetch_one(pool).await?;
let mut qb = QueryBuilder::<MySql>::new(base_sql);
if let Some(f) = ¶ms.filter {
qb.push(" WHERE ");
build_filter(&mut qb, f, &whitelist).map_err(|e| sqlx::Error::Protocol(e))?;
}
qb.push(" LIMIT ");
qb.push_bind(params.page_size);
qb.push(" OFFSET ");
qb.push_bind(params.page * params.page_size);
let list = qb.build_query_as::<T>().fetch_all(pool).await?;
Ok(PageResult { total, list })
}