1use axum::{extract::State, http::StatusCode};
2use serde::{Deserialize, Serialize};
3use serde_json::{json, Value};
4use sqlx::{PgPool, Row};
5
6pub async fn gbs_db_connect<T>(
8 State(pg_pool): State<PgPool>,
9 function_name: String,
10 params: Value,
11) -> Result<(StatusCode, String), (StatusCode, String)>
12where
13 T: for<'de> Deserialize<'de> + Serialize,
14{
15 let query = format!("SELECT {}($1::jsonb) as data", function_name);
16
17 let row = sqlx::query(&query)
18 .bind(params)
19 .fetch_one(&pg_pool)
20 .await
21 .map_err(|e| {
22 (
23 StatusCode::INTERNAL_SERVER_ERROR,
24 json!({"success": false, "message": e.to_string()}).to_string(),
25 )
26 })?;
27
28 let result_json: Value = row.try_get("data").map_err(|e| {
29 (
30 StatusCode::INTERNAL_SERVER_ERROR,
31 json!({"success": false, "message": format!("Failed to get JSON from row: {}", e)})
32 .to_string(),
33 )
34 })?;
35
36 let data: Vec<T> = serde_json::from_value(result_json).map_err(|e| {
37 (
38 StatusCode::INTERNAL_SERVER_ERROR,
39 json!({"success": false, "message": format!("Failed to deserialize data: {}", e)})
40 .to_string(),
41 )
42 })?;
43
44 Ok((
45 StatusCode::OK,
46 json!({"success": true, "data": data}).to_string(),
47 ))
48}