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