Files
imphnen-backend-service/imphnen-utils/src/query_list.rs
T

71 lines
1.9 KiB
Rust
Raw Normal View History

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-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-17 02:08:59 +07:00
ListQueryBuilder::from_meta(table, meta, search_field, select_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-03-26 13:06:34 +07:00
query_exec = query_exec.bind(("search", search.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
})
}