use crate::types::TypedValue;
use std::error::Error;
pub fn map_verb_to_sql(verb: &str, args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
match verb {
"select" => map_select(args),
"filter" => map_filter(args),
"group" => map_group(args),
"join" => map_join(args),
"sort" => map_sort(args),
_ => Err(format!("Unsupported verb for DuckDB mapping: {}", verb).into()),
}
}
fn map_select(args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
if args.is_empty() {
return Err("Select verb requires at least one argument (table or columns)".into());
}
let mut columns = "*".to_string();
let table = args[0].to_string();
if args.len() > 1 {
let column_args: Vec<String> = args[1..]
.iter()
.map(|arg| arg.to_string())
.collect();
if !column_args.is_empty() {
columns = column_args.join(", ");
}
}
Ok(format!("SELECT {} FROM {}", columns, table))
}
fn map_filter(args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
if args.len() < 2 {
return Err("Filter verb requires a table and at least one condition".into());
}
let table = args[0].to_string();
let conditions: Vec<String> = args[1..]
.iter()
.map(|arg| arg.to_string())
.collect();
if conditions.is_empty() {
return Err("Filter verb requires valid condition arguments".into());
}
let condition_str = conditions.join(" AND ");
Ok(format!("SELECT * FROM {} WHERE {}", table, condition_str))
}
fn map_group(args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
if args.len() < 2 {
return Err("Group verb requires a table and at least one grouping column".into());
}
let table = args[0].to_string();
let group_columns: Vec<String> = args[1..]
.iter()
.map(|arg| arg.to_string())
.collect();
if group_columns.is_empty() {
return Err("Group verb requires valid column arguments".into());
}
let group_str = group_columns.join(", ");
Ok(format!("SELECT * FROM {} GROUP BY {}", table, group_str))
}
fn map_join(args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
if args.len() < 3 {
return Err("Join verb requires two tables and at least one join condition".into());
}
let table1 = args[0].to_string();
let table2 = args[1].to_string();
let conditions: Vec<String> = args[2..]
.iter()
.map(|arg| arg.to_string())
.collect();
if conditions.is_empty() {
return Err("Join verb requires valid condition arguments".into());
}
let condition_str = conditions.join(" AND ");
Ok(format!("SELECT * FROM {} JOIN {} ON {}", table1, table2, condition_str))
}
fn map_sort(args: &[TypedValue]) -> Result<String, Box<dyn Error>> {
if args.len() < 2 {
return Err("Sort verb requires a table and at least one sorting column".into());
}
let table = args[0].to_string();
let sort_columns: Vec<String> = args[1..]
.iter()
.map(|arg| arg.to_string())
.collect();
if sort_columns.is_empty() {
return Err("Sort verb requires valid column arguments".into());
}
let sort_str = sort_columns.join(", ");
Ok(format!("SELECT * FROM {} ORDER BY {}", table, sort_str))
}