52 lines
1.7 KiB
Rust
52 lines
1.7 KiB
Rust
// src/shared/schema_qualifier.rs
|
|
use sqlx::PgPool;
|
|
use tonic::Status;
|
|
|
|
// TODO in the future, remove database query on every request and implement caching for scalable
|
|
// solution with many data and requests
|
|
|
|
/// Qualifies a table name by checking for its existence in the table_definitions table.
|
|
/// This is the robust, "source of truth" approach.
|
|
///
|
|
/// Rules:
|
|
/// - If a table is found in `table_definitions`, it is qualified with the 'gen' schema.
|
|
/// - Otherwise, it is assumed to be a system table in the 'public' schema.
|
|
pub async fn qualify_table_name(
|
|
db_pool: &PgPool,
|
|
profile_name: &str,
|
|
table_name: &str,
|
|
) -> Result<String, Status> {
|
|
// Check if a definition exists for this table in the given profile.
|
|
let definition_exists = sqlx::query!(
|
|
r#"SELECT EXISTS (
|
|
SELECT 1 FROM table_definitions td
|
|
JOIN profiles p ON td.profile_id = p.id
|
|
WHERE p.name = $1 AND td.table_name = $2
|
|
)"#,
|
|
profile_name,
|
|
table_name
|
|
)
|
|
.fetch_one(db_pool)
|
|
.await
|
|
.map_err(|e| Status::internal(format!("Schema lookup failed: {}", e)))?
|
|
.exists
|
|
.unwrap_or(false);
|
|
|
|
if definition_exists {
|
|
// It's a user-defined table, so it lives in 'gen'.
|
|
Ok(format!("gen.\"{}\"", table_name))
|
|
} else {
|
|
// It's not a user-defined table, so it must be a system table in 'public'.
|
|
Ok(format!("\"{}\"", table_name))
|
|
}
|
|
}
|
|
|
|
/// Qualifies table names for data operations
|
|
pub async fn qualify_table_name_for_data(
|
|
db_pool: &PgPool,
|
|
profile_name: &str,
|
|
table_name: &str,
|
|
) -> Result<String, Status> {
|
|
qualify_table_name(db_pool, profile_name, table_name).await
|
|
}
|