2025-05-17 02:08:59 +07:00
|
|
|
use super::{ListQueryBuilder, bind_filter_value};
|
2025-03-23 20:42:38 +07:00
|
|
|
use crate::{CountResult, MetaRequestDto, MetaResponseDto, ResponseListSuccessDto};
|
2025-05-17 02:08:59 +07:00
|
|
|
use anyhow::Result;
|
|
|
|
|
use serde::{Serialize, de::DeserializeOwned};
|
|
|
|
|
use surrealdb::{Surreal, engine::remote::ws::Client};
|
2025-03-23 20:42:38 +07:00
|
|
|
|
|
|
|
|
pub async fn query_list_with_meta<T>(
|
|
|
|
|
db: &Surreal<Client>,
|
|
|
|
|
table: &str,
|
|
|
|
|
meta: &MetaRequestDto,
|
|
|
|
|
conditions: Vec<String>,
|
2025-03-26 13:06:34 +07:00
|
|
|
custom_select: Option<String>,
|
2025-05-17 02:08:59 +07:00
|
|
|
search_field: &str,
|
|
|
|
|
select_fields: Option<Vec<&str>>,
|
2025-05-20 01:49:50 +07:00
|
|
|
fetch_fields: Option<Vec<&str>>,
|
2025-03-23 20:42:38 +07:00
|
|
|
) -> Result<ResponseListSuccessDto<Vec<T>>>
|
|
|
|
|
where
|
|
|
|
|
T: DeserializeOwned + Serialize,
|
|
|
|
|
{
|
2025-05-17 02:08:59 +07:00
|
|
|
let page = meta.page.unwrap_or(1).max(1);
|
|
|
|
|
let per_page = meta.per_page.unwrap_or(10).max(1);
|
2025-03-23 20:42:38 +07:00
|
|
|
let start = (page - 1) * per_page;
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-26 13:06:34 +07:00
|
|
|
let sql = custom_select.unwrap_or_else(|| {
|
2025-05-20 01:49:50 +07:00
|
|
|
ListQueryBuilder::from_meta(
|
|
|
|
|
table,
|
|
|
|
|
meta,
|
|
|
|
|
search_field,
|
|
|
|
|
select_fields,
|
|
|
|
|
fetch_fields,
|
|
|
|
|
)
|
|
|
|
|
.build()
|
2025-03-26 13:06:34 +07:00
|
|
|
});
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-26 13:06:34 +07:00
|
|
|
let mut query_exec = db.query(sql);
|
2025-03-23 20:42:38 +07:00
|
|
|
if let Some(search) = &meta.search {
|
|
|
|
|
if !search.is_empty() {
|
2025-05-20 01:49:50 +07:00
|
|
|
query_exec = query_exec.bind(("search", search.to_lowercase().clone()));
|
2025-03-23 20:42:38 +07:00
|
|
|
}
|
|
|
|
|
}
|
2025-05-17 02:08:59 +07:00
|
|
|
if let Some(filter_val) = &meta.filter {
|
|
|
|
|
query_exec = bind_filter_value(query_exec, filter_val.clone());
|
2025-03-23 20:42:38 +07:00
|
|
|
}
|
2025-03-26 13:06:34 +07:00
|
|
|
query_exec = query_exec
|
|
|
|
|
.bind(("per_page", per_page))
|
|
|
|
|
.bind(("start", start));
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-30 02:46:16 +07:00
|
|
|
let raw: Vec<T> = query_exec.await?.take(0)?;
|
2025-05-17 02:08:59 +07:00
|
|
|
|
|
|
|
|
let mut count_query = db.query(format!(
|
|
|
|
|
"SELECT count() FROM {} {}",
|
|
|
|
|
table,
|
|
|
|
|
if conditions.is_empty() {
|
|
|
|
|
String::new()
|
|
|
|
|
} else {
|
|
|
|
|
format!("WHERE {}", conditions.join(" AND "))
|
|
|
|
|
}
|
|
|
|
|
));
|
2025-03-25 10:48:34 +07:00
|
|
|
if let Some(search) = &meta.search {
|
|
|
|
|
if !search.is_empty() {
|
|
|
|
|
count_query = count_query.bind(("search", search.clone()));
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-17 02:08:59 +07:00
|
|
|
if let Some(filter_val) = &meta.filter {
|
|
|
|
|
count_query = bind_filter_value(count_query, filter_val.clone());
|
2025-03-23 20:42:38 +07:00
|
|
|
}
|
|
|
|
|
let count_result: Vec<CountResult> = count_query.await?.take(0)?;
|
|
|
|
|
let total = count_result.first().map(|c| c.count);
|
2025-03-25 10:48:34 +07:00
|
|
|
|
2025-03-23 20:42:38 +07:00
|
|
|
Ok(ResponseListSuccessDto {
|
2025-03-30 02:46:16 +07:00
|
|
|
data: raw,
|
2025-05-17 02:08:59 +07:00
|
|
|
meta: Some(MetaResponseDto {
|
|
|
|
|
page: Some(page),
|
|
|
|
|
per_page: Some(per_page),
|
|
|
|
|
total,
|
|
|
|
|
}),
|
2025-03-23 20:42:38 +07:00
|
|
|
})
|
|
|
|
|
}
|