use actix_web::HttpResponse;
use sqlx::{Pool, Postgres};
use crate::AppState;
use crate::api::response::{bad_request, internal_error};
use crate::athena::postgres_clients::resolved_catalog_postgres_uri;
use crate::data::clients::{AthenaClientRecord, get_athena_client_by_name};
use crate::drivers::postgresql::sqlx_driver::RegisteredClient;
use crate::parser::resolve_compatible_postgres_uri;
pub(super) fn resolve_registered_client_uri(
state: &AppState,
client_name: &str,
) -> Result<String, HttpResponse> {
let registered: RegisteredClient = state
.pg_registry
.registered_client(client_name)
.ok_or_else(|| {
bad_request(
"Unknown client",
format!("No Postgres client named '{}' is registered.", client_name),
)
})?;
registered_client_connection_uri(®istered).ok_or_else(|| {
bad_request(
"Client URI unavailable",
format!("No Postgres URI is available for client '{}'.", client_name),
)
})
}
fn registered_client_connection_uri(registered: &RegisteredClient) -> Option<String> {
registered
.config_uri_template
.as_deref()
.map(resolve_compatible_postgres_uri)
.or_else(|| {
registered
.pg_uri
.as_deref()
.map(resolve_compatible_postgres_uri)
})
}
fn catalog_client_connection_uri(client: &AthenaClientRecord) -> Option<String> {
resolved_catalog_postgres_uri(client)
}
pub(super) async fn resolve_client_connection_uri(
state: &AppState,
client_name: &str,
) -> Result<Option<String>, HttpResponse> {
if let Some(runtime_client) = state.pg_registry.registered_client(client_name)
&& let Some(uri) = registered_client_connection_uri(&runtime_client)
{
return Ok(Some(uri));
}
let pool: Pool<Postgres> = match super::client_catalog_pool(state) {
Ok(value) => value,
Err(_) => return Ok(None),
};
let catalog_client: Option<AthenaClientRecord> = get_athena_client_by_name(&pool, client_name)
.await
.map_err(|err| internal_error("Failed to load catalog client", err.to_string()))?;
Ok(catalog_client
.as_ref()
.and_then(catalog_client_connection_uri))
}