From a26fbdd2cf33da8d4dcb5cd01c5ee0ac27ba4744 Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 1 Mar 2025 17:26:41 +0100 Subject: [PATCH] trying to make work multi profile setup --- .../handlers/post_table_definition.rs | 73 ++++++++++++++----- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/server/src/table_definition/handlers/post_table_definition.rs b/server/src/table_definition/handlers/post_table_definition.rs index 31922ab..6cd9daa 100644 --- a/server/src/table_definition/handlers/post_table_definition.rs +++ b/server/src/table_definition/handlers/post_table_definition.rs @@ -4,6 +4,13 @@ use sqlx::{PgPool, Row}; use serde_json::json; use common::proto::multieko2::table_definition::{PostTableDefinitionRequest, TableDefinitionResponse}; +const VALID_DATA_TYPES: &[&str] = &["TEXT", "INTEGER", "BIGINT", "BOOLEAN", "TIMESTAMPTZ", "NUMERIC"]; + +// Add to validation section +fn is_valid_data_type(dt: &str) -> bool { + VALID_DATA_TYPES.contains(&dt.to_uppercase().as_str()) +} + // Validate SQL identifiers fn is_valid_identifier(s: &str) -> bool { !s.is_empty() && @@ -58,14 +65,21 @@ pub async fn post_table_definition( None }; + fn is_reserved_column(name: &str, linked_table: Option<&str>) -> bool { + let reserved = vec!["id", "deleted", "firma", "created_at"]; + reserved.contains(&name) || linked_table.map(|lt| format!("{}_id", lt)) == Some(name.to_string()) + } + // Validate columns and indexes (add data type support) let mut columns = Vec::new(); for col_def in request.columns.drain(..) { let col_name = sanitize_identifier(&col_def.name); if !is_valid_identifier(&col_name) { - return Err(Status::invalid_argument(format!("Invalid column name: {}", 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")); } - // Add data type validation here columns.push(format!("\"{}\" {}", col_name, col_def.data_type)); } @@ -122,23 +136,48 @@ pub async fn post_table_definition( }) } -fn generate_table_sql(table_name: &str, columns: &[String], indexes: &[String]) -> (String, Vec) { - let columns_sql = columns.join(",\n "); + +// Add system columns to SQL generation +fn generate_table_sql( + table_name: &str, + columns: &[String], + indexes: &[String], + linked_table: Option<&str>, +) -> (String, Vec) { + let mut system_columns = vec![ + "id BIGSERIAL PRIMARY KEY", + "deleted BOOLEAN NOT NULL DEFAULT FALSE", + "firma TEXT NOT NULL", + ]; + + if let Some(linked) = linked_table { + system_columns.push( + format!("\"{}_id\" BIGINT NOT NULL REFERENCES \"{}\"(id)", linked, linked) + ); + } + + let all_columns = system_columns + .iter() + .map(|s| s.to_string()) + .chain(columns.iter().cloned()) + .collect::>(); let create_sql = format!( - "CREATE TABLE \"{}\" ( - id BIGSERIAL PRIMARY KEY, - deleted BOOLEAN NOT NULL DEFAULT FALSE, - {}, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP - )", table_name, columns_sql); + "CREATE TABLE \"{}\" (\n {},\n created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP\n)", + table_name, + all_columns.join(",\n ") + ); - let index_sql = indexes.iter() - .map(|i| format!( - "CREATE INDEX idx_{}_{} ON \"{}\" (\"{}\")", - table_name, i, table_name, i - )) - .collect(); + let mut system_indexes = vec![ + format!("CREATE INDEX idx_{}_firma ON \"{}\" (firma)", table_name, table_name), + ]; - (create_sql, index_sql) + if let Some(linked) = linked_table { + system_indexes.push(format!( + "CREATE INDEX idx_{}_{}_id ON \"{}\" (\"{}_id\")", + table_name, linked, table_name, linked + )); + } + + (create_sql, [system_indexes, indexes.to_vec()].concat()) }