This commit is contained in:
parent
c15bd364c1
commit
17ed0bde36
3 changed files with 57 additions and 39 deletions
|
@ -11,7 +11,6 @@ FOR EACH item IN items
|
|||
|
||||
let alias = LLM "Return a single word for " + item.company + " like a token, no spaces, no special characters, no numbers, no uppercase letters."
|
||||
|
||||
CREATE_SITE alias, "OpenSourceCars", prompt
|
||||
|
||||
let to = item.emailcto
|
||||
let subject = "Simulador " + alias
|
||||
|
@ -19,6 +18,6 @@ FOR EACH item IN items
|
|||
|
||||
CREATE_DRAFT to, subject, body
|
||||
|
||||
|
||||
SET "gb.rob", "robid="+ item.robid, "ACTION=CLOSE"
|
||||
|
||||
NEXT item
|
|
@ -1,13 +1,12 @@
|
|||
use rhai::Dynamic;
|
||||
use rhai::Engine;
|
||||
use serde_json::{json, Value};
|
||||
use sqlx::{PgPool};
|
||||
use sqlx::{PgPool, Row};
|
||||
use std::error::Error;
|
||||
|
||||
use crate::services::state::AppState;
|
||||
use crate::services::utils;
|
||||
|
||||
|
||||
pub fn set_keyword(state: &AppState, engine: &mut Engine) {
|
||||
let db = state.db_custom.clone();
|
||||
|
||||
|
@ -53,31 +52,34 @@ pub async fn execute_set(
|
|||
table_str, filter_str, updates_str
|
||||
);
|
||||
|
||||
// Parse the updates first to know how many parameters we'll have
|
||||
let (set_clause, update_params) = parse_updates(updates_str).map_err(|e| e.to_string())?;
|
||||
let update_params_count = update_params.len();
|
||||
// Parse updates with proper type handling
|
||||
let (set_clause, update_values) = parse_updates(updates_str).map_err(|e| e.to_string())?;
|
||||
let update_params_count = update_values.len();
|
||||
|
||||
// Parse the filter condition with an offset for parameter indices
|
||||
let (where_clause, filter_params) = utils::parse_filter_with_offset(filter_str, update_params_count)
|
||||
// Parse filter with proper type handling
|
||||
let (where_clause, filter_values) = utils::parse_filter_with_offset(filter_str, update_params_count)
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
// Combine all parameters (updates first, then filter)
|
||||
let mut params = update_params;
|
||||
params.extend(filter_params);
|
||||
|
||||
let query = format!(
|
||||
"UPDATE {} SET {} WHERE {}",
|
||||
table_str, set_clause, where_clause
|
||||
);
|
||||
println!("Executing query: {}", query);
|
||||
|
||||
// Execute the update with all parameters
|
||||
let mut query_builder = sqlx::query(&query);
|
||||
for param in ¶ms {
|
||||
query_builder = query_builder.bind(param);
|
||||
// Build query with proper parameter binding
|
||||
let mut query = sqlx::query(&query);
|
||||
|
||||
// Bind update values
|
||||
for value in update_values {
|
||||
query = bind_value(query, value);
|
||||
}
|
||||
|
||||
// Bind filter values
|
||||
for value in filter_values {
|
||||
query = bind_value(query, value);
|
||||
}
|
||||
|
||||
let result = query_builder
|
||||
let result = query
|
||||
.execute(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
|
@ -85,8 +87,6 @@ pub async fn execute_set(
|
|||
e.to_string()
|
||||
})?;
|
||||
|
||||
println!("Update successful, affected {} rows", result.rows_affected());
|
||||
|
||||
Ok(json!({
|
||||
"command": "set",
|
||||
"table": table_str,
|
||||
|
@ -96,28 +96,40 @@ pub async fn execute_set(
|
|||
}))
|
||||
}
|
||||
|
||||
// Helper function to parse the updates string into SQL SET clause and parameters
|
||||
fn bind_value<'q>(query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>, value: String) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
|
||||
if let Ok(int_val) = value.parse::<i64>() {
|
||||
query.bind(int_val)
|
||||
} else if let Ok(float_val) = value.parse::<f64>() {
|
||||
query.bind(float_val)
|
||||
} else if value.eq_ignore_ascii_case("true") {
|
||||
query.bind(true)
|
||||
} else if value.eq_ignore_ascii_case("false") {
|
||||
query.bind(false)
|
||||
} else {
|
||||
query.bind(value)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse updates without adding quotes
|
||||
fn parse_updates(updates_str: &str) -> Result<(String, Vec<String>), Box<dyn Error>> {
|
||||
let mut set_clauses = Vec::new();
|
||||
let mut params = Vec::new();
|
||||
|
||||
// Split multiple updates by comma
|
||||
for (i, update) in updates_str.split(',').enumerate() {
|
||||
let parts: Vec<&str> = update.split('=').collect();
|
||||
if parts.len() != 2 {
|
||||
return Err("Invalid update format. Expected 'KEY=VALUE'".into());
|
||||
return Err("Invalid update format".into());
|
||||
}
|
||||
|
||||
let column = parts[0].trim();
|
||||
let value = parts[1].trim();
|
||||
|
||||
// Validate column name to prevent SQL injection
|
||||
if !column.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
|
||||
return Err("Invalid column name in update".into());
|
||||
return Err("Invalid column name".into());
|
||||
}
|
||||
|
||||
set_clauses.push(format!("{} = ${}", column, i + 1));
|
||||
params.push(value.to_string());
|
||||
params.push(value.to_string()); // Store raw value without quotes
|
||||
}
|
||||
|
||||
Ok((set_clauses.join(", "), params))
|
||||
|
|
|
@ -239,20 +239,27 @@ pub fn parse_filter(filter_str: &str) -> Result<(String, Vec<String>), Box<dyn E
|
|||
Ok((format!("{} = $1", column), vec![value.to_string()]))
|
||||
}
|
||||
|
||||
// Parse filter without adding quotes
|
||||
pub fn parse_filter_with_offset(filter_str: &str, offset: usize) -> Result<(String, Vec<String>), Box<dyn Error>> {
|
||||
let parts: Vec<&str> = filter_str.split('=').collect();
|
||||
if parts.len() != 2 {
|
||||
return Err("Invalid filter format. Expected 'KEY=VALUE'".into());
|
||||
let mut clauses = Vec::new();
|
||||
let mut params = Vec::new();
|
||||
|
||||
for (i, condition) in filter_str.split('&').enumerate() {
|
||||
let parts: Vec<&str> = condition.split('=').collect();
|
||||
if parts.len() != 2 {
|
||||
return Err("Invalid filter format".into());
|
||||
}
|
||||
|
||||
let column = parts[0].trim();
|
||||
let value = parts[1].trim();
|
||||
|
||||
if !column.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
|
||||
return Err("Invalid column name".into());
|
||||
}
|
||||
|
||||
clauses.push(format!("{} = ${}", column, i + 1 + offset));
|
||||
params.push(value.to_string()); // Store raw value without quotes
|
||||
}
|
||||
|
||||
let column = parts[0].trim();
|
||||
let value = parts[1].trim();
|
||||
|
||||
// Validate column name to prevent SQL injection
|
||||
if !column.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
|
||||
return Err("Invalid column name in filter".into());
|
||||
}
|
||||
|
||||
// Use the offset + 1 for the parameter number
|
||||
Ok((format!("{} = ${}", column, offset + 1), vec![value.to_string()]))
|
||||
Ok((clauses.join(" AND "), params))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue