fixed push data to the tables

This commit is contained in:
filipriec
2025-03-08 20:06:34 +01:00
parent b0daa4ff18
commit 6f9887a303

View File

@@ -25,7 +25,6 @@ pub async fn post_table_data(
} }
// Add trimmed non-empty values to data map // Add trimmed non-empty values to data map
// Empty optional fields will be skipped in SQL generation
if !trimmed.is_empty() || key == "firma" { if !trimmed.is_empty() || key == "firma" {
data.insert(key, trimmed); data.insert(key, trimmed);
} }
@@ -44,7 +43,7 @@ pub async fn post_table_data(
// Lookup table_definition // Lookup table_definition
let table_def = sqlx::query!( let table_def = sqlx::query!(
r#"SELECT id, columns, linked_table_id FROM table_definitions r#"SELECT id, columns FROM table_definitions
WHERE profile_id = $1 AND table_name = $2"#, WHERE profile_id = $1 AND table_name = $2"#,
profile_id, profile_id,
table_name table_name
@@ -70,18 +69,22 @@ pub async fn post_table_data(
columns.push((name, sql_type)); columns.push((name, sql_type));
} }
// Check required system columns // Get required relationships
let mut required_columns = vec!["firma".to_string()]; let required_links = sqlx::query!(
if let Some(linked_table_id) = table_def.linked_table_id { r#"SELECT ltd.table_name
let linked_table = sqlx::query!( FROM table_definition_links tdl
"SELECT table_name FROM table_definitions WHERE id = $1", JOIN table_definitions ltd ON tdl.linked_table_id = ltd.id
linked_table_id WHERE tdl.source_table_id = $1 AND tdl.is_required = true"#,
table_def.id
) )
.fetch_one(db_pool) .fetch_all(db_pool)
.await .await
.map_err(|e| Status::internal(format!("Linked table error: {}", e)))?; .map_err(|e| Status::internal(format!("Link lookup error: {}", e)))?;
let base_name = linked_table.table_name.splitn(2, '_').last().unwrap_or(&linked_table.table_name); // Build required columns list
let mut required_columns = vec!["firma".to_string()];
for link in required_links {
let base_name = link.table_name.split('_').last().unwrap_or(&link.table_name);
required_columns.push(format!("{}_id", base_name)); required_columns.push(format!("{}_id", base_name));
} }
@@ -101,7 +104,6 @@ pub async fn post_table_data(
} }
} }
// Validate Steel scripts // Validate Steel scripts
let scripts = sqlx::query!( let scripts = sqlx::query!(
"SELECT target_column, script FROM table_scripts WHERE table_definitions_id = $1", "SELECT target_column, script FROM table_scripts WHERE table_definitions_id = $1",
@@ -114,23 +116,18 @@ pub async fn post_table_data(
for script_record in scripts { for script_record in scripts {
let target_column = script_record.target_column; let target_column = script_record.target_column;
// Check if target column is present in data
if !data.contains_key(&target_column) { if !data.contains_key(&target_column) {
return Err(Status::invalid_argument( return Err(Status::invalid_argument(
format!("Column '{}' is required due to an associated script", target_column) format!("Column '{}' is required due to an associated script", target_column)
)); ));
} }
// Parse the script
let operation = execution::parse_script(&script_record.script, &target_column) let operation = execution::parse_script(&script_record.script, &target_column)
.map_err(|e| Status::invalid_argument(e.to_string()))?; .map_err(|e| Status::invalid_argument(e.to_string()))?;
// Get source column from operation let source_column = match operation {
let source_column =
match operation {
ScriptOperation::SetToLocalColumn { source } => source, ScriptOperation::SetToLocalColumn { source } => source,
ScriptOperation::SetToExternalColumn { table, column } => { ScriptOperation::SetToExternalColumn { table, column } => {
// For external columns, we need to resolve the value from the external table
let external_source = format!("@{}.{}", table, column); let external_source = format!("@{}.{}", table, column);
let resolved_value = execution::resolve_value( let resolved_value = execution::resolve_value(
db_pool, db_pool,
@@ -140,24 +137,20 @@ pub async fn post_table_data(
&external_source &external_source
).await.map_err(|e| Status::invalid_argument(e.to_string()))?; ).await.map_err(|e| Status::invalid_argument(e.to_string()))?;
// Return the resolved value
resolved_value resolved_value
} }
}; };
// Check source column presence
let source_value = data.get(&source_column) let source_value = data.get(&source_column)
.ok_or_else(|| Status::invalid_argument( .ok_or_else(|| Status::invalid_argument(
format!("Source column '{}' required by script for '{}' is missing", source_column, target_column) format!("Source column '{}' required by script for '{}' is missing", source_column, target_column)
))?; ))?;
// Get target value
let target_value = data.get(&target_column) let target_value = data.get(&target_column)
.ok_or_else(|| Status::invalid_argument( .ok_or_else(|| Status::invalid_argument(
format!("Target column '{}' is missing in data", target_column) format!("Target column '{}' is missing in data", target_column)
))?; ))?;
// Validate value match
if target_value != source_value { if target_value != source_value {
return Err(Status::invalid_argument( return Err(Status::invalid_argument(
format!("Value for '{}' must match '{}' as per script. Expected '{}', got '{}'", format!("Value for '{}' must match '{}' as per script. Expected '{}', got '{}'",
@@ -186,8 +179,6 @@ pub async fn post_table_data(
.ok_or_else(|| Status::invalid_argument(format!("Column not found: {}", col)))? .ok_or_else(|| Status::invalid_argument(format!("Column not found: {}", col)))?
}; };
// TODO This needs heavy adjustement. More stuff to be added for user to only pick
// preprogrammed functions
match sql_type { match sql_type {
"TEXT" | "VARCHAR(15)" | "VARCHAR(255)" => { "TEXT" | "VARCHAR(15)" | "VARCHAR(255)" => {
if let Some(max_len) = sql_type.strip_prefix("VARCHAR(") if let Some(max_len) = sql_type.strip_prefix("VARCHAR(")
@@ -221,7 +212,6 @@ pub async fn post_table_data(
param_idx += 1; param_idx += 1;
} }
// Ensure we have at least one column to insert
if columns_list.is_empty() { if columns_list.is_empty() {
return Err(Status::invalid_argument("No valid columns to insert")); return Err(Status::invalid_argument("No valid columns to insert"));
} }