fixed push data to the tables
This commit is contained in:
@@ -14,18 +14,17 @@ pub async fn post_table_data(
|
|||||||
let profile_name = request.profile_name;
|
let profile_name = request.profile_name;
|
||||||
let table_name = request.table_name;
|
let table_name = request.table_name;
|
||||||
let mut data = HashMap::new();
|
let mut data = HashMap::new();
|
||||||
|
|
||||||
// Process and validate all data values
|
// Process and validate all data values
|
||||||
for (key, value) in request.data {
|
for (key, value) in request.data {
|
||||||
let trimmed = value.trim().to_string();
|
let trimmed = value.trim().to_string();
|
||||||
|
|
||||||
// Handle firma specially - it cannot be empty
|
// Handle firma specially - it cannot be empty
|
||||||
if key == "firma" && trimmed.is_empty() {
|
if key == "firma" && trimmed.is_empty() {
|
||||||
return Err(Status::invalid_argument("Firma cannot be empty"));
|
return Err(Status::invalid_argument("Firma cannot be empty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
)
|
||||||
.await
|
.fetch_all(db_pool)
|
||||||
.map_err(|e| Status::internal(format!("Linked table error: {}", e)))?;
|
.await
|
||||||
|
.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,50 +116,41 @@ 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 =
|
ScriptOperation::SetToLocalColumn { source } => source,
|
||||||
match operation {
|
ScriptOperation::SetToExternalColumn { table, column } => {
|
||||||
ScriptOperation::SetToLocalColumn { source } => source,
|
let external_source = format!("@{}.{}", table, column);
|
||||||
ScriptOperation::SetToExternalColumn { table, column } => {
|
let resolved_value = execution::resolve_value(
|
||||||
// For external columns, we need to resolve the value from the external table
|
db_pool,
|
||||||
let external_source = format!("@{}.{}", table, column);
|
profile_id,
|
||||||
let resolved_value = execution::resolve_value(
|
&table_name,
|
||||||
db_pool,
|
&data,
|
||||||
profile_id,
|
&external_source
|
||||||
&table_name,
|
).await.map_err(|e| Status::invalid_argument(e.to_string()))?;
|
||||||
&data,
|
|
||||||
&external_source
|
resolved_value
|
||||||
).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)
|
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"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user