table creation columns is now not accessed via raw sql

This commit is contained in:
filipriec
2025-03-03 12:03:41 +01:00
parent a03f2697b4
commit bca2cf925d
5 changed files with 101 additions and 14 deletions

View File

@@ -5,11 +5,15 @@ use serde_json::json;
use time::OffsetDateTime;
use common::proto::multieko2::table_definition::{PostTableDefinitionRequest, TableDefinitionResponse};
const VALID_DATA_TYPES: &[&str] = &["TEXT", "INTEGER", "BIGINT", "BOOLEAN", "TIMESTAMPTZ", "NUMERIC"];
fn is_valid_data_type(dt: &str) -> bool {
VALID_DATA_TYPES.contains(&dt.to_uppercase().as_str())
}
const PREDEFINED_FIELD_TYPES: &[(&str, &str)] = &[
("text", "TEXT"),
("psc", "TEXT"),
("phone", "VARCHAR(15)"),
("address", "TEXT"),
("email", "VARCHAR(255)"),
("boolean", "BOOLEAN"),
("timestamp", "TIMESTAMPTZ"),
];
fn is_valid_identifier(s: &str) -> bool {
!s.is_empty() &&
@@ -28,6 +32,14 @@ fn sanitize_identifier(s: &str) -> String {
format!("{}_{}", year, cleaned)
}
fn map_field_type(field_type: &str) -> Result<&str, Status> {
PREDEFINED_FIELD_TYPES
.iter()
.find(|(key, _)| *key == field_type.to_lowercase().as_str())
.map(|(_, sql_type)| *sql_type)
.ok_or_else(|| Status::invalid_argument(format!("Invalid field type: {}", field_type)))
}
pub async fn post_table_definition(
db_pool: &PgPool,
mut request: PostTableDefinitionRequest,
@@ -52,7 +64,6 @@ pub async fn post_table_definition(
// Validate linked table if provided
let linked_table_id;
if let Some(lt_name) = &request.linked_table_name {
// Lookup the table with the EXACT provided name
let lt_record = sqlx::query!(
"SELECT id FROM table_definitions
WHERE profile_id = $1 AND table_name = $2",
@@ -78,10 +89,9 @@ pub async fn post_table_definition(
if !is_valid_identifier(&col_def.name) {
return Err(Status::invalid_argument("Invalid column name"));
}
if !is_valid_data_type(&col_def.data_type) {
return Err(Status::invalid_argument("Invalid data type"));
}
columns.push(format!("\"{}\" {}", col_name, col_def.data_type));
let sql_type = map_field_type(&col_def.field_type)?;
columns.push(format!("\"{}\" {}", col_name, sql_type));
}
let mut indexes = Vec::new();
@@ -155,9 +165,8 @@ fn generate_table_sql(
];
if let Some(linked) = linked_table {
// Extract base name without prefix for relationship
let parts: Vec<&str> = linked.splitn(2, '_').collect();
let base_name = parts.get(1).unwrap_or(&linked); // "profile_table"
let base_name = parts.get(1).unwrap_or(&linked);
system_columns.push(
format!("\"{}_id\" BIGINT NOT NULL REFERENCES \"{}\"(id)",