// 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 { // 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 { qualify_table_name(db_pool, profile_name, table_name).await }