Skip to main content

moire_web/api/
sql.rs

1use std::sync::Arc;
2
3use axum::body::Bytes;
4use axum::extract::State;
5use axum::http::StatusCode;
6use axum::response::IntoResponse;
7use moire_types::{QueryRequest, SqlRequest};
8
9use crate::app::AppState;
10use crate::db::{Db, query_named_blocking, sql_query_blocking};
11use crate::util::http::{json_error, json_ok};
12
13pub async fn api_sql(State(state): State<AppState>, body: Bytes) -> impl IntoResponse {
14    execute_sql_request(body, state.db.clone()).await
15}
16
17pub async fn api_query(State(state): State<AppState>, body: Bytes) -> impl IntoResponse {
18    execute_named_query_request(body, state.db.clone()).await
19}
20
21pub async fn execute_sql_request(body: Bytes, db: Arc<Db>) -> impl IntoResponse {
22    let request: SqlRequest = match facet_json::from_slice(&body) {
23        Ok(request) => request,
24        Err(error) => {
25            return json_error(
26                StatusCode::BAD_REQUEST,
27                format!("invalid request json: {error}"),
28            );
29        }
30    };
31
32    match tokio::task::spawn_blocking(move || sql_query_blocking(&db, request.sql.as_str())).await {
33        Ok(Ok(response)) => json_ok(&response),
34        Ok(Err(error)) => json_error(StatusCode::BAD_REQUEST, error),
35        Err(error) => json_error(
36            StatusCode::INTERNAL_SERVER_ERROR,
37            format!("sql worker join error: {error}"),
38        ),
39    }
40}
41
42pub async fn execute_named_query_request(body: Bytes, db: Arc<Db>) -> impl IntoResponse {
43    let request: QueryRequest = match facet_json::from_slice(&body) {
44        Ok(request) => request,
45        Err(error) => {
46            return json_error(
47                StatusCode::BAD_REQUEST,
48                format!("invalid request json: {error}"),
49            );
50        }
51    };
52
53    let name = request.name.to_string();
54    let limit = request.limit.unwrap_or(50);
55    match tokio::task::spawn_blocking(move || query_named_blocking(&db, &name, limit)).await {
56        Ok(Ok(response)) => json_ok(&response),
57        Ok(Err(error)) => json_error(StatusCode::BAD_REQUEST, error),
58        Err(error) => json_error(
59            StatusCode::INTERNAL_SERVER_ERROR,
60            format!("query worker join error: {error}"),
61        ),
62    }
63}